PB Editor, print command
PB Editor, print command
it's not a big issue or a problem any way. but it will be good if we can print source code within the editor(almost all ide have this command in file menu)
Below is an addin tool to print the currently selected source code from within the IDE.
Compile the source code to an .exe file.
From the PB IDE take the menu path Tools -> Configure Tools -> New
Fill in details as follows:
Command line = Pathname to the .exe file (preferably in double quotes, but this may cause a 'Memory Write' error)
Arguments = "%TEMPFILE"
Name = Print Source Code
Event = Menu or Shortcut
Tick only the box 'Wait until tool quits'
To print your source code, ensure the printer is online then take the menu path Tools -> Print source Code
Here is the program to be compiled:
Note that on the printout, if a long source line is wrapped onto multiple printer lines, each of those printer lines (except the first) is prefixed with the continuation character "¬".
Compile the source code to an .exe file.
From the PB IDE take the menu path Tools -> Configure Tools -> New
Fill in details as follows:
Command line = Pathname to the .exe file (preferably in double quotes, but this may cause a 'Memory Write' error)
Arguments = "%TEMPFILE"
Name = Print Source Code
Event = Menu or Shortcut
Tick only the box 'Wait until tool quits'
To print your source code, ensure the printer is online then take the menu path Tools -> Print source Code
Here is the program to be compiled:
Code: Select all
; PrintFile AKJ 15-Mar-06
; Print a text file whose path is given as the command line parameter
; Lines too wide for the page are cut and resulting overflow lines prepended with "¬"
;{ Constants
#program$="PrintFile"
#version$="1.1"
#file=1
; The following constants may be edited by the user:
#gap=5 ; Vertical gap (leading) in pixels between print lines
#Lmargin=200 ; Left hand margin in pixels
#Rmargin=100 ; Right margin in pixels
#Tmargin=200 ; Top margin in pixels
#Bmargin=0 ; Bottom margin in pixels
#indent=0 ; Additional left indentation in pixels for non-empty overflow lines
#continue$="¬" ; Continuation character shown at the start of non-empty overflow lines
;}
;{ Declarations
Declare PrintLine(ln$, indent, lineh, lpp)
EnableExplicit
Define pagew, pageh, lineh, lpp
Define path$, ln$, indent, cut, p, tmp$, indent$
;}
;{ Get text file's pathname
path$ = ProgramParameter()
If path$ = "": End: EndIf ; Quit without error message
If FileSize(path$)<=0: : End: EndIf ; Quit without error message
;}
;{ Initialise printer and get printer metrics
If DefaultPrinter()=0
MessageRequester(#program$+" Error", "Cannot open default printing device")
End
EndIf
StartPrinting("Text File")
pagew=PrinterPageWidth()-#Lmargin-#Rmargin
pageh=PrinterPageHeight()-#Tmargin-#Bmargin
StartDrawing(PrinterOutput())
; !!! DrawingFont(LoadFont(0, "Arial", 10))
lineh=TextHeight("bgj_~QX")+#gap
lpp=(pageh+#gap)/lineh ; Lines that will fit on a page
;}
;{ Print the file
If ReadFile(#file, path$)=0: End: EndIf ; Quit without error message
While Not Eof(#file)
ln$=RTrim(ReadString(#file)) ; Preserve any whitespace on the left
indent=0 ; Indentation (if any) beyond the left margin
; Does the line need to be split because it is too long for the page width?
Repeat
If TextWidth(ln$)<=pagew-indent ; If line will fit on page
PrintLine(ln$, indent, lineh, lpp)
ln$=""
Else ; Line too wide for page
cut=Len(ln$) ; Point [just before] where the line will eventually be cut
Repeat ; Large steps
cut-12 ; New trial cut point
Until TextWidth(Left(ln$,cut))<=pagew-indent ; Until it will fit
cut+12
Repeat ; Small steps
cut-1 ; New trial cut point
Until TextWidth(Left(ln$,cut))<=pagew-indent ; Until it will fit
; Try not to split the last word, except at a hyphen
For p=cut To cut-12 Step -1
If FindString(" -"+#TAB$, Mid(ln$,p,1), 1) ; If whitespace or hyphen
Break ; Found a better cut point
EndIf
Next p
If p>=cut-12: cut=p: EndIf ; If a better cut point was found
; Now print and cut the line, removing trailing whitespace
tmp$=RTrim(Left(ln$, cut))
If indent ; If an overflow line
If Len(tmp$) ; Do not print empty overflow (indented) lines
PrintLine(tmp$, indent, lineh, lpp)
EndIf
Else ; Not an overflow line
indent$=Left(tmp$, Len(tmp$)-Len(LTrim(tmp$))) ; Remember the leading whitespace
PrintLine(tmp$, indent, lineh, lpp) ; Print, even if empty
indent=#indent ; Indentation (if any) beyond the left margin
EndIf
ln$=LTrim(Mid(ln$,cut+1,9999)) ; Build the overflow line
If Len(ln$): ln$=indent$+#continue$+ln$: EndIf ; Prepend the same leading whitespace
EndIf
Until Len(ln$)=0
Wend
;}
;{ Windup
CloseFile(#file)
StopDrawing()
StopPrinting()
End
;}
Procedure PrintLine(ln$, indent, lineh, lpp)
Static line=0 ; Lines printed on the current page
Static y=#Tmargin ; Vertical print position
DrawText(#Lmargin+indent, y, ln$) ; "Print" the line
line+1: y+lineh
If line>=lpp ; If the current page is full
line=0: y=#Tmargin
NewPrinterPage()
EndIf
EndProcedure
Anthony Jordan
Thanks for the code. I missed that feature too. But your code got me
going, as I wanted to add Line #'s and Page #'s to the print out too, as
it is easier to reference when examining the code with those #'s.
I modified your code to include Line #'s and Page #'s, plus some
other commented stuff, and compiled with version 4.0 beta 7.
I'm new to Purebasic and don't quit understand the your use of indent
the way you did, so I did it another way. It works on both ver 3.94
and 4.0 as far as printing goes. But both your code and mine, cause 4.0
to crash after it is done printing, which may be a beta bug.
Error: An attemped read or write to/from an address to which that process
isn't allowed.
Here is the code if any one wants these features also.
Forgot to add.
I didn't write the program to also print the file name on the page top.
I just put the name and comments at the source beginning under
;comments instead. So you may want to do that before you print
out some code later, so you know what it is from.
going, as I wanted to add Line #'s and Page #'s to the print out too, as
it is easier to reference when examining the code with those #'s.
I modified your code to include Line #'s and Page #'s, plus some
other commented stuff, and compiled with version 4.0 beta 7.
I'm new to Purebasic and don't quit understand the your use of indent
the way you did, so I did it another way. It works on both ver 3.94
and 4.0 as far as printing goes. But both your code and mine, cause 4.0
to crash after it is done printing, which may be a beta bug.
Error: An attemped read or write to/from an address to which that process
isn't allowed.
Here is the code if any one wants these features also.
Code: Select all
;PrintFile AKJ 15-Mar-06
; PrintFile2 yrret 16-Mar-06 added Line #'s and Page #'s, plus a few other commented edits.
; Print a text file whose path is given as the command line parameter
; Lines too wide for the page are cut and resulting overflow lines prepended with "¬"
;{ Constants
#program$="PrintFile"
#version$="1.1"
#file=1
; The following constants may be edited by the user:
#gap=5 ; Vertical gap (leading) in pixels between print lines
#Lmargin=200 ; Left hand margin in pixels
#Rmargin=260 ; Right margin in pixels (adj for line #'s)
#Tmargin=200 ; Top margin in pixels
#Bmargin=0 ; Bottom margin in pixels
#continue$="¬" ; Continuation character shown at the start of non-empty overflow lines
;}
;{ Declarations
Declare PrintLine(ln$, indent, lineh, lpp, pgline)
EnableExplicit
Define lnum, lnum$, nonum, pgn
Define pagew, pageh, lineh, lpp, pgline
Define path$, ln$, indent, cut, p, tmp$, indent$
;}
;{ Get text file's pathname
path$ = ProgramParameter()
If path$ = "": End: EndIf ; Quit without error message
If FileSize(path$)<=0: : End: EndIf ; Quit without error message
;}
;{ Initialise printer and get printer metrics
If DefaultPrinter()=0
MessageRequester(#program$+" Error", "Cannot open default printing device")
End
EndIf
StartPrinting("Text File")
pagew=PrinterPageWidth()-#Lmargin-#Rmargin ;Return the width of the drawing area, in pixel.
pageh=PrinterPageHeight()-#Tmargin-#Bmargin ;Return the height of the drawing area, in pixel.
StartDrawing(PrinterOutput())
; !!! DrawingFont(LoadFont(0, "Arial", 10))
lineh=TextHeight("bgj_~QX")+#gap
lpp=((pageh+#gap)/lineh)-3 ; Lines that will fit on a page. Make room for Page #'s
;}
;{ Print the file
If ReadFile(#file, path$)=0: End: EndIf ; Quit without error message
;add line numbers
lnum=1
pgline=0
nonum=0
pgn=1
indent=0 ; Use only for Page # positioning
While Not Eof(#file)
ln$=RTrim(ReadString(#file)) ; Preserve any whitespace on the left
If nonum=0 And Left(ln$,1)=" " ;Double indent space as it makes code look better.
indent$=Left(ln$,Len(ln$)-Len(LTrim(ln$)))
ln$=indent$+ln$
EndIf
; Does the line need to be split because it is too long for the page width?
Repeat
lnum$=Str(lnum) ;space line #'s for 5 positions
If Len(lnum$)<5
lnum$=Left(lnum$+" ",5)
EndIf ;add two spaces between line # and text
lnum$=lnum$+" "
If TextWidth(ln$)<=pagew ; If line will fit on page
If pgline=lpp ; If the current page is full
PrintLine(" ", indent, lineh, lpp, pgline)
pgline+1
PrintLine("Page "+Str(pgn), indent+2000, lineh, lpp, pgline)
pgline=0
pgn+1
EndIf
If nonum=0
PrintLine(lnum$+ln$, indent, lineh, lpp, pgline)
pgline+1
Else
PrintLine(ln$, indent, lineh, lpp, pgline)
pgline+1
nonum=0
EndIf
ln$=""
Else ; Line too wide for page
;first get line indent and add line number spaces to it.
indent$=Left(ln$,Len(ln$)-Len(LTrim(ln$)))+" "+Space(Len(Str(lnum)))
cut=Len(ln$) ; Point [just before] where the line will eventually be cut
Repeat ; Large steps
cut-12 ; New trial cut point
Until TextWidth(Left(ln$,cut))<=pagew ; Until it will fit
cut+12
Repeat ; Small steps
cut-1 ; New trial cut point
Until TextWidth(Left(ln$,cut))<=pagew ; Until it will fit
; Try not to split the last word, except at a hyphen
For p=cut To cut-12 Step -1
If FindString(" -_"+#TAB$, Mid(ln$,p,1), 1) ; If whitespace or hyphen
Break ; Found a better cut point
EndIf
Next p
If p>=cut-12: cut=p: EndIf ; If a better cut point was found
;Now print and cut the first part of the line.
tmp$=Left(ln$, cut-1)
If pgline=lpp ; If the current page is full
PrintLine(" ", indent, lineh, lpp, pgline)
pgline+1
PrintLine("Page "+Str(pgn), indent+2000, lineh, lpp, pgline)
pgline=0
pgn+1
EndIf
PrintLine(lnum$+tmp$, indent, lineh, lpp, pgline)
pgline+1
;Now build the overflow line
ln$=Mid(ln$,cut,Len(ln$)-cut)
If Len(ln$)
ln$=indent$+#continue$+ln$
nonum=1
EndIf
EndIf
If nonum=0
lnum+1
EndIf
Until Len(ln$)=0
Wend
;}
;{ Windup
CloseFile(#file)
If pgline<lpp+1 ;print page # on last page at bottom of page.
Repeat
PrintLine(" ", indent, lineh, lpp, pgline)
pgline+1
Until pgline>lpp
pgline-1 ;don't need new print page, as this is the last page.
PrintLine("Page "+Str(pgn), indent+2000, lineh, lpp, pgline)
EndIf
StopDrawing()
StopPrinting()
End
;}
Procedure PrintLine(ln$, indent, lineh, lpp, pgline)
;Static pgline=0 ; Lines printed on the current page
Static y=#Tmargin ; Vertical print position
DrawText(#Lmargin+indent, y, ln$) ; "Print" the line
y+lineh
If pgline>lpp ; If the current page is full
y=#Tmargin
NewPrinterPage()
EndIf
EndProcedure
;Note that on the printout, If a long source line is wrapped onto multiple printer lines,
;each of those printer lines (except the first) is prefixed with the continuation character "¬".]
I didn't write the program to also print the file name on the page top.
I just put the name and comments at the source beginning under
;comments instead. So you may want to do that before you print
out some code later, so you know what it is from.
Last edited by yrret on Thu Mar 16, 2006 9:35 pm, edited 1 time in total.
- utopiomania
- Addict
- Posts: 1655
- Joined: Tue May 10, 2005 10:00 pm
- Location: Norway
Here's another method: http://www.purebasic.fr/english/viewtopic.php?t=17127
and here another method with Syntax-Highlightning: http://www.purebasic.fr/german/viewtopic.php?t=5159
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.

Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.

I have amended my code to include most/all of yrret's additional ideas.
However most of the responsibility for generating page numbers and line numbers is now within the procedure PrintLine() which - I think - greatly simplifies the logic.
The continuation character has been changed from "¬" to "" (i.e. omitted) as it is now redundant, because the absence of line numbers on continuation lines now makes them easy to detect.
However most of the responsibility for generating page numbers and line numbers is now within the procedure PrintLine() which - I think - greatly simplifies the logic.
The continuation character has been changed from "¬" to "" (i.e. omitted) as it is now redundant, because the absence of line numbers on continuation lines now makes them easy to detect.
Code: Select all
; PrintFile AKJ 17-Mar-06
; Print a text file whose path is given as the command line parameter
; Lines too wide for the page are cut
; Page numbers and line numbers are printed (as suggested by yrret)
;{ Constants
#program$="PrintFile"
#version$="2.0"
#file=1
; The following constants may be edited by the user:
#gap=5 ; Vertical gap (leading) in pixels between print lines
#Lmargin=200 ; Left hand margin in pixels
#Rmargin=100 ; Right margin in pixels
#Tmargin=180 ; Top margin in pixels
#Bmargin=0 ; Bottom margin in pixels
#continue$="" ; Continuation character shown at the start of non-empty overflow lines
;}
;{ Declarations
Declare PrintLine(ln$, overflow, linenumw, lineh, lpp)
EnableExplicit
Define pagew, pageh, linenumw, printw, lineh, lpp
Define path$, ln$, cut, p, tmp$, whitespace$, overflow
;}
;{ Get text file's pathname
path$ = ProgramParameter()
If path$ = "": End: EndIf ; Quit without error message
If FileSize(path$)<=0: : End: EndIf ; Quit without error message
;}
;{ Initialise printer and get printer metrics
If DefaultPrinter()=0
MessageRequester(#program$+" Error", "Cannot open default printing device")
End
EndIf
StartPrinting("Text File")
pagew=PrinterPageWidth()-#Lmargin-#Rmargin
pageh=PrinterPageHeight()-#Tmargin-#Bmargin
StartDrawing(PrinterOutput())
; !!! DrawingFont(LoadFont(0, "Arial", 10))
linenumw=TextWidth("1000 ") ; Width of line number column
printw=pagew-linenumw ; Width available for printing file text
lineh=TextHeight("bgj_~QX")+#gap
lpp=(pageh+#gap)/lineh ; Lines that will fit on a page
;}
;{ Print the file
If ReadFile(#file, path$)=0: End: EndIf ; Quit without error message
While Not Eof(#file)
ln$=RTrim(ReadString(#file)) ; Preserve any whitespace on the left
overflow=#False ; Not a continuation line
; Does the line need to be split because it is too long for the page width?
Repeat
If TextWidth(ln$)<=printw ; If line will fit on page
PrintLine(ln$, overflow, linenumw, lineh, lpp)
ln$=""
Else ; Line too wide for page
cut=Len(ln$) ; Point [just before] where the line will eventually be cut
Repeat ; Large steps
cut-12 ; New trial cut point
Until TextWidth(Left(ln$,cut))<=printw ; Until it will fit
cut+12
Repeat ; Small steps
cut-1 ; New trial cut point
Until TextWidth(Left(ln$,cut))<=printw ; Until it will fit
; Try not to split the last word, except at a hyphen
For p=cut To cut-12 Step -1
If FindString(" -_"+#TAB$, Mid(ln$,p,1), 1) ; If whitespace, hyphen or underscore
Break ; Found a better cut point
EndIf
Next p
If p>=cut-12: cut=p: EndIf ; If a better cut point was found
; Now print and cut the line, removing trailing whitespace
tmp$=RTrim(Left(ln$, cut))
If overflow ; If a continuation line
If Len(tmp$) ; Do not print empty continuation lines
PrintLine(tmp$, overflow, linenumw, lineh, lpp)
EndIf
Else ; Not an overflow line
whitespace$=Left(tmp$, Len(tmp$)-Len(LTrim(tmp$))) ; Remember the leading whitespace
PrintLine(tmp$, overflow, linenumw, lineh, lpp) ; Print, even if empty
overflow=#True
EndIf
ln$=LTrim(Mid(ln$,cut+1,9999)) ; Build the next continuation line
If Len(ln$): ln$=whitespace$+#continue$+ln$: EndIf ; Prepend the same leading whitespace
EndIf
Until Len(ln$)=0
Wend
;}
;{ Windup
CloseFile(#file)
StopDrawing()
StopPrinting()
End
;}
Procedure PrintLine(ln$, overflow, linenumw, lineh, lpp)
; Print the line in ln$
; overflow is True if the line is a continuation line, printed without a line number
; linenumw is the width in pixels of the line number column
; lineh is the vertical distance in pixels between lines
; lpp is the number of lines that will physically print on a page
Static pagenum=0 ; Current page number
Static linenum=0 ; Current line number within source file
Static line=0 ; Lines printed on the current page
Static y=#Tmargin ; Vertical print position
If line=0 ; If starting a new page
pagenum+1
DrawText(#Lmargin, y, "Page "+Str(pagenum)) ; Print page number
line=2: y+lineh*2 ; Leave a blank line
EndIf
If Not overflow ; If not an overflow line
linenum+1
DrawText(#Lmargin+TextWidth("1999")-TextWidth(Str(linenum)), y, Str(linenum)) ; "Print" linenumber
EndIf
DrawText(#Lmargin+linenumw, y, ln$) ; "Print" text to the right of the line number column
line+1: y+lineh
If line>=lpp ; If the current page is full
line=0: y=#Tmargin
NewPrinterPage()
EndIf
EndProcedure
Anthony Jordan
First of all I'm not trying to compete with you akj, as you can probably
program circles around me. I liked your code, but the fun of learning is
to improve on it. So I added page # from and to, and filename, and
build #, if using PureBUILD Build, in print out.
Example in printing this code: (1st line page 1)
Page 1 of 5 D:\Purebasic4_0\work\print_file.pb build # 6
(and last page)
Page 5 of 5 D:\Purebasic4_0\work\print_file.pb build # 6
I also re-added double indent space as it makes code look better, like you
see it in the IDE.
Thanks again for the great code.
program circles around me. I liked your code, but the fun of learning is
to improve on it. So I added page # from and to, and filename, and
build #, if using PureBUILD Build, in print out.
Example in printing this code: (1st line page 1)
Page 1 of 5 D:\Purebasic4_0\work\print_file.pb build # 6
(and last page)
Page 5 of 5 D:\Purebasic4_0\work\print_file.pb build # 6
I also re-added double indent space as it makes code look better, like you
see it in the IDE.
Code: Select all
; PrintFile AKJ 17-Mar-06
; version 2.0
; Print a text file whose path is given as the command line parameter
; Lines too wide for the page are cut
; Page numbers and line numbers are printed (as suggested by yrret)
;
; PrintFile yrret 17-Mar-06
; version 2.0a
; Added page from and to, and filename in print out.
; If using PureBUILD Build, I also added the build #
; Also added indent$ to make indent spacing like in editor and to make code easier to read.
;
;Use as an addin tool to print the currently selected source code from within the IDE.
;Compile the source code (with PB 4.0) to an .exe file.
;From the PB IDE take the menu path Tools -> Configure Tools -> New
;Fill in details as follows:
;Command line = Pathname To the .exe file (Don't use double quotes, as this causes a 'Memory Write' error)
;
;*********
;Arguments = "%FILE"
;*** NOTE: Remains empty if file has not yet been saved yet. So always save file before printing. ***
;*********
;
;Name = Print Source Code
;Event = Menu Or Shortcut
;Tick only the box 'Wait until tool quits'
;To print your source code, ensure the printer is online then take the menu path Tools -> Print source Code
;{ Constants
#program$="PrintFile"
#version$="2.0"
#file=1
; The following constants may be edited by the user:
#gap=5 ; Vertical gap (leading) in pixels between print lines
#Lmargin=200 ; Left hand margin in pixels
#Rmargin=100 ; Right margin in pixels
#Tmargin=180 ; Top margin in pixels
#Bmargin=0 ; Bottom margin in pixels
#continue$="" ; Continuation character shown at the start of non-empty overflow lines
;}
;{ Declarations
Declare PrintLine(ln$, overflow, linenumw, lineh, lpp, pt, name$)
EnableExplicit
Define pagew, pageh, linenumw, printw, lineh, lpp
Define path$, ln$, cut, p, tmp$, whitespace$, indent$, overflow
Define ln, pt, name$
;}
;{ Get text file's pathname
path$ = ProgramParameter()
If path$ = "": End: EndIf ; Quit without error message
If FileSize(path$)<=0: : End: EndIf ; Quit without error message
;}
;{ Initialise printer and get printer metrics
If DefaultPrinter()=0
MessageRequester(#program$+" Error", "Cannot open default printing device")
End
EndIf
StartPrinting("Text File")
pagew=PrinterPageWidth()-#Lmargin-#Rmargin
pageh=PrinterPageHeight()-#Tmargin-#Bmargin
StartDrawing(PrinterOutput())
; !!! DrawingFont(LoadFont(0, "Arial", 10))
linenumw=TextWidth("1000 ") ; Width of line number column
printw=pagew-linenumw ; Width available for printing file text
lineh=TextHeight("bgj_~QX")+#gap
lpp=(pageh+#gap)/lineh ; Lines that will fit on a page
;}
;{ Get total page #'s, file name and build # if using PureBUILD.
;You need to do basically the same as for printing, but without printing,
;to make sure you have the same number of lines to calculate the total pages.
ln=3 ;start from 3 here to account for starting from 0 and skipping to 2 later in the PrintLine proceedure.
pt=1
name$ = path$ ;Get file name and path, and also print with page #'s.
;name$ = GetFilePart(path$) ;use this if you just want file name
If ReadFile(#file, path$)=0: End: EndIf ; Quit without error message
While Not Eof(#file)
ln$=RTrim(ReadString(#file)) ; Preserve any whitespace on the left
If FindString(ln$, "; PureBUILD Build =", 1) ; If using PureBUILD Build, get build # and add to name$
If FindString(ln$, "PureBUILD Plugin", 1) ; Make sure your using correct data. eg: if printing this file.
name$=name$+" build # "+Mid(ln$,FindString(ln$, "PureBUILD Build =", 1)+18, 9999)
name$=Left(name$, FindString(name$, "[", 1)-1)
EndIf
EndIf
overflow=#False ; Not a continuation line
; Does the line need to be split because it is too long for the page width?
Repeat
If TextWidth(ln$)<=printw ; If line will fit on page
ln+1
ln$=""
Else ; Line too wide for page
cut=Len(ln$) ; Point [just before] where the line will eventually be cut
Repeat ; Large steps
cut-12 ; New trial cut point
Until TextWidth(Left(ln$,cut))<=printw ; Until it will fit
cut+12
Repeat ; Small steps
cut-1 ; New trial cut point
Until TextWidth(Left(ln$,cut))<=printw ; Until it will fit
; Try not to split the last word, except at a hyphen
For p=cut To cut-12 Step -1
If FindString(" -_"+#TAB$, Mid(ln$,p,1), 1) ; If whitespace, hyphen or underscore
Break ; Found a better cut point
EndIf
Next p
If p>=cut-12: cut=p: EndIf ; If a better cut point was found
; Now print and cut the line, removing trailing whitespace
tmp$=RTrim(Left(ln$, cut))
If overflow ; If a continuation line
If Len(tmp$) ; Do not print empty continuation lines
ln+1
EndIf
Else ; Not an overflow line
whitespace$=Left(tmp$, Len(tmp$)-Len(LTrim(tmp$))) ; Remember the leading whitespace
ln+1
overflow=#True
EndIf
ln$=LTrim(Mid(ln$,cut+1,9999)) ; Build the next continuation line
If Len(ln$): ln$=whitespace$+#continue$+ln$: EndIf ; Prepend the same leading whitespace
EndIf
If ln>=lpp ; If the current page is full
ln=1
pt+1
EndIf
Until Len(ln$)=0
Wend
CloseFile(#file)
Delay(1000) ;give time for file to close before re-openning
;}
;{ Print the file
If ReadFile(#file, path$)=0: End: EndIf ; Quit without error message
While Not Eof(#file)
ln$=RTrim(ReadString(#file)) ; Preserve any whitespace on the left
If Not overflow And Left(ln$,1)=" " ;Added double indent space as it makes code look better. yrret 03/17/06
indent$=Left(ln$,Len(ln$)-Len(LTrim(ln$)))
ln$=indent$+ln$
EndIf
overflow=#False ; Not a continuation line
; Does the line need to be split because it is too long for the page width?
Repeat
If TextWidth(ln$)<=printw ; If line will fit on page
PrintLine(ln$, overflow, linenumw, lineh, lpp, pt, name$)
ln$=""
Else ; Line too wide for page
cut=Len(ln$) ; Point [just before] where the line will eventually be cut
Repeat ; Large steps
cut-12 ; New trial cut point
Until TextWidth(Left(ln$,cut))<=printw ; Until it will fit
cut+12
Repeat ; Small steps
cut-1 ; New trial cut point
Until TextWidth(Left(ln$,cut))<=printw ; Until it will fit
; Try not to split the last word, except at a hyphen
For p=cut To cut-12 Step -1
If FindString(" -_"+#TAB$, Mid(ln$,p,1), 1) ; If whitespace, hyphen or underscore
Break ; Found a better cut point
EndIf
Next p
If p>=cut-12: cut=p: EndIf ; If a better cut point was found
; Now print and cut the line, removing trailing whitespace
tmp$=RTrim(Left(ln$, cut))
If overflow ; If a continuation line
If Len(tmp$) ; Do not print empty continuation lines
PrintLine(tmp$, overflow, linenumw, lineh, lpp, pt, name$)
EndIf
Else ; Not an overflow line
whitespace$=Left(tmp$, Len(tmp$)-Len(LTrim(tmp$))) ; Remember the leading whitespace
PrintLine(tmp$, overflow, linenumw, lineh, lpp, pt, name$) ; Print, even if empty
overflow=#True
EndIf
ln$=LTrim(Mid(ln$,cut+1,9999)) ; Build the next continuation line
If Len(ln$): ln$=whitespace$+#continue$+ln$: EndIf ; Prepend the same leading whitespace
EndIf
Until Len(ln$)=0
Wend
;}
;{ Windup
CloseFile(#file)
StopDrawing()
StopPrinting()
End
;}
Procedure PrintLine(ln$, overflow, linenumw, lineh, lpp, pt, name$)
; Print the line in ln$
; overflow is True if the line is a continuation line, printed without a line number
; linenumw is the width in pixels of the line number column
; lineh is the vertical distance in pixels between lines
; lpp is the number of lines that will physically print on a page
Static pagenum=0 ; Current page number
Static linenum=0 ; Current line number within source file
Static line=0 ; Lines printed on the current page
Static y=#Tmargin ; Vertical print position
If line=0 ; If starting a new page
pagenum+1
DrawText(#Lmargin, y, "Page "+Str(pagenum)+" of "+Str(pt)+" "+name$) ; Print page number of page total and file name.
line=2: y+lineh*2 ; Leave a blank line
EndIf
If Not overflow ; If not an overflow line
linenum+1
DrawText(#Lmargin+TextWidth("1999")-TextWidth(Str(linenum)), y, Str(linenum)) ; "Print" linenumber
EndIf
DrawText(#Lmargin+linenumw, y, ln$) ; "Print" text to the right of the line number column
line+1: y+lineh
If line>=lpp ; If the current page is full
line=0: y=#Tmargin
NewPrinterPage()
EndIf
EndProcedure
;
; PureBUILD Build = 6 [generated by PureBUILD Plugin]
Yrret says:
Based on yrret's suggestions, I have enhanced my version of the program still further, but only making one pass of the input text file whilst yrret's code makes two passes. I have not incorporated his suggestion of "double indent spacing", because I think his coding is unnecessary as the spacing on the printer is - I believe - identical to that in the IDE, provided the IDE Editor preference 'Use real Tab (ASCII 9)' is not ticked.
Also, the program will now print just selected text rather than the whole file if the text selection in the IDE is 2 lines long or more.
*** Important ***: In the configuration of this IDE add-in tool, the command line arguments box must now be set to:
"%SELECTION" "%TEMPFILE" "%FILE"
I certainly agree. The fun is in the 'doing' not the 'viewing'.the fun of learning is to improve on it
Based on yrret's suggestions, I have enhanced my version of the program still further, but only making one pass of the input text file whilst yrret's code makes two passes. I have not incorporated his suggestion of "double indent spacing", because I think his coding is unnecessary as the spacing on the printer is - I believe - identical to that in the IDE, provided the IDE Editor preference 'Use real Tab (ASCII 9)' is not ticked.
Also, the program will now print just selected text rather than the whole file if the text selection in the IDE is 2 lines long or more.
*** Important ***: In the configuration of this IDE add-in tool, the command line arguments box must now be set to:
"%SELECTION" "%TEMPFILE" "%FILE"
Code: Select all
; PrintFile AKJ 19-Mar-06 PB Add-in Tool
; Print a text file whose path is given as a command line parameter
; Lines too wide for the page are wrapped onto subsequent print lines
; Page titles, page numbers & line numbers are printed (as suggested by yrret)
; Any PureBUILD build number is included in the title (as suggested by yrret)
; If multiple text lines are selected, only those lines are printed
; The add-in tool configuration arguments must be "%SELECTION" "%TEMPFILE" "%FILE"
;{ Constants
#program$="PrintFile"
#version$="2.3"
#file=1
; The following constants may be edited by the user:
#gap=5 ; Vertical gap (leading) in pixels between print lines
#Lmargin=200 ; Left hand margin in pixels
#Rmargin=100 ; Right margin in pixels
#Tmargin=180 ; Top margin in pixels
#Bmargin=0 ; Bottom margin in pixels
#continue$="" ; Continuation character shown at the start of non-empty overflow lines
;}
;{ Declarations
EnableExplicit
Global NewList lines$() ; Buffer for storing the print lines prior to printing
Define selection$ ; Limits of selected text
Define linefrst, linelast ; First/last selected text lines
Define path$="" ; Pathname of file to be printed
Define pagew, pageh ; Page dimensions in pixels sans margins
Define linenumw ; Width in pixels of the line number column
Define printw ; Width available for printing file text (excludes the line number column)
Define lineh ; Vertical distance in pixels between lines
Define lpp ; Lines per page available for printing (including title lines)
Define pages ; Number of pages that will physically be printed
Define pagenumx ; Start position of the right-aligned page number
Define title$="" ; Title (excluding page number) at the top of each page
Define titlew ; Width in pixels available for the title
Define ln$ ; The text line currently being processed/printed
Define tmp$ ; Temporary string variable
Define whitespace$ ; A copy of any whitespace at the start of the current line
Define cut; Position at which a text line must be cut to fit on the page
Define p ; Position within text strings and command line parameter number
Define overflow$ ; Flag: "#" (line has a line number) or "+" (continuation line)
Define build$="" ; PureBUILD build number
Define pagenum=0 ; Current page number
Define linenum=0 ; Current printed line number within source file
Define line=0 ; Lines printed on the current page
Define y=#Tmargin ; Vertical print position on the current page
;}
;{ Identify text selection from the command line
selection$=ProgramParameter(0)
linefrst=Val(StringField(selection$, 1, "x"))
linelast=Val(StringField(selection$, 3, "x"))
; If the selection ends at the beginning of a line, treat it as ending on the previous line
If StringField(selection$, 4, "x")="1": linelast-1: EndIf
; If the selection is confined to one line, treat it as no selection
If linefrst>=linelast: linefrst=1: linelast=99999: EndIf
;}
;{ Get file pathnames from the command line
; path$ will point to the latest in-memory version of the file
; title$ will contain the program's pathname if it has ever been saved
For p=1 To 2
tmp$ = ProgramParameter(p)
If FindString(LCase(tmp$), "\compilers\tempfile.pb", 1) ; If a temporary filename
path$=tmp$
ElseIf Len(tmp$)
title$=tmp$
EndIf
Next p
If path$="": End: EndIf ; Quit without error message
If FileSize(path$)<=0: : End: EndIf ; Quit without error message
;}
;{ Initialise printer and get printer metrics
If DefaultPrinter()=0
MessageRequester(#program$+" Error", "Cannot open default printing device")
End
EndIf
StartPrinting("Text File")
pagew=PrinterPageWidth()-#Lmargin-#Rmargin
pageh=PrinterPageHeight()-#Tmargin-#Bmargin
StartDrawing(PrinterOutput())
; !!! DrawingFont(LoadFont(0, "Arial", 10))
linenumw=TextWidth("1999 ") ; Width of line number column
printw=pagew-linenumw ; Width available for printing file text
lineh=TextHeight("bgj_~QX")+#gap
lpp=(pageh+#gap)/lineh ; Lines that will fit on a page
;}
;{ Build print lines in a linked list
If ReadFile(#file, path$)=0: End: EndIf ; Quit without error message
While Not Eof(#file)
ln$=RTrim(ReadString(#file)) ; Preserve any whitespace on the left
; If using PureBUILD, try to get the build number
If FindString(LCase(ln$), "purebuild plugin", 1)
p=FindString(LCase(ln$), "purebuild build =", 1)
If p
build$=" Build "+Str(Val(Mid(ln$,p+17,9999)))
EndIf
EndIf
overflow$="#" ; Not a continuation line
linenum+1
; Does the line need to be split because it is too long for the page width?
Repeat
If TextWidth(ln$)<=printw ; If line will fit on page
If linenum>=linefrst And linenum<=linelast
AddElement(lines$()): lines$()=overflow$+ln$
EndIf
ln$=""
Else ; Line too wide for page
cut=Len(ln$) ; Point [just before] where the line will eventually be cut
Repeat ; Large steps
cut-12 ; New trial cut point
Until TextWidth(Left(ln$,cut))<=printw ; Until it will fit
cut+12
Repeat ; Small steps
cut-1 ; New trial cut point
Until TextWidth(Left(ln$,cut))<=printw ; Until it will fit
; Try not to split the last word, except at a hyphen
For p=cut To cut-12 Step -1
If FindString(" -_"+#TAB$, Mid(ln$,p,1), 1) ; If whitespace, hyphen or underscore
cut=p: Break ; Found a better cut point
EndIf
Next p
; Now cut the line, removing trailing whitespace
tmp$=RTrim(Left(ln$, cut))
If overflow$="+" ; If a continuation line
If Len(tmp$) ; Ignore empty continuation lines
If linenum>=linefrst And linenum<=linelast
AddElement(lines$()): lines$()=overflow$+tmp$
EndIf
EndIf
Else ; Not a continuation line
whitespace$=Left(tmp$, Len(tmp$)-Len(LTrim(tmp$))) ; Remember the leading whitespace
If linenum>=linefrst And linenum<=linelast
AddElement(lines$()): lines$()=overflow$+tmp$
EndIf
overflow$="+"
EndIf
ln$=LTrim(Mid(ln$,cut+1,9999)) ; Build the next continuation line
If Len(ln$): ln$=whitespace$+#continue$+ln$: EndIf ; Prepend the same leading whitespace
EndIf
Until Len(ln$)=0
Wend
CloseFile(#file)
;}
;{ Print the lines
; Calculate the number of pages to be printed
pages=(CountList(lines$())-1)/(lpp-2)+1 ; The -2 allows for the title lines on each page
; Calculate the start position of the [nearly] right-aligned page number
pagenumx=#Lmargin+pagew-TextWidth(Str(pages)+" of "+Str(pages))
; Fit the title [and build number] into the width available
title$+build$
titlew=pagenumx-#Lmargin-40
If TextWidth(title$)>titlew ; If too wide
titlew-TextWidth("...")
Repeat
title$=Mid(title$, FindString(title$,"\",2), 999) ; Truncate at left-most "\"
Until TextWidth(title$)<=titlew ; Until it will fit
title$="..."+title$ ; Prepend "..."
EndIf
; Now do the printing
linenum=linefrst-1
ForEach lines$()
If line=0 ; If starting a new page
pagenum+1
DrawText(#Lmargin, y, title$) ; Print title [and build number]
DrawText(pagenumx, y, Str(pagenum)+" of "+Str(pages)) ; Print page number
line=2: y+lineh*2 ; Leave a blank line
EndIf
If Left(lines$(),1)="#" ; If not a continuation line
linenum+1
DrawText(#Lmargin+TextWidth("1999")-TextWidth(Str(linenum)), y, Str(linenum)) ; "Print" linenumber
EndIf
DrawText(#Lmargin+linenumw, y, Mid(lines$(),2,9999)) ; "Print" text to the right of the line number column
line+1: y+lineh
If line>=lpp ; If the current page is full
line=0: y=#Tmargin
NewPrinterPage()
EndIf
Next lines$()
StopDrawing()
StopPrinting()
End
}
Last edited by akj on Mon Mar 20, 2006 10:45 am, edited 2 times in total.
Anthony Jordan