yTxt2PDF : convert any plain text (even web Html) to PDF

Published on by Yousfi Benameur

          

Foxypreviewer can translate any  txt file (even big one as a book) to pdf (save this code as ytxt2pdf.prg)
the text can be from any web page (html)converted to txt file or any local txt file.
the txt file is divided into pages and passed to  a memo  field ytext of a cursor playing the role of dataenvironment of the report.
when the report appears to modify, can customize margins,page width,page height,fonts,fields.....as your convenience and accordly to the number of lines/page.(can do that offline).the code ask to point to foxypreviewer location if its not already  loaded in memory (copy foxypreviewer.app in the source folder is better).
the report ytemp.frx (frx+frt) must be created manually before running this code.
the output is a pdf file opened with the default acrobat viewer.
the lines/page is important .can adjust and control after rendering report).
if ou compile an exe (ytxt2pdf.exe) make a project add this file and a config.fpw and put foxypreviewer.app in same folder (mark it as excluded).
this option is built automatically by the code *2* (ybuildexe.prg).
Note : the report ytemp.frx must be marked mandatory as excluded to prepare it to modify (otherwise its compiled and stays readonly).
can modify the report look (open it as a normal table and update any field) and in parallel the output PDF produced.
the structure of report is in the option (3).Use objtype and objcode to modify fonts,colors,...style.this is document in option 3 and 4 of the code.
note : you can put a top level form as permanent support of this app.here can run 1 option and exit...
*top level form added in codes *3* and *4*

[Post 250]


Click on code to select [then copy] -click outside to deselect


*1* created on sunday 17 of december 2017
*ytxt2pdf  convert any plain txt (even web html) to PDf
*use Foxypreviewer.app (can download it on https://vfpx.github.io/)

If !_vfp.StartMode=0
  On Shutdown Quit
Endi

_Screen.Closable=.F.  &&important for modiying report.

Publi m.yrep
m.yrep=Addbs(Justpath(Sys(16,1)))
Set Defa To (yrep)

If ! File(m.yrep+"ytemp.frx")
  Messagebox("must create the report ytemp.frx before continue!...cancelling.",16+4096)
  Return .F.
  *Create Report ytemp   From  ycurs Width 1  &&better create/use custom report
Endi

Local m.inp
m.inp=Inputbox("Web txt file(0)-local file (1)-Help (2)-Documentation (3)-Change report style (4)","","0")
If Empty(m.inp)
  Return .F.
Endi
If !Inlist(m.inp,"0","1","2","3","4")
  m.inp="1"
Endi

Do Case
  Case m.inp="0"
    Do ytxt2pdf0

  Case m.inp="1"
    Do ytxt2pdf1

  Case m.inp="2"
    Do yhelp

  Case m.inp="3"
    Local m.myvar
    TEXT to m.myvar pretext 7 noshow
.FRX and .LBX Table Structure for Visual FoxPro for Windows
this is utile to traverse the report as table and modify each object in the table structure
can use this code :
------------------------
use myreport
brow  &&can update fields here
use in select("myreport")
------------------------
this is relative to vfp9 (see other report for other versions in same folder).
this builds a pdf from the report in home(1)+"tools\filespec\90.frx" as documentation for use.
All modifications you can do in report designer can be done from modifying the report table but you must
know the structure and meaning of each field.(see in particular objtype and objCode fields).

    ENDTEXT
    Messagebox(m.myvar,0+32+4096,'')

    Try  &&if user cancel locfile dialog ....to avoid returning error
      Do Locfile("FoxyPreviewer.App")  &&dialog to pint to the app
      * build PDF
      If File(m.yrep+"ytemp.pdf")
        Erase  (m.yrep+"ytemp.pdf")
      Endi
      Report Form  (Home(1)+'tools\filespec\90frx.frx')  Object Type 10 To File (m.yrep+"ytemp.Pdf")   Preview
    Catch
    Endtry

  Case m.inp="4"
    Do yreport_change
Endcase

m.yrep=Null
Release m.yrep
_Screen.Closable=.T.   &&reset vfp exit(X)
if !_vfp.startmode=0
Quit
endi

*

Procedure ytxt2pdf0
  Local lcUrl
  m.lcUrl=Inputbox("type teh web url here","","http://www.fullbooks.com/Les-Miserables-by-Victor-Hugo-trans-Isabel-F1.html")
  If Empty(m.lcUrl) Or ! Lower(Substr(m.lcUrl,1,7))=="http://"
    Messagebox("cancelling...!",4+4096,'error',1200)
    Return .F.
  Endi

  *download as demo any big book (even html) as txt file.download one time and its saved here as txt file.
  Local m.ydownl,m.lcbook
  m.downl=.T.
  If m.downl=.T.  &&turn it to .f. if already downloaded to skip this step.
    #Define OLECMDID_SAVEAS 4
    #Define OLECMDEXECOPT_DONTPROMPTUSER  2
    Local apie
    apie = Createobject('internetexplorer.application')
    With apie
      .Navigate(m.lcUrl)   &&http://www.fullbooks.com/Droll-Stories-Complete1.html')
      Do While.readystate#4  &&pass the transitionning (can put 5 sec as inke(5)).
      Enddo
      Inke(1)
      apie.ExecWB(OLECMDID_SAVEAS ,OLECMDEXECOPT_DONTPROMPTUSER,m.yrep+"book.txt","")  &&there is a bug in IE11 the dialog shows always in contary of the command!
      .Quit
    Endwith
  Endi

  Local m.maxl,i,j,N,m.xtext,m.cr,m.x
  m.xtext=Filetostr(m.yrep+"book.txt")
  N=Alines(yArray,m.xtext,4)
  m.cr=Chr(13)

  Create Cursor ycurs (ytext m)

  If ! File(m.yrep+"ytemp.frx")
    Messagebox("must create the report ytemp.frx before continue!",16+4096)
    Return .F.
    *Create Report ytemp   From  ycurs Width 1    && better create/use custom report
  Endi

  _Screen.Visible=.T.  &&for exe
  Modi Repo ytemp   &&iCan modify/customize somethings here- right click on repo (in designer) to modify left margin,page width,page hight,adjust field ytext,date,pageno....see specimen image below ( can comment this line).

  m.j=1
  m.x=""

  Set Memo To 8192  &&very important to have always same lines/page in report as set in m.max variable
  m.maxl=70  && lines per page

  For m.i=1 To m.n
    m.x=m.x+Chr(9)+yArray[i]+Chr(13)

    If  m.j>m.maxl
      Insert Into ycurs Values (cr+m.x)
      m.j=1
      m.x=""
    Else
      m.j=m.j+1
    Endi
  Endfor
  If !Empty(m.x)
    Insert Into ycurs Values (cr+m.x)   && add the last chunk
  Endi
  *brow
  Try  &&if user cancel locfile dialog ....to avoid returning error
    Do Locfile("FoxyPreviewer.App")  &&dialog to pint to the app
    Sele ycurs
    Copy To mytable
    * build PDF
    If File(m.yrep+"ytemp.pdf")
      Erase (m.yrep+'ytemp.pdf')
    Endi
    Report Form  (m.yrep+'ytemp.frx')  Object Type 10 To File (m.yrep+"ytemp.Pdf")   Preview
  Catch

  Endtry

  _Screen.Visible=.F.
  Return
Endproc

*

Procedure ytxt2pdf1

  Local m.lcbook
  m.lcbook=Getfile('txt')
  If  Empty(m.lcbook)
    Return .F.
  Endi


  Local m.maxl,i,j,N,m.xtext,m.cr,m.x
  m.xtext=Filetostr(m.lcbook)
  N=Alines(yArray,m.xtext,4)
  m.cr=Chr(13)

  Create Cursor ycurs (ytext m)

  If ! File(m.yrep+"ytemp.frx")
    Messagebox("must create the report ytemp.frx before continue!",16+4096)
    Return .F.
    *Create Report ytemp   From  ycurs Width 1
  Endi

  _Screen.Visible=.T.  &&for exe
  Modi Repo ytemp   &&iCan modify/customize somethings here- right click on repo (in designer) to modify left margin,page width,page hight,adjust field ytext,date,pageno....see specimen image below ( can comment this line).


  Set Memo To 8192  &&very important to have always same lines/page as set in m.max variable
  m.j=1
  m.x=""
  m.maxl=70  && lines per page

  For m.i=1 To m.n
    m.x=m.x+Chr(9)+yArray[i]+Chr(13)
    If  m.j>m.maxl
      Insert Into ycurs Values (cr+m.x)
      m.j=1
      m.x=""
    Else
      m.j=m.j+1
    Endi
  Endfor
  If !Empty(m.x)
    Insert Into ycurs Values (cr+m.x)   && add the last chunk
  Endi
  *brow

  Try  &&if user cancel locfile dialog ....to avoid returning error
    Do Locfile("FoxyPreviewer.App")  &&dialog to pint to the app
    Sele ycurs
    Copy To mytable
    * build PDF
    If File(m.yrep+"ytemp.pdf")
      Erase  (m.yrep+"ytemp.pdf")
    Endi
    Report Form  (m.yrep+'ytemp.frx')  Object Type 10 To File (m.yrep+"ytemp.Pdf")   Preview
  Catch
  Endtry
  _Screen.Visible=.F.
  Return
Endproc

*

Procedure yhelp
  Local xwidth,xheight,xtitle,xtext,m.xpict
  m.xwidth= "640"
  m.xheight="660"
  m.xtitle="  ytxt2PDF convert any txt file to pdf  "
  TEXT to m.xtext noshow
<strong>Foxypreviewer can translate any  txt file (even big one as a book) to pdf </strong>(save this code as ytxt2pdf.prg)<br>
the text can be from any web page (html)converted to txt file or any local txt file.<br>
the txt file is divided into many pages and passed to  a memo  field ytext of a cursor playing the role of dataenvironment of the report.<br>
when the report appears to modify, can customize margins,page width,page height,fonts,fields.....as your convenience and accordly to the
 number of lines/page.(can do that offline).the code ask to point to foxypreviewer location if its not already  loaded in memory <br>
(copy foxypreviewer.app in the source folder is better).<br>
<strong style="color:blue;">the report ytemp.frx (frx+frt) must be created manually before running this code.</strong><br>
the output is a pdf file opened with the default acrobat viewer.<br>
the lines/page is important .can adjust and control after rendering report).<br>
if ou compile an exe (ytxt2pdf.exe) make a project add this file and a config.fpw and put foxypreviewer.app in same folder (mark it as excluded).<br>
<p style="color:red;font-family:script;font-size:22px;">this option is built automatically by the code *2* (ybuildexe.prg).</p><br>
Note : the report ytemp.frx must be marked mandatory as excluded to prepare it to modify (otherwise its compiled and stays readonly).<br>
can modify the report look (open it as a normal table and update any field) and in parallel the output PDF produced.<br>
the structure of report is in the option (3).Use objtype and objcode to modify fonts,colors,...style.this is document in option 3 and 4 of the code.
More infos in my blog  <a href="http://www.yousfi.over-blog.com/"</a>
  ENDTEXT
  m.xpict="http://img.over-blog-kiwi.com/1/43/54/07/20171204/ob_2f9ca2_3.png"  &&web url also

  =ybuild(m.xwidth,m.xheight,m.xtitle,m.xtext,m.xpict)
  Retu
Endproc
*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*
*dont touch from here!
*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*

Function ybuild()
  Lparameters xwidth,xheight,xtitle,xtext,xpict
  Local m.myvar
  TEXT to m.myvar textmerge pretext 7 noshow
<title></title>
<style>
body { background-color: #f5f5d0;
  background: linear-gradient(to bottom, blue, indigo 50%, navy);
  scroll:no;
  }

.DlgMsg {
	font-family: Segoe UI, Arial;
	font-size: 11pt;
	color: #603030;
	padding:10px 15px;
	position: relative;top: 15px;left:10px;
}
.p1 {font-weight:italic;color:tomato;}
.DlgButtons {
    position:relative;top:30px;
}
.DlgBtn {
	font-family: Segoe UI, Arial;
	font-size: 12pt;
	font-weight: 700;
	color: #704040;
	background-color: #d1a5a5;
	border: 1px solid #907060;
	width: 70px;
	height: 27px;
}
h2 {color:orange;background-color:navy}
</style>

<body style=" scroll:no;background:url('');repeat:repeat;background-color:moccasin; " >
<table style="padding:10px;width:100%"> <tr>
<td width="15px"></td>
<td style="background-color:navy;"><a href="http://www.yousfi.over-blog.com"><img src="<<m.xpict>>" alt="My Blog" width="64" height="64" style="border:0;float:left;"></a></td>
<td style="color:white;font-size:22px;background-color:navy;"><center>  <<m.xtitle>>  </center></td>
</tr></table>


 <div class="DlgMsg"><Strong>ShowHTMLDialog</Strong>
<<m.xtext>>
</div>
<center><div class="DlgButtons">
<input class="DlgBtn" id="btnOk" type="Submit" value="OK"> </center>

</div>
<script for="btnOk" event="onclick">
	window.returnValue="Agree";
	window.close();
</script>
</body></html>
  ENDTEXT

  Set Safe Off
  Strtofile(m.myvar,m.yrep+"dlgdefinition.html")
  #Define URL_MK_LEGACY 0
  #Define URL_MK_UNIFORM 1
  Do Declare
  Local m.cDlgDefinitionFile, m.cUrl, m.nUrlMoniker, m.cFeatures,;
    m.cArguments, m.cOutput, m.cDlgReturn
  * the dialog definition is stored in local HTML file
  m.cDlgDefinitionFile=Lower(m.yrep+"dlgdefinition.html")
  If Not File(m.cDlgDefinitionFile)
    Messagebox("file"+m.yrep+ "dlgdefinition.html must be created before running this code",16+4096)
    Return .F.
  Endif

  * create URL Moniker from the Url
  m.cUrl=ToUnicode(m.cDlgDefinitionFile)
  m.nUrlMoniker=0
  If CreateURLMonikerEx(0, m.cUrl, @nUrlMoniker, URL_MK_UNIFORM) <> 0
    Messagebox("failed...cancelling !")
    Return  && failed
  Endif

  * ShowHTMLDialog input parameteres
  m.cFeatures=ToUnicode("dialogWidth:"+m.xwidth+"px ;dialogHeight:"+m.xheight+"px;center:1;")
  m.cArguments=ToUnicode("")
  m.cOutput=Replicate(Chr(0), 256)
  m.cDlgReturn=""

  If ShowHTMLDialog(_Screen.HWnd, m.nUrlMoniker,;
      m.cArguments, m.cFeatures, @cOutput) = 0
    nAddr=buf2dword(Substr(cOutput,9,4))
    If m.nAddr <> 0
      cDlgReturn=FromUnicode( Mem2Str(nAddr) )
    Endif
  Endif
  *return  cDlgReturn   &&can use to return value (here its a simple modal messagebox )
Endfunc

Procedure Declare
  Declare Integer CreateURLMonikerEx In urlmon  Integer pMkCtx, String szURL,Integer @ppmk, Long dwFlags
  Declare Integer ShowHTMLDialog In mshtml  Integer hwndParent, Integer pMk, String pvarArgIn, String pchOptions, String @pvarArgOut
  Declare RtlMoveMemory In kernel32 As MemToStr   String @, Integer, Integer
Endproc

Function buf2dword(cBuffer)
  Return Asc(Substr(cBuffer, 1,1)) + ;
    BitLShift(Asc(Substr(cBuffer, 2,1)),  8) +;
    BitLShift(Asc(Substr(cBuffer, 3,1)), 16) +;
    BitLShift(Asc(Substr(cBuffer, 4,1)), 24)
Endfunc

Function ToUnicode(cStr)
  Return Strconv(cStr+Chr(0), 5)
Endfunc

Function FromUnicode(cStr)
  Return Strtran(Strconv(cStr, 6), Chr(0), "")
Endfunc

Function Mem2Str(nBaseAddr As Number)
  #Define BUFFER_SIZE 16
  #Define EMPTY_BUFFER Replicate(Chr(0), BUFFER_SIZE)
  * reads Unicode string from specified memory address
  If nBaseAddr = 0
    Return ""
  Endif
  Local nCurAddr, cResult, cBuffer, nPos
  nCurAddr=nBaseAddr
  cResult=""

  Do While .T.
    cBuffer = EMPTY_BUFFER
    = MemToStr(@cBuffer, nCurAddr, BUFFER_SIZE)
    nPos = At(Chr(0)+Chr(0), cBuffer)
    If nPos > 0
      cResult = cResult + Substr(cBuffer, 1, nPos)
      Return cResult
    Else
      cResult = cResult + cBuffer
      nCurAddr = m.nCurAddr + BUFFER_SIZE
    Endif
  Enddo
Endfunc

*

Procedure yreport_change
  *open the report frx as a table .can  modify colors ,fontname,font styles   manually or programmatly....
  *here the report is modified programmatly uneditable for the demo (can modify out of thiss app).
  Close Data All

  If !Vartype(m.yrep)="C"
    m.yrep=Addbs(Justpath(Sys(16,1)))
    Set Defa To (yrep)
  Endi

  If !File("mytable.dbf")
    Messagebox("execute first the txt2pdf0 or pdf1 to create table mytable",16+4096,"",2000)
    Return .F.
  Endi
  Messagebox("Can customize any thing in report opened as table  ytemp.frx.This is a demo!",0+32+4096,"",2000)
  _Screen.Visible=.T.

  Use  ytemp.frx  Shared
  Repl All penRed With 0,penGreen With 0
  Repl All penBlue With 0
  Repl All fillRed With -1,fillGreen With -1
  Repl All fillBlue With -1
  Repl All fontstyle With 0 For objtype=8 And objcode=0

  Repl All penRed With 255,penGreen With 140 , penBlue With 10        For  objtype=5  &&header (label)
  Repl All penRed With 0,penGreen With 0 , penBlue With 255           For  objtype=8 And objcode=0  &&fields detail+date+page
  Repl All penRed With 200,penGreen With 100 , penBlue With 120       For  uniqueID="_5310OBFCL"
  Repl All penRed With 255,penGreen With 255 , penBlue With 155       For  uniqueID="_5310OBFET"

  Repl fontstyle With 1   For objtype=8 And objcode=0
  Repl fillpat   With 8   For objtype=8 And objcode=0
  Repl fillRed With 218,fillGreen With 255 , fillBlue With 181     For objtype=8 And objcode=0

  Repl  fontstyle With 1 For objtype=7 And objcode=4
  Repl  penRed With 255,penGreen With 0 , penBlue With 0       For objtype=7 And objcode=4
  Repl fillRed With 213,fillGreen With 255, fillBlue With 255  For objtype=7 And objcode=4

  Repl fontstyle With 1  For  uniqueID="_5310OBFCL" Or  uniqueID="_5310OBFET"
  Repl fillRed With 255,fillGreen With 232, fillBlue With 153  For uniqueID="_5310OBFCL"
  Repl fillRed With 55,fillGreen With 32, fillBlue  With 153   For uniqueID="_5310OBFET"

  Brow  title "report  ytemp.frx as table-not editable here (demo only)" Noedit
  Use In Select("ytemp.frx")


  Try  &&if user cancel locfile dialog ....to avoid returning error
    Do Locfile("FoxyPreviewer.App")  &&dialog to pint to the app
    Use mytable
    * build PDF
    If File(m.yrep+"ytemp.pdf")
      Erase  (m.yrep+"ytemp.pdf")
    Endi
    Report Form  (m.yrep+'ytemp.frx')  Object Type 10 To File (m.yrep+"ytemp.Pdf")   Preview
  Catch
  Endtry

  Use In Select("mytable")
  _Screen.Visible=.F.
Endproc




click on image to enlarge  it.

click on image to enlarge it.

Click on code to select [then copy] -click outside to deselect


*2* created on sunday 17 of december 2017
*save this prg as ybuildexe.prg
*it builds programmatly a proj from (ytxt2pdf.prg as above and add a config.fpw) an compile+clean
*it builds an executable app and cleans all tools used to achieve this goal.
*the executable built is ytxt2pdf.exe (can create a desktop shortcut to run it or pin it on taskbar....)
*remember the report (frx+frt) ytem.frx must bein same folder as sources and foxypreviewer.app also(better to avoid locate dialog....)

Set Safe Off
Local m.yrep
m.yrep=Addbs(Justpath(Sys(16,1)))
Set Defa To (yrep)

*build file configuration config.fpw
Local m.myvar
TEXT to m.myvar noshow
screen=off
resource=off
safe=off
ENDTEXT
Strtofile(m.myvar, "config.fpw")

*build proj and compile to exe
Build Project yfoo  From  "ytxt2pdf.prg" ,"config.fpw"
Build Exe ytxt2pdf.Exe From yfoo
Inkey(1)

*clean traces
Dele File yfoo*.*
If File(m.yrep+"ytxt2pdf.exe",1)
  Messagebox("ytxt2pdf.exe created!",0+32+4096,"Create an exe",1000)
Endi

Try
  Dele File config.fpw
Catch
Endtry
Set Safe On

local m.o
m.o=m.yrep+"ytxt2pdf.exe"
Run/N &o



yTxt2PDF : convert any plain text (even web Html)  to PDF
yTxt2PDF : convert any plain text (even web Html)  to PDF
yTxt2PDF : convert any plain text (even web Html)  to PDF
yTxt2PDF : convert any plain text (even web Html)  to PDF
yTxt2PDF : convert any plain text (even web Html)  to PDF
yTxt2PDF : convert any plain text (even web Html)  to PDF

Click on code to select [then copy] -click outside to deselect


*3* created on 17 of december 2017
*this is the same code as above but transformed in a top level form.
*save it as ytxt2pdf_form.prg (mandatory for build exe below)
*can execute the code *4* to build an exe programmatly

If ! _vfp.StartMode=0
  On Shutdown Quit
Endi
_Screen.WindowState=1
Do ydeclare

Public oform
oform=Newobject("ytxt2pdf")
oform.Show
Read Events
Return

*
Define Class ytxt2pdf As Form
  BorderStyle = 0
  Height = 200
  Width = 597
  ShowWindow = 2
  AutoCenter = .T.
  Caption = "ytxt2pdf"
  BackColor=Rgb(212,210,208)
  BorderStyle=1
  Name = "Form1"
  
  Add Object ybkg1 as ybkg with ;
  left=10,;
  top=5,;
  name="ybkg1"
  
  Add Object LABEL1 As Label With;
    AutoSize = .T.,;
    FontBold = .T.,;
    FontName = "Arial",;
    FontSize = 32,;
    FontItalic=.T.,;
    BackStyle = 0,;
    Caption = "YTXT2PDF",;
    Height = 54,;
    Left = 197+4,;
    Top = 1+3,;
    Width = 199,;
    ForeColor = Rgb(45,45,45) ,;
    Name = "Label1"

  Add Object ysystem1 As ysystem With ;
    left=597-65,;
    top=1,;
    name="ysystem1"

  Add Object LABEL2 As Label With;
    AutoSize = .T.,;
    FontBold = .T.,;
    FontName = "Arial",;
    FontSize = 32,;
    FontItalic=.T.,;
    BackStyle = 0,;
    Caption = "YTXT2PDF",;
    Height = 54,;
    Left = 197,;
    Top = 1,;
    Width = 199,;
    ForeColor =Rgb(255,128,54),;
    Name = "Label2"

  Add Object command1 As CommandButton With ;
    AutoSize = .F., ;
    Top = 36+20, ;
    Left = 12, ;
    Height = 27, ;
    Width = 107, ;
    FontBold = .T., ;
    Caption = "from txt file", ;
    MousePointer = 15, ;
    BackColor = Rgb(128,0,64), ;
    Name = "Command1"

  Add Object command2 As CommandButton With ;
    AutoSize = .F., ;
    Top = 85+20, ;
    Left = 10, ;
    Height = 27, ;
    Width = 107, ;
    FontBold = .T., ;
    Caption = "From web page", ;
    MousePointer = 15, ;
    BackColor = Rgb(128,255,0), ;
    Name = "Command2"

  Add Object text1 As TextBox With ;
    Height = 27, ;
    Left = 122, ;
    Top = 84+20, ;
    Visible = .T., ;
    Width = 421, ;
    Name = "Text1"

  Add Object command3 As CommandButton With ;
    AutoSize = .F., ;
    Top = 83+17, ;
    Left = 551, ;
    Height = 27, ;
    Width = 36, ;
    FontBold = .T., ;
    Caption = "Go", ;
    MousePointer = 15, ;
    BackColor = Rgb(128,255,0), ;
    Name = "Command3"

  Add Object text2 As TextBox With ;
    Height = 27, ;
    Left = 121, ;
    Top = 36+20, ;
    Visible = .T., ;
    Width = 421, ;
    Name = "Text2"

  Add Object command4 As CommandButton With ;
    AutoSize = .F., ;
    Top = 40+17, ;
    Left = 550, ;
    Height = 27, ;
    Width = 36, ;
    FontBold = .T., ;
    Caption = "Go", ;
    MousePointer = 15, ;
    BackColor = Rgb(128,0,64), ;
    Name = "Command4"

  Add Object command5 As CommandButton With ;
    Top = 132+20, ;
    Left = 12, ;
    Height = 25, ;
    Width = 120, ;
    FontBold = .T., ;
    FontSize = 10, ;
    Caption = "Help", ;
    MousePointer = 15, ;
    BackColor = Rgb(255,128,0), ;
    Name = "Command5"

  Add Object command6 As CommandButton With ;
    Top = 132+20, ;
    Left = 211, ;
    Height = 25, ;
    Width = 120, ;
    FontBold = .T., ;
    FontSize = 10, ;
    Caption = "report_changes", ;
    MousePointer = 15, ;
    BackColor = Rgb(255,128,0), ;
    Name = "Command6"

  Add Object ydoc As CommandButton With ;
    Top = 152 , ;
    Left = 361, ;
    Height = 25, ;
    Width = 120, ;
    FontBold = .T., ;
    FontSize = 10, ;
    Caption = "Documentation", ;
    MousePointer = 15, ;
    BackColor = Rgb(255,128,0), ;
    Name = "ydoc"

  Procedure LABEL2.MouseEnter
    Lparameters nButton, nShift, nXCoord, nYCoord
    This.ForeColor=Rgb(0,255,0)
  Endproc

  Procedure LABEL2.MouseLeave
    Lparameters nButton, nShift, nXCoord, nYCoord
    This.ForeColor= Rgb(255,128,54)
  Endproc

  Procedure ydoc.Click
    Local m.myvar
    TEXT to m.myvar pretext 7 noshow
		.FRX and .LBX Table Structure for Visual FoxPro for Windows
		this is utile to traverse the report as table and modify each object in the table structure
		can use this code :
		------------------------
		use myreport
		brow  &&can update fields here
		use in select("myreport")
		------------------------
		this is relative to vfp9 (see other report for other versions in same folder).
		this builds a pdf from the report in home(1)+"tools\filespec\90.frx" as documentation for use.
		All modifications you can do in report designer can be done from modifying the report table but you must
		know the structure and meaning of each field.(see in particular objtype and objCode fields).

    ENDTEXT
    Messagebox(m.myvar,0+32+4096,'')

    Try  &&if user cancel locfile dialog ....to avoid returning error
      *  Do Locfile("FoxyPreviewer.App")  &&dialog to pint to the app
      * build PDF
      If File(m.yrep+"ytemp.pdf")
        Erase  (m.yrep+"ytemp.pdf")
      Endi
      Report Form  (Home(1)+'tools\filespec\90frx.frx')  Object Type 10 To File (m.yrep+"ytemp.Pdf")   Preview
    Catch
    Endtry
  Endproc


  Procedure Init
    Publi m.yrep
    m.yrep=Addbs(Justpath(Sys(16,1)))
    Set Defa To (yrep)
    Thisform.TitleBar=0
  Endproc

  Procedure KeyPress
    Lparameters nKeyCode, nShiftAltCtrl
    If nKeyCode=27
      Thisform.Release
    Endi
  Endproc

  Procedure MouseDown
    Lparameters nButton, nShift, nXCoord, nYCoord
    lnHandle = Thisform.HWnd
    param1 = 274
    param2 = 0xF012

    Thisform.MousePointer=15
    bb=ReleaseCapture()
    bb=SendMessage(lnHandle, param1, param2,0)
    Thisform.MousePointer=0
  Endproc

  Procedure Load
    Set Safe Off
    Do Locfile("foxypreviewer.app")
  Endproc

  Procedure Destroy
    m.yrep=Null
    Release m.yrep
    oform=Null
    Release oform
    Clea Events
  Endproc

  Procedure command1.Click
    Thisform.text1.Visible=.T.
    Local m.lcfile
    m.lcfile=Getfile("txt|htm|html|prg|mpr|log")
    If Empty(m.lcfile)
      Return .F.
    Endi

    Thisform.text2.Value=m.lcfile
    Thisform.text2.Visible=.T.
  Endproc

  Procedure command2.Click
    Thisform.text1.Visible=.T.
    Thisform.text1.Value="http://www.fullbooks.com/Les-Miserables-by-Victor-Hugo-trans-Isabel-F1.html"
  Endproc

  Procedure text1.RightClick
    This.Value=_Cliptext
  Endproc

  Procedure command3.Click
    Local lcUrl
    m.lcUrl=Thisform.text1.Value
    If Empty(m.lcUrl) Or ! Lower(Substr(m.lcUrl,1,7))=="http://"
      Messagebox("Url invalid...to correct!",4+4096,'error',1200)
      Return .F.
    Endi

    *download as demo any big book (even html) as txt file.download one time and its saved here as txt file.
    Local m.ydownl,m.lcbook
    m.downl=.T.
    If m.downl=.T.  &&turn it to .f. if already downloaded to skip this step.
      #Define OLECMDID_SAVEAS 4
      #Define OLECMDEXECOPT_DONTPROMPTUSER  2
      Local apie
      apie = Createobject('internetexplorer.application')
      With apie
        .Navigate(m.lcUrl)   &&http://www.fullbooks.com/Droll-Stories-Complete1.html')
        Do While.readystate#4  &&pass the transitionning (can put 5 sec as inke(5)).
        Enddo
        Inke(1)
        apie.ExecWB(OLECMDID_SAVEAS ,OLECMDEXECOPT_DONTPROMPTUSER,m.yrep+"book.txt","")  &&there is a bug in IE11 the dialog shows always in contary of the command!
        .Quit
      Endwith
    Endi

    Local m.maxl,i,j,N,m.xtext,m.cr,m.x
    m.xtext=Filetostr(m.yrep+"book.txt")
    N=Alines(yArray,m.xtext,4)
    m.cr=Chr(13)

    Create Cursor ycurs (ytext m)

    If ! File(m.yrep+"ytemp.frx")
      Messagebox("must create the report ytemp.frx before continue!",16+4096)
      Return .F.
      *Create Report ytemp   From  ycurs Width 1    && better create/use custom report
    Endi

    _Screen.Visible=.T.  &&for exe
    Modi Repo ytemp   &&iCan modify/customize somethings here- right click on repo (in designer) to modify left margin,page width,page hight,adjust field ytext,date,pageno....see specimen image below

    m.j=1
    m.x=""

    Set Memo To 8192  &&very important to have always same lines/page in report as set in m.max variable
    m.maxl=70  && lines per page

    For m.i=1 To m.n
      m.x=m.x+Chr(9)+yArray[i]+Chr(13)

      If  m.j>m.maxl
        Insert Into ycurs Values (cr+m.x)
        m.j=1
        m.x=""
      Else
        m.j=m.j+1
      Endi
    Endfor
    If !Empty(m.x)
      Insert Into ycurs Values (cr+m.x)   && add the last chunk
    Endi
    *brow
    Try  &&if user cancel locfile dialog ....to avoid returning error
      * Do Locfile("FoxyPreviewer.App")  &&dialog to pint to the app
      Sele ycurs
      Copy To mytable
      * build PDF
      If File(m.yrep+"ytemp.pdf")
        Erase (m.yrep+'ytemp.pdf')
      Endi
      Report Form  (m.yrep+'ytemp.frx')  Object Type 10 To File (m.yrep+"ytemp.Pdf")   Preview
    Catch

    Endtry

    _Screen.Visible=.F.
  Endproc

  Procedure text2.RightClick
    This.Value=_Cliptext
  Endproc

  Procedure command4.Click
    Local m.lcbook
    m.lcbook=Thisform.text2.Value
    If  Empty(m.lcbook)
      Return .F.
    Endi

    Local m.maxl,i,j,N,m.xtext,m.cr,m.x
    m.xtext=Filetostr(m.lcbook)
    N=Alines(yArray,m.xtext,4)
    m.cr=Chr(13)

    Create Cursor ycurs (ytext m)

    If ! File(m.yrep+"ytemp.frx")
      Messagebox("must create the report ytemp.frx before continue!",16+4096)
      Return .F.
      *Create Report ytemp   From  ycurs Width 1
    Endi

    _Screen.Visible=.T.  &&for exe
    Modi Repo ytemp   &&iCan modify/customize somethings here- right click on repo (in designer) to modify left margin,page width,page hight,adjust field ytext,date,pageno....see specimen image below

    m.j=1
    m.x=""

    Set Memo To 8192  &&very important to have always same lines/page as set.
    m.maxl=70  && lines per page

    For m.i=1 To m.n
      m.x=m.x+Chr(9)+yArray[i]+Chr(13)

      If  m.j>m.maxl
        Insert Into ycurs Values (cr+m.x)
        m.j=1
        m.x=""
      Else
        m.j=m.j+1
      Endi
    Endfor
    If !Empty(m.x)
      Insert Into ycurs Values (cr+m.x)   && add the last chunk
    Endi
    *brow

    Try  &&if user cancel locfile dialog ....to avoid returning error
      *Do Locfile("FoxyPreviewer.App")  &&dialog to pint to the app
      Sele ycurs
      Copy To mytable
      * build PDF
      If File(m.yrep+"ytemp.pdf")
        Erase  (m.yrep+"ytemp.pdf")
      Endi
      Report Form  (m.yrep+'ytemp.frx')  Object Type 10 To File (m.yrep+"ytemp.Pdf")   Preview
    Catch
    Endtry
    _Screen.Visible=.F.

    Return
  Endproc

  Procedure command5.Click
    Local m.myvar
    TEXT to m.myvar pretext 7 noshow
Foxypreviewer can translate any  txt file (even big one as a book) to pdf (save this code as ytxt2pdf.prg)
the text can be from any web page (html)converted to txt file or any local txt file.
the txt file is divided into pages and passed to  a memo  field ytext of a cursor playing the role of dataenvironment of the report.
when the report appears to modify, can customize margins,page width,page height,fonts,fields.....as your convenience and accordly to the number of lines/page.(can do that offline).the code ask to point to foxypreviewer location if its not already  loaded in memory (copy foxypreviewer.app in the source folder is better).
the report ytemp.frx (frx+frt) must be created manually before running this code.
the output is a pdf file opened with the default acrobat viewer.
the lines/page is important .can adjust and control after rendering report).
if ou compile an exe (ytxt2pdf.exe) make a project add this file and a config.fpw and put foxypreviewer.app in same folder (mark it as excluded).
this option is built automatically by the code *2* (ybuildexe.prg).
Note : the report ytemp.frx must be marked mandatory as excluded to prepare it to modify (otherwise its compiled and stays readonly).
can modify the report look (open it as a normal table and update any field) and in parallel the output PDF produced.
the structure of report is in the option (3).Use objtype and objcode to modify fonts,colors,...style.this is document in option 3 and 4 of the code.
note : you can put a top level form as permanent support of this app.here can run 1 option and exit...
The form is movable by mousedown.can press ESC to exit.can paste the clipboard to textboxes by rightclick on.
    ENDTEXT
    Local oshell
    oshell = Createobject('WScript.Shell')
    oshell.Popup(m.myvar,0, 'Summary help for ytxt2PDF', 0+32+4096)  &&4,16,48,64...
    oshell=Null
  Endproc

  Procedure command6.Click
    *open the report frx as a table .can  modify colors ,fontname,font styles   manually or programmatly....
    *here the report is modified programmatly uneditable for the demo (can modify out of thiss app).
    Close Data All

    If !File("mytable.dbf")
      Messagebox("execute first the txt2pdf0 or pdf1 to create table mytable",16+4096,"",2000)
      Return .F.
    Endi
    Messagebox("Can customize any thing in report opened as table  ytemp.frx.This is a demo!",0+32+4096,"",2000)
    _Screen.Visible=.T.

    Use  ytemp.frx  Shared
    Repl All penRed With 0,penGreen With 0
    Repl All penBlue With 0
    Repl All fillRed With -1,fillGreen With -1
    Repl All fillBlue With -1
    Repl All fontstyle With 0 For objtype=8 And objcode=0

    Repl All penRed With 255,penGreen With 140 , penBlue With 10        For  objtype=5  &&header (label)
    Repl All penRed With 0,penGreen With 0 , penBlue With 255           For  objtype=8 And objcode=0  &&fields detail+date+page
    Repl All penRed With 200,penGreen With 100 , penBlue With 120       For  uniqueID="_5310OBFCL"
    Repl All penRed With 255,penGreen With 255 , penBlue With 155       For  uniqueID="_5310OBFET"

    Repl fontstyle With 1   For objtype=8 And objcode=0
    Repl fillpat   With 8   For objtype=8 And objcode=0
    Repl fillRed With 218,fillGreen With 255 , fillBlue With 181     For objtype=8 And objcode=0

    Repl  fontstyle With 1 For objtype=7 And objcode=4
    Repl  penRed With 255,penGreen With 0 , penBlue With 0       For objtype=7 And objcode=4
    Repl fillRed With 213,fillGreen With 255, fillBlue With 255  For objtype=7 And objcode=4

    Repl fontstyle With 1  For  uniqueID="_5310OBFCL" Or  uniqueID="_5310OBFET"
    Repl fillRed With 255,fillGreen With 232, fillBlue With 153  For uniqueID="_5310OBFCL"
    Repl fillRed With 55,fillGreen With 32, fillBlue  With 153   For uniqueID="_5310OBFET"

    Brow  Title "report  ytemp.frx as table-not editable here (demo only)" Noedit
    Use In Select("ytemp.frx")


    Try  &&if user cancel locfile dialog ....to avoid returning error
     * Do Locfile("FoxyPreviewer.App")  &&dialog to pint to the app
      Use mytable
      * build PDF
      If File(m.yrep+"ytemp.pdf")
        Erase  (m.yrep+"ytemp.pdf")
      Endi
      Report Form  (m.yrep+'ytemp.frx')  Object Type 10 To File (m.yrep+"ytemp.Pdf")   Preview
    Catch
    Endtry

    Use In Select("mytable")
    _Screen.Visible=.F.
  Endproc

Enddefine
*
*-- EndDefine: ytxt2pdf

Procedure ydeclare
  Declare Integer ReleaseCapture In WIN32API
  Declare Integer SendMessage In WIN32API Integer, Integer, Integer, Integer
Endproc

*
Define Class ysystem As Container   &&minimize,maximize/restore,close buttons as fonts.
  Width = 65
  Height = 26
  BackStyle=0
  BorderWidth=0
  Name = "ysystem"

  Add Object label3 As Label With ;
    AutoSize = .T., ;
    FontBold = .T., ;
    FontName = "Marlett", ;
    FontSize = 12, ;
    BackStyle = 0, ;
    Caption = "0", ;
    Height = 21, ;
    Left = 0, ;
    MousePointer = 15, ;
    Top = 0, ;
    Width = 22, ;
    ForeColor = Rgb(255,0,0), ;
    Name = "Label3"

  Add Object label4 As Label With ;
    AutoSize = .T., ;
    FontBold = .T., ;
    FontName = "Marlett", ;
    FontSize = 12, ;
    BackStyle = 0, ;
    Caption = "r", ;
    Height = 21, ;
    Left = 43, ;
    MousePointer = 15, ;
    Top = 5, ;
    Width = 22, ;
    ForeColor = Rgb(255,0,0), ;
    Name = "Label4"

  Add Object label5 As Label With ;
    AutoSize = .T., ;
    FontBold = .T., ;
    FontName = "Marlett", ;
    FontSize = 12, ;
    BackStyle = 0, ;
    Caption = "1", ;
    Height = 21, ;
    Left = 22, ;
    MousePointer = 15, ;
    Top = 5, ;
    Width = 22, ;
    ForeColor = Rgb(255,0,0), ;
    Name = "Label5"

  Procedure label3.Click
    Thisform.WindowState=1
  Endproc

  Procedure label3.MouseLeave
    Lparameters nButton, nShift, nXCoord, nYCoord
    This.ForeColor=255
  Endproc

  Procedure label3.MouseEnter
    Lparameters nButton, nShift, nXCoord, nYCoord
    This.ForeColor=Rgb(0,255,0)
  Endproc

  Procedure label4.Click
    Thisform.Release
  Endproc

  Procedure label4.MouseLeave
    Lparameters nButton, nShift, nXCoord, nYCoord
    This.ForeColor=255
  Endproc

  Procedure label4.MouseEnter
    Lparameters nButton, nShift, nXCoord, nYCoord
    This.ForeColor=Rgb(0,255,0)
  Endproc

  Procedure label5.Init  &&disabled for this app
    This.Enabled=.F.
  Endproc

  Procedure label5.MouseEnter
    Lparameters nButton, nShift, nXCoord, nYCoord
    This.ForeColor=Rgb(0,255,0)
  Endproc

  Procedure label5.MouseLeave
    Lparameters nButton, nShift, nXCoord, nYCoord
    This.ForeColor=255
  Endproc

  Procedure label5.Click
    With Thisform
      .WindowState=Iif(.WindowState=0,2,0)

      If .WindowState=0
        This.Caption="1"
      Else
        This.Caption="2"
      Endi
    Endwith
  Endproc

Enddefine
*
*-- EndDefine: ysystem
*
DEFINE CLASS ybkg AS container
	Width = 84
	Height = 15
	backstyle=0
	borderwidth=0
	Name = "ybkg"

	ADD OBJECT shape1 AS shape WITH ;
		Top = 0, ;
		Left = 0, ;
		Height = 15, ;
		Width = 15, ;
		Curvature = 99, ;
		MousePointer = 15, ;
		BackColor = RGB(0,0,64), ;
		BorderColor = RGB(255,255,255), ;
		Name = "Shape1"

	ADD OBJECT shape2 AS shape WITH ;
		Top = 0, ;
		Left = 22, ;
		Height = 15, ;
		Width = 15, ;
		Curvature = 99, ;
		MousePointer = 15, ;
		BackColor = RGB(85,85,85), ;
		BorderColor = RGB(255,255,255), ;
		Name = "Shape2"

	ADD OBJECT shape3 AS shape WITH ;
		Top = 0, ;
		Left = 45, ;
		Height = 15, ;
		Width = 15, ;
		Curvature = 99, ;
		MousePointer = 15, ;
		BackColor = RGB(32,0,16), ;
		BorderColor = RGB(255,255,255), ;
		Name = "Shape3"

	ADD OBJECT shape4 AS shape WITH ;
		Top = 0, ;
		Left = 69, ;
		Height = 15, ;
		Width = 15, ;
		Curvature = 99, ;
		MousePointer = 15, ;
		BackColor = RGB(0,43,0), ;
		BorderColor = RGB(255,255,255), ;
		Name = "Shape4"


	PROCEDURE shape1.Click
		thisform.backcolor=this.backcolor
	ENDPROC

	PROCEDURE shape2.Click
		thisform.backcolor=this.backcolor
	ENDPROC

	PROCEDURE shape3.Click
		thisform.backcolor=this.backcolor
	ENDPROC

	PROCEDURE shape4.Click
		thisform.backcolor=this.backcolor
	ENDPROC

ENDDEFINE
*
*-- EndDefine: ybkg


Click on code to select [then copy] -click outside to deselect


*4* created on sunday 17 of december 2017
*save this prg as ybuildexe.prg
*it builds programmatly a proj from (ytxt2pdf_form.prg as above and add a config.fpw) an compile+clean
*it builds an executable app and cleans all tools used to achieve this goal.
*the executable built is ytxt2pdf.exe (can create a desktop shortcut to run it or pin it on taskbar....)
*remember the report (frx+frt) ytem.frx must bein same folder as sources and foxypreviewer.app also(better to avoid locate dialog....)

Set Safe Off
Local m.yrep
m.yrep=Addbs(Justpath(Sys(16,1)))
Set Defa To (yrep)

*build file configuration config.fpw
Local m.myvar
TEXT to m.myvar noshow
screen=off
resource=off
safe=off
ENDTEXT
Strtofile(m.myvar, "config.fpw")

*build proj and compile to exe
Build Project yfoo  From  "ytxt2pdf_form.prg" ,"config.fpw"
Build Exe ytxt2pdf.Exe From yfoo
Inkey(1)

*clean traces
Dele File yfoo*.*
If File(m.yrep+"ytxt2pdf.exe",1)
  Messagebox("ytxt2pdf.exe created!",0+32+4096,"Create an exe",1000)
Endi

Try
  Dele File config.fpw
Catch
Endtry
Set Safe On

local m.o
m.o=m.yrep+"ytxt2pdf.exe"
Run/N &o


see the class ysystem (minimize,maximlize/restore/close to add to any form.(made with Marlett font)
see the class ysystem (minimize,maximlize/restore/close to add to any form.(made with Marlett font)
see the class ysystem (minimize,maximlize/restore/close to add to any form.(made with Marlett font)

see the class ysystem (minimize,maximlize/restore/close to add to any form.(made with Marlett font)

Click on code to select [then copy] -click outside to deselect


*5* light utility to convert any html page to txt
*yHtml2Txt.prg
create cursor ycurs (texte m)

local m.lcurl
m.lcUrl=inputbox("Any web valid url","","http://yousfi.over-blog.com/2017/12/ytxt2pdf-convert-any-plain-texte-even-web-html-to-pdf.html")

Local loRequest,m.xtext
m.loRequest = Createobject('MsXml2.XmlHttp')
m.loRequest.Open("GET",m.lcUrl,.F.)
m.loRequest.Send()
m.xtext=m.loRequest.ResponseText
m.loRequest=Null
insert into ycurs values (m.xtext)
brow   title m.lcurl

*export to  txt file
*local m.lcdest
*m.lcdest=addbs(sys(2023))+"ytemp.txt"
*strtofile(m.xtext,m.lcdest)
*run/n notepad &lcdest

*note : can also use internetexplorer.application , navigate to the url and return the body.innertext



                     

Yousfi Benameur


Important:All Codes above are tested on VFP9SP2 & windows 10 pro 64 bits version 1709(fall creator) & IE11 emulation.

To be informed of the latest articles, subscribe:
Comment on this post