PB Editor, print command
Posted: Sun Feb 26, 2006 12:23 pm
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)
http://www.purebasic.com
https://www.purebasic.fr/english/
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
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 "¬".]
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
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]
I certainly agree. The fun is in the 'doing' not the 'viewing'.the fun of learning is to improve on it
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
}