Does RevPrintText Support A Page Break?

Got a LiveCode personal license? Are you a beginner, hobbyist or educator that's new to LiveCode? This forum is the place to go for help getting started. Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller

richmond62
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 9389
Joined: Fri Feb 19, 2010 10:17 am
Location: Bulgaria

Re: Does RevPrintText Support A Page Break?

Post by richmond62 » Sun Dec 27, 2020 12:49 pm

From the Documentation:

"Tip: If the textToPrint contains tags, the tags are interpreted as text style information.
To print tags literally, set the of a field to the text you want to print,
then use the HTMLText of that field as the textToPrint.
Converting to the HTMLText escapes the tags and allows them to be printed."

Somebody was being a bit sleepy with "set the of a field to the text"

From a web search:

"To suggest a page break, add <P style="page-break-before: always"> before the beginning of a new printed page."
sadly I cannot test it, because my old wreck of a printer, no longer will connect to my computers
I know the feeling.

You can, however, test things by doing a print-to-PDF.

TerryL
Posts: 78
Joined: Sat Nov 23, 2013 8:57 pm

Re: Does RevPrintText Support A Page Break?

Post by TerryL » Mon Dec 28, 2020 7:35 pm

Thanks to all for the comments.
@ Jacque. I saved your detailed description of printing with print break for another project. Thank you for your efforts.
@ Richmond62. The special paragraph tag <p...> for page break may be for printing a cascading style sheet web page from a browser.
Beginner Lab (LiveCode tutorial) and StarterKit (my public stacks)
https://tlittle72.neocities.org/info.html

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9842
Joined: Sat Apr 08, 2006 7:05 am
Location: Los Angeles
Contact:

Re: Does RevPrintText Support A Page Break?

Post by FourthWorld » Mon Dec 28, 2020 7:49 pm

richmond62 wrote:
Sun Dec 27, 2020 12:49 pm
From a web search:

"To suggest a page break, add <P style="page-break-before: always"> before the beginning of a new printed page."
Is that for LiveCode or browsers?
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

richmond62
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 9389
Joined: Fri Feb 19, 2010 10:17 am
Location: Bulgaria

Re: Does RevPrintText Support A Page Break?

Post by richmond62 » Mon Dec 28, 2020 8:11 pm

I'm getting cheesed off because I want to find out how to code a page break in 'pure' HTML5 without
any 'crap' anent CSS.

TerryL
Posts: 78
Joined: Sat Nov 23, 2013 8:57 pm

Re: Does RevPrintText Support A Page Break?

Post by TerryL » Tue Jan 05, 2021 8:05 pm

@ Richard. I've been able to add a forced page break feature to the revPrintText handler in the revPrintLibrary stack. Someone else will have to take it from here. It needs testing on all platforms, critical review, and <%formfeed%> update to the Dictionary's revPrintText and revPrintField pages.

I cleaned up some of the original code, and Richard, I included your tabAlign bug fix in the code. One snafu is <%formfeed%> should be inserted on its own line to correctly calculate cr's for a page break.

EDIT: Enabled <%expression%> in header/footer by including some script locals I had neglected previously. Code and download stack updated.
EDIT2: Why not. Added header/footer and page break to revPrintField. Download stack updated.
EDIT3: Submitted request, bug 23060. https://quality.livecode.com/show_bug.cgi?id=23060

Code: Select all

--requires fld "A" for revPrintText command
--<%formfeed%> evaluated as value(formfeed) = forced page break symbol
-- insert <%formfeed%> on separate line of text

on mouseUp  --print text with forced page break to pdf
   local tReport, tHeader
   put fld "A" into tReport  --alternate
   --put "This is page1." &cr& "<%formfeed%>" &cr& "This is page2." &cr& "<%formfeed%>" &cr& "This is page3." into tReport
   set the printmargins to 36,36,36,36  --L,T,R,B (.25"=18, .5"=36, 1"=72)
   set the printPaperOrientation to "portrait"  --or landscape
   revShowPrintDialog false,false  --no printer or page setup dialogs (must be in same handler as revPrintTest)
   answer "Please select your" &&quote& "Print-To-PDF/XPS" &quote&& "program instead of your printer." &cr&cr& \
         the availablePrinters with "OK" titled "Print To PDF"
   answer printer  --choose printer
   if result() = "Cancel" then exit to top
   set the cursor to watch
   put tab& "<%pageNumber%> of <%numPages%>" into tHeader  --header in param2, footer in param3  --***not working
   revPrintText tReport,tHeader,,the long name of fld "A"  --use fld "A" font/size/style
end mouseUp

--in msg box: edit the script of stack "revPrintLibrary"  --copy revPrintText and revPrintSetText handlers
local lPageNumber, pageNumber --holds lPageNumber between handlers
local lAnswerPrinter, lPageSetup
local numPages
constant kPo = "36"
on revPrintText pText,pHeader,pFooter,pSourceFieldRef,pHeaderFldRef,pFooterFldRef
   --pText contains the text, either html or text
   --pHeader contains header text, either html or text
   --pFooter contains header text, either html or text
   --pSourceFieldRef contains a vaild field descriptor
   local tActualPageWidth --width of page subtracting right and left printmargins
   local tPrintMargins --margins stored in array for script simplification
   local tPageWidth,tPageHeight --height and width of the page
   local tScrolling,tPageLine,tScrollList --scroll values for text height calculations
   lock messages
   --general initialization
   if the printPageNumber is empty then
      if lAnswerPrinter is empty then put "true" into lAnswerPrinter
      if lPageSetUp is empty then put "true" into lPageSetup
      if lPageSetup then answer page setup
      if the result is "Cancel" then return "cancel"
      if lAnswerPrinter then answer printer
      if the result is "Cancel" then return "cancel"
   end if
   open printing
   --setting up
   if pSourceFieldRef <> "" and pHeaderFldRef = "" then put pSourceFieldRef into pHeaderFldRef
   if pSourceFieldRef <> "" and pFooterFldRef = "" then put pSourceFieldRef into pFooterFldRef
   put item 1 of the printmargins into tPrintMargins["left"]
   put item 2 of the printmargins into tPrintMargins["top"]
   put item 3 of the printmargins into tPrintMargins["right"]
   put item 4 of the printmargins into tPrintMargins["bottom"]
   put item 3 of the printPaperRectangle - item 1 of the printPaperRectangle into tPageWidth
   put item 4 of the printPaperRectangle - item 2 of the printPaperRectangle into tPageHeight
   put "0" into tScrolling
   put "0" into tPageLine
   put "1" into lPageNumber
   put lPageNumber into pageNumber  --for <%pageNumber%>
   put tPageWidth - tPrintMargins["right"] - tPrintMargins["left"] into tActualPageWidth
   -- reset the stack & field templates (fixes wrapping bug where dontWrap of the templateField is set before calling)
   reset the templateStack
   reset the templateField
   -- prepare template for invisible stacks the width of the page
   set the backgroundColor of the templateStack to "white"
   if pSourceFieldRef is not empty then
      put revTargetStack(pSourceFieldRef) into tTargetStack
      set the underLineLinks of the templateStack to the underLineLinks of stack tTargetStack
      set the linkColor of the templateStack to the linkColor of stack tTargetStack
      set the linkHiliteColor of the templateStack to the linkHiliteColor of stack tTargetStack
      set the linkVisitedColor of the templateStack to the linkVisitedColor of stack tTargetStack
   end if
   set the visible of the templateStack to "false"
   set the width of the templateStack to tActualPageWidth
   --if the printerName is not "pdf" then  --original
   if "pdf" is not in the printerName then  --*forced page break update
      set the formatForPrinting of the templateStack to "false"
      set the formatForPrinting of the templateStack to "true"
   end if
   -- prepare template for fields in these stacks
   set the width of the templateField to tActualPageWidth
   -- the following three properties are set so that text height calculations are correct
   set the borderWidth of the templateField to "0"
   set the margins of the templateField to "6"
   set the showBorder of the templateField to "true"
   set the opaque of the templateField to "false"
   set the fixedLineHeight of the templateField to "false"
   set the lockLoc of the templateField to "true"
   -- header and footer initialization
   if pHeader is not empty then
      create stack "revTempHeader"
      set the defaultStack to "revTempHeader"
      set the backColor of this card to "white" -- work around 1955 unicode color issue
      revSetPrintFont pHeaderFldRef
      get revCreatePrintHeaderAndFooter(pHeader)
      -- if size of header or footer is greater then current margins will allow, then increase top or bottom margins.
      if it > tPrintMargins["top"] then put it into tPrintMargins["top"]
   end if
   if pFooter is not empty then
      create stack "revTempFooter"
      set the defaultStack to "revTempFooter"
      set the backColor of this card to "white" -- work around 1955 unicode color issue  *forced page break update
      revSetPrintFont pFooterFldRef
      get revCreatePrintHeaderAndFooter(pFooter)
      if it > tPrintMargins["bottom"] then put it into tPrintMargins["bottom"]
   end if
   --body initialization
   global gREVPrintFileName
   if gREVPrintFileName is empty or there is a stack gREVPrintFileName then put "revTempBody" into gREVPrintFileName
   create stack gREVPrintFileName
   set the defaultStack to gREVPrintFileName
   set the height of this stack to tPageHeight - tPrintMargins["bottom"] - tPrintMargins["top"]
   revSetPrintFont pSourceFieldRef
   create field
   if pSourceFieldRef is not empty then
      set the tabStops of fld 1 to the tabStops of pSourceFieldRef
      set the hGrid of fld 1 to the hGrid of pSourceFieldRef
      set the vGrid of fld 1 to the vGrid of pSourceFieldRef
      set the fixedLineHeight of fld 1 to the fixedLineHeight of pSourceFieldRef -- NEW
      set the textHeight of fld 1 to the effective textHeight of pSourceFieldRef -- NEW
      set the textAlign of fld 1 to the effective textAlign of pSourceFieldRef
      if version() >= "7.0" then set the tabAlign of fld 1 to the effective tabAlign of pSourceFieldRef --NEW
   end if
   set the rect of fld 1 to the rect of this card
   revPrintSetText pText  --convert <%expression%> to value(expression)
   
   ----*start forced page break update
   local tPgHeight, tTxtHeight, tRowsInPg, tSkipC="0", tBreakChar, tRanges, tPage, tRowsToBreak, tReturns, tCount
   put line 1 of the pageHeights of fld 1 into tPgHeight  --page height in pixels
   put the effective textHeight of fld 1 into tTxtHeight  --row height in pixels
   put trunc(tPgHeight / tTxtHeight) into tRowsInPg  --rows/page (not lines/page)
   repeat
      put offset(value(formfeed),fld 1,tSkipC) into tBreakChar  --break symbol char
       if tBreakChar = "0" then exit repeat  --escape, no break symbols
      add tBreakChar to tSkipC  --char search
      put the pageRanges of fld 1 into tRanges  --line list of page ranges: startChar,endChar
      repeat with i = 1 to number(lines in tRanges)
         if tSkipC <= item 2 of line i of tRanges then
            put i into tPage  --break symbol char on page i
            exit repeat
         end if
      end repeat
      set the vScroll of fld 1 to (tPgHeight * (tPage - 1))  --first break char on page
      select after char tSkipC of fld 1  --for selectedLoc(): vertical distance from top of stack to top of break char in pixels
      put trunc((item 2 of selectedLoc(fld 1) - the top of fld 1 + tTxtHeight) / tTxtHeight) into tRowsToBreak
      put tRowsInPg - tRowsToBreak into tReturns  --number of returns to force page break
      repeat tReturns
         put cr after tCount
      end repeat
      put tCount after char tSkipC of fld 1  --force page break
      put empty into tCount  --reset
      --delete char tSkipC of fld 1  --break symbol
   end repeat
   ----*end forced page break update
   
   put the pageHeights of fld 1 into tScrollList
   --printing cycle
   -- headers and footers are split up into three fields by tab items
   set the itemDel to tab
   put the number of lines of tScrollList into numPages  --for <%numPages%>, only supported in header/footer
   --repeat  --original
   repeat numPages
      if pHeader is not empty then
         set the defaultStack to "revTempHeader"
         repeat with lLoop = 1 to 3
            put item lLoop of pHeader into fld lLoop
            if fld lLoop <> empty then revPrintSetText fld lLoop,lLoop
         end repeat
         print this card into tPrintMargins["left"],kPo,tPageWidth-tPrintMargins["right"],kPo+the height of stack "revTempHeader"
      end if
      if pFooter is not empty then
         set the defaultStack to "revTempFooter"
         repeat with lLoop = 1 to 3
            put item lLoop of pFooter into fld lLoop
            if fld lLoop <> empty then revPrintSetText fld lLoop,lLoop
         end repeat
         print this card into tPrintMargins["left"],tPageHeight-kPo-height of stack "revTempFooter",tPageWidth-tPrintMargins["right"],tPageHeight-kPo
      end if
      add 1 to tPageLine
      add 1 to lPageNumber
      put lPageNumber into pageNumber  --for <%pageNumber&>, only supported in header/footer
      set the defaultStack to gREVPrintFileName
      set the height of fld 1 to line tPageLine of tScrollList
      set the vScroll of fld 1 to tScrolling
      print this card into tPrintMargins["left"],tPrintMargins["top"],tPageWidth-tPrintMargins["right"],tPageHeight - tPrintMargins["bottom"]
      add line tPageLine of tScrollList to tScrolling  --reset
      if tPageLine = numPages then exit repeat
      print break
   end repeat
   --clean up
   close printing
   if there is a stack "revTempHeader" then delete stack "revTempHeader"
   if there is a stack "revTempFooter" then delete stack "revTempFooter"
   if there is a stack gREVPrintFileName then delete stack gREVPrintFileName  --page break update
   --delete stack gREVPrintFileName  --original
   reset the templateStack
   reset the templateField
end revPrintText

on revPrintSetText pTheText, pFldNum
  local tExpressionStart, tExpressionEnd
  if pFldNum = "" then put "1" into pFldNum
  if "<p>" is in pTheText or matchChunk(pTheText, "<(.+>.+</.+)>") is "true" then set the htmlText of fld pFldNum to pTheText
  else put pTheText into fld pFldNum
  repeat until matchChunk(fld pFldNum, "<%(.[^<]*)%>", tExpressionStart, tExpressionEnd) is "false"
    put value(char tExpressionStart to tExpressionEnd of fld pFldNum) into char tExpressionStart-2 to tExpressionEnd+2 of fld pFldNum
  end repeat
end revPrintSetText
Attachments
PageBreak.zip
stack all setup
(6.51 KiB) Downloaded 142 times
Beginner Lab (LiveCode tutorial) and StarterKit (my public stacks)
https://tlittle72.neocities.org/info.html

Post Reply

Return to “Getting Started with LiveCode - Complete Beginners”