Better PDF generation script
This commit is contained in:
parent
f87fbe7e2a
commit
d67d9603c2
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -27,3 +27,6 @@ install_manifest.txt
|
|||
/Mod/
|
||||
/ZERO_CHECK.dir/
|
||||
/build/
|
||||
/src/Tools/offlinedoc/localwiki/
|
||||
/src/Tools/offlinedoc/todolist.txt
|
||||
/src/Tools/offlinedoc/wikifiles.txt
|
||||
|
|
|
@ -41,6 +41,7 @@ VERBOSE = True # set true to get output messages
|
|||
INCLUDECOMMANDS = True # if true, the command pages of each workbench are included after each WB page
|
||||
OVERWRITE = False # if true, pdf files are recreated even if already existing
|
||||
FIREFOXPDFFOLDER = os.path.expanduser("~")+os.sep+"PDF" # if firefox is used, set this to where it places its pdf files by default
|
||||
COVER = "http://www.freecadweb.org/wiki/images/7/79/Freecad-pdf-cover.svg"
|
||||
|
||||
# END CONFIGURATION ##############################################
|
||||
|
||||
|
@ -50,7 +51,7 @@ FOLDER = "./localwiki"
|
|||
fcount = dcount = 0
|
||||
|
||||
def crawl():
|
||||
"downloads an entire wiki site"
|
||||
"creates a pdf file from the localwiki folder"
|
||||
|
||||
# tests ###############################################
|
||||
|
||||
|
@ -65,9 +66,9 @@ def crawl():
|
|||
print "Error: Htmldoc not found, exiting."
|
||||
return 1
|
||||
try:
|
||||
from pyPdf import PdfFileReader,PdfFileWriter
|
||||
from PyPDF2 import PdfFileReader,PdfFileWriter
|
||||
except:
|
||||
print "Error: Python-pypdf not installed, exiting."
|
||||
print "Error: Python-pypdf2 not installed, exiting."
|
||||
|
||||
# run ########################################################
|
||||
|
||||
|
@ -77,6 +78,7 @@ def crawl():
|
|||
if VERBOSE: print "All done!"
|
||||
return 0
|
||||
|
||||
|
||||
def buildpdffiles():
|
||||
"scans a folder for html files and converts them all to pdf"
|
||||
templist = os.listdir(FOLDER)
|
||||
|
@ -101,6 +103,7 @@ def buildpdffiles():
|
|||
createpdf_htmldoc(f[:-5])
|
||||
i += 1
|
||||
|
||||
|
||||
def fetch_resources(uri, rel):
|
||||
"""
|
||||
Callback to allow pisa/reportlab to retrieve Images,Stylesheets, etc.
|
||||
|
@ -116,8 +119,8 @@ def createpdf_pisa(pagename):
|
|||
"creates a pdf file from a saved page using pisa (python module)"
|
||||
import ho.pisa as pisa
|
||||
if (not exists(pagename+".pdf",image=True)) or OVERWRTIE:
|
||||
infile = file(FOLDER + os.sep + pagename+'.html','ro')
|
||||
outfile = file(FOLDER + os.sep + pagename+'.pdf','wb')
|
||||
infile = open(FOLDER + os.sep + pagename+'.html','ro')
|
||||
outfile = open(FOLDER + os.sep + pagename+'.pdf','wb')
|
||||
if VERBOSE: print "Converting " + pagename + " to pdf..."
|
||||
pdf = pisa.CreatePDF(infile,outfile,FOLDER,link_callback=fetch_resources)
|
||||
outfile.close()
|
||||
|
@ -125,6 +128,7 @@ def createpdf_pisa(pagename):
|
|||
return pdf.err
|
||||
return 0
|
||||
|
||||
|
||||
def createpdf_firefox(pagename):
|
||||
"creates a pdf file from a saved page using firefox (needs command line printing extension)"
|
||||
# the default printer will be used, so make sure it is set to pdf
|
||||
|
@ -139,6 +143,7 @@ def createpdf_firefox(pagename):
|
|||
else:
|
||||
print "-----------------------------------------> Couldn't find print output!"
|
||||
|
||||
|
||||
def createpdf_htmldoc(pagename):
|
||||
"creates a pdf file from a saved page using htmldoc (external app, but supports images)"
|
||||
if (not exists(pagename+".pdf",image=True)) or OVERWRITE:
|
||||
|
@ -146,6 +151,7 @@ def createpdf_htmldoc(pagename):
|
|||
outfile = FOLDER + os.sep + pagename+'.pdf'
|
||||
return os.system('htmldoc --webpage --textfont sans --browserwidth 840 -f '+outfile+' '+infile)
|
||||
|
||||
|
||||
def createpdf_wkhtmltopdf(pagename):
|
||||
"creates a pdf file from a saved page using htmldoc (external app, but supports images)"
|
||||
if (not exists(pagename+".pdf",image=True)) or OVERWRITE:
|
||||
|
@ -155,55 +161,59 @@ def createpdf_wkhtmltopdf(pagename):
|
|||
else:
|
||||
print "skipping"
|
||||
|
||||
|
||||
def joinpdf():
|
||||
"creates one pdf file from several others, following order from startpage"
|
||||
from pyPdf import PdfFileReader,PdfFileWriter
|
||||
"creates one pdf file from several others, following order from the cover"
|
||||
from PyPDF2 import PdfFileReader,PdfFileWriter
|
||||
if VERBOSE: print "Building table of contents..."
|
||||
f = open(FOLDER+os.sep+INDEX+'.html')
|
||||
html = ''
|
||||
for line in f: html += line
|
||||
f.close()
|
||||
html = html.replace("\n"," ")
|
||||
html = html.replace("> <","><")
|
||||
html = re.findall("<ul.*/ul>",html)[0]
|
||||
pages = re.findall('href="(.*?)"',html)
|
||||
pages.insert(1,INDEX+".html")
|
||||
|
||||
result = PdfFileWriter()
|
||||
for p in pages:
|
||||
if exists(p[:-5]):
|
||||
if VERBOSE: print 'Appending',p[:-5]+'.pdf'
|
||||
try:
|
||||
inputfile = PdfFileReader(file(FOLDER+os.sep+p[:-5]+'.pdf','rb'))
|
||||
except:
|
||||
print 'Unable to append',p
|
||||
else:
|
||||
for i in range(inputfile.getNumPages()):
|
||||
createCover()
|
||||
inputfile = PdfFileReader(open(FOLDER+os.sep+'Cover.pdf','rb'))
|
||||
result.addPage(inputfile.getPage(0))
|
||||
count = 1
|
||||
|
||||
tocfile = open("toc.txt")
|
||||
parent = False
|
||||
for page in tocfile:
|
||||
page = page.strip()
|
||||
if page:
|
||||
if page[0] == "#":
|
||||
continue
|
||||
if page == "begin":
|
||||
parent = True
|
||||
continue
|
||||
if page == "end":
|
||||
parent = False
|
||||
continue
|
||||
if VERBOSE: print 'Appending',page, "at position",count
|
||||
title = page.replace("_"," ")
|
||||
pdffile = page + ".pdf"
|
||||
if exists(pdffile,True):
|
||||
inputfile = PdfFileReader(open(FOLDER + os.sep + pdffile,'rb'))
|
||||
numpages = inputfile.getNumPages()
|
||||
for i in range(numpages):
|
||||
result.addPage(inputfile.getPage(i))
|
||||
if INCLUDECOMMANDS:
|
||||
if ("_Workbench.html" in p) or ("_Module.html" in p):
|
||||
mod = [p.split("_")[0]]
|
||||
if mod[0] == "PartDesign":
|
||||
mod.append("Constraint")
|
||||
for m in mod:
|
||||
for f in fileslist:
|
||||
if f[:len(m)+1] == m+"_":
|
||||
if (not("Module" in f)) and (not("Workbench" in f)) and (not("Scripting" in f)) and (not("API" in f)):
|
||||
if VERBOSE: print ' Appending',f[:-5]+'.pdf'
|
||||
try:
|
||||
inputfile = PdfFileReader(file(FOLDER+os.sep+f[:-5]+'.pdf','rb'))
|
||||
except:
|
||||
print 'Unable to append',f
|
||||
else:
|
||||
for i in range(inputfile.getNumPages()):
|
||||
result.addPage(inputfile.getPage(i))
|
||||
if parent == True:
|
||||
parent = result.addBookmark(title,count)
|
||||
elif parent == False:
|
||||
result.addBookmark(title,count)
|
||||
else:
|
||||
result.addBookmark(title,count,parent)
|
||||
count += numpages
|
||||
else:
|
||||
print "page",pdffile,"not found, aborting."
|
||||
sys.exit()
|
||||
|
||||
if VERBOSE: print "Writing..."
|
||||
outputfile = file(FOLDER+os.sep+"freecad.pdf",'wb')
|
||||
outputfile = open(FOLDER+os.sep+"freecad.pdf",'wb')
|
||||
result.write(outputfile)
|
||||
outputfile.close()
|
||||
if VERBOSE:
|
||||
print ' '
|
||||
print 'Successfully created '+FOLDER+os.sep+'freecad.pdf'
|
||||
|
||||
|
||||
def local(page,image=False):
|
||||
"returns a local path for a given page/image"
|
||||
if image:
|
||||
|
@ -211,22 +221,41 @@ def local(page,image=False):
|
|||
else:
|
||||
return FOLDER + os.sep + page + '.html'
|
||||
|
||||
|
||||
def exists(page,image=False):
|
||||
"checks if given page/image already exists"
|
||||
path = local(page,image)
|
||||
if os.path.exists(path): return True
|
||||
return False
|
||||
|
||||
|
||||
def makeStyleSheet():
|
||||
"Creates a stylesheet for wkhtmltopdf"
|
||||
outputfile = file(FOLDER+os.sep+"wkhtmltopdf.css",'wb')
|
||||
outputfile = open(FOLDER+os.sep+"wkhtmltopdf.css",'wb')
|
||||
outputfile.write("""
|
||||
html {
|
||||
margin: 50px 0;
|
||||
margin: 50px 0 0 50px !important;
|
||||
}
|
||||
a:link, a:visited {
|
||||
color: #000 !important;
|
||||
}
|
||||
.printfooter {
|
||||
display:none !important;
|
||||
}
|
||||
""")
|
||||
outputfile.close()
|
||||
|
||||
|
||||
|
||||
def createCover():
|
||||
"downloads and creates a cover page"
|
||||
if VERBOSE: print "fetching " + COVER
|
||||
data = (urlopen(COVER).read())
|
||||
path = FOLDER + os.sep + "Cover.svg"
|
||||
fil = open(path,'wb')
|
||||
fil.write(data)
|
||||
fil.close()
|
||||
os.system('inkscape --export-pdf='+FOLDER+os.sep+'Cover.pdf'+' '+FOLDER+os.sep+'Cover.svg')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
crawl()
|
||||
|
||||
crawl()
|
||||
|
|
|
@ -53,8 +53,6 @@ def crawl(pagename):
|
|||
todolist = []
|
||||
processed = []
|
||||
count = 1
|
||||
if pagename:
|
||||
INDEX = pagename[0]
|
||||
if os.path.exists("wikifiles.txt"):
|
||||
f = open("wikifiles.txt","r")
|
||||
if VERBOSE: print "Reading existing list..."
|
||||
|
@ -71,8 +69,11 @@ def crawl(pagename):
|
|||
todolist.append(l.strip())
|
||||
f.close()
|
||||
else:
|
||||
indexpages,imgs = get(INDEX)
|
||||
todolist.extend(indexpages)
|
||||
if pagename:
|
||||
todolist = pagename
|
||||
else:
|
||||
indexpages,imgs = get(INDEX)
|
||||
todolist.extend(indexpages)
|
||||
while todolist:
|
||||
targetpage = todolist.pop()
|
||||
if not targetpage in NORETRIEVE:
|
||||
|
|
304
src/Tools/offlinedoc/toc.txt
Normal file
304
src/Tools/offlinedoc/toc.txt
Normal file
|
@ -0,0 +1,304 @@
|
|||
# order of pages for the PDF version.
|
||||
# pagenames preceded with # are incomplete and not included.
|
||||
# each line indicates a pagename, or the word "begin" if the given
|
||||
# page is the main page of a section, or "end" if the next pages don't
|
||||
# below to any section.
|
||||
|
||||
Online_Help_Startpage
|
||||
About_FreeCAD
|
||||
Getting_started
|
||||
Workbenches
|
||||
|
||||
begin
|
||||
|
||||
Part_Workbench
|
||||
Part_Box
|
||||
Part_Cone
|
||||
Part_Cylinder
|
||||
Part_Sphere
|
||||
Part_Torus
|
||||
Part_CreatePrimitives
|
||||
Part_Plane
|
||||
Part_Prism
|
||||
Part_Wedge
|
||||
Part_Helix
|
||||
Part_Spiral
|
||||
Part_Circle
|
||||
Part_Ellipse
|
||||
Part_Line
|
||||
Part_Point
|
||||
Part_RegularPolygon
|
||||
Part_Booleans
|
||||
# Part_Common
|
||||
# Part_Cut
|
||||
Part_Fuse
|
||||
# Part_Shapebuilder
|
||||
Part_Extrude
|
||||
Part_Fillet
|
||||
Part_Revolve
|
||||
Part_SectionCross
|
||||
Part_Chamfer
|
||||
Part_Mirror
|
||||
Part_RuledSurface
|
||||
Part_Sweep
|
||||
Part_Loft
|
||||
Part_Offset
|
||||
Part_Thickness
|
||||
Part_RefineShape
|
||||
Part_CheckGeometry
|
||||
|
||||
begin
|
||||
|
||||
PartDesign_Workbench
|
||||
PartDesign_Pad
|
||||
PartDesign_Pocket
|
||||
PartDesign_Revolution
|
||||
PartDesign_Groove
|
||||
|
||||
Sketcher_Point
|
||||
Sketcher_Line
|
||||
Sketcher_Arc
|
||||
Sketcher_Circle
|
||||
Sketcher_Ellipse
|
||||
Sketcher_Arc_of_Ellipse
|
||||
Sketcher_Polyline
|
||||
Sketcher_Rectangle
|
||||
Sketcher_Triangle
|
||||
Sketcher_Square
|
||||
Sketcher_Pentagon
|
||||
Sketcher_Hexagon
|
||||
Sketcher_Heptagon
|
||||
Sketcher_Octagon
|
||||
Sketcher_Slot
|
||||
Sketcher_Fillet
|
||||
Sketcher_Trimming
|
||||
# Sketcher_Arch3Point
|
||||
# Sketcher_Circle3Point
|
||||
# Sketcher_ConicSections
|
||||
# Sketcher_Ellipse_by_3_Points
|
||||
|
||||
Constraint_PointOnPoint
|
||||
Constraint_Vertical
|
||||
Constraint_Horizontal
|
||||
Constraint_Parallel
|
||||
Constraint_Perpendicular
|
||||
Constraint_Tangent
|
||||
Constraint_EqualLength
|
||||
Constraint_Symmetric
|
||||
Constraint_Lock
|
||||
Constraint_HorizontalDistance
|
||||
Constraint_VerticalDistance
|
||||
Constraint_Length
|
||||
Constraint_Radius
|
||||
Constraint_InternalAngle
|
||||
Constraint_SnellsLaw
|
||||
Constraint_Internal_Alignment
|
||||
# Constraint_PointOnObject
|
||||
|
||||
Sketcher_MapSketch
|
||||
Sketcher_Reorient
|
||||
Sketcher_Validate
|
||||
Sketcher_Show_Hide_Internal_Geometry
|
||||
# Sketcher_MergeSketch
|
||||
# Sketcher_CloseShape
|
||||
# Sketcher_ConnectLines
|
||||
# Sketcher_SelectConstraints
|
||||
# Sketcher_SelectOrigin
|
||||
# Sketcher_SelectVerticalAxis
|
||||
# Sketcher_SelectHorizontalAxis
|
||||
# Sketcher_SelectRedundantConstraints
|
||||
# Sketcher_SelectConflictingConstraints
|
||||
# Sketcher_SelectElementsAssociatedWithConstraints
|
||||
|
||||
PartDesign_Fillet
|
||||
PartDesign_Chamfer
|
||||
PartDesign_Draft
|
||||
PartDesign_Mirrored
|
||||
PartDesign_LinearPattern
|
||||
PartDesign_PolarPattern
|
||||
PartDesign_Scaled
|
||||
PartDesign_MultiTransform
|
||||
PartDesign_WizardShaft
|
||||
PartDesign_InvoluteGear
|
||||
|
||||
Sketcher_Tutorial
|
||||
|
||||
begin
|
||||
|
||||
Draft_Workbench
|
||||
Draft_Line
|
||||
Draft_Wire
|
||||
Draft_Circle
|
||||
Draft_Arc
|
||||
Draft_Ellipse
|
||||
Draft_Polygon
|
||||
Draft_Rectangle
|
||||
Draft_Text
|
||||
Draft_Dimension
|
||||
Draft_BSpline
|
||||
Draft_Point
|
||||
Draft_ShapeString
|
||||
Draft_Facebinder
|
||||
Draft_BezCurve
|
||||
Draft_Move
|
||||
Draft_Rotate
|
||||
Draft_Offset
|
||||
Draft_Trimex
|
||||
Draft_Upgrade
|
||||
Draft_Downgrade
|
||||
Draft_Scale
|
||||
Draft_Edit
|
||||
Draft_WireToBSpline
|
||||
Draft_AddPoint
|
||||
Draft_DelPoint
|
||||
Draft_Shape2DView
|
||||
Draft_Draft2Sketch
|
||||
Draft_Array
|
||||
Draft_Clone
|
||||
Draft_SelectPlane
|
||||
Draft_VisGroup
|
||||
|
||||
begin
|
||||
|
||||
Arch_Workbench
|
||||
Arch_Wall
|
||||
Arch_Structure
|
||||
Arch_Rebar
|
||||
Arch_Floor
|
||||
Arch_Building
|
||||
Arch_Site
|
||||
Arch_Window
|
||||
Arch_SectionPlane
|
||||
Arch_Axis
|
||||
Arch_Roof
|
||||
Arch_Space
|
||||
Arch_Stairs
|
||||
Arch_Panel
|
||||
Arch_Frame
|
||||
Arch_Equipment
|
||||
Arch_CutPlane
|
||||
Arch_Add
|
||||
Arch_Remove
|
||||
Arch_Survey
|
||||
Arch_tutorial
|
||||
|
||||
begin
|
||||
|
||||
Drawing_Workbench
|
||||
Drawing_Landscape_A3
|
||||
Drawing_View
|
||||
Drawing_Annotation
|
||||
Drawing_Clip
|
||||
Drawing_Openbrowser
|
||||
Drawing_Symbol
|
||||
Drawing_DraftView
|
||||
Drawing_Save
|
||||
Drawing_ProjectShape
|
||||
# Drawing_Othoviews
|
||||
|
||||
begin
|
||||
|
||||
Raytracing_Workbench
|
||||
# Raytracing_New
|
||||
# Raytracing_Lux
|
||||
# Raytracing_Part
|
||||
# Raytracing_ResetCamera
|
||||
# Raytracing_Export
|
||||
# Raytracing_Render
|
||||
|
||||
begin
|
||||
|
||||
Robot_Workbench
|
||||
# Robot_createRobot
|
||||
# Robot_Simulate
|
||||
# Robot_Export
|
||||
# Robot_SetHomePos
|
||||
# Robot_RestoreHomePos
|
||||
# Robot_CreateTrajectory
|
||||
# Robot_SetDefaultOrientation
|
||||
# Robot_InsertWaypoint
|
||||
# Robot_InsertWaypointPre
|
||||
# Robot_Edge2Trac
|
||||
# Robot_TrajectoryDressUp
|
||||
# Robot_TrajectoryCompound
|
||||
|
||||
begin
|
||||
|
||||
OpenSCAD_Workbench
|
||||
OpenSCAD_AddOpenSCADElement
|
||||
# OpenSCAD_ColorCodeShape
|
||||
# OpenSCAD_ReplaceObject
|
||||
# OpenSCAD_RemoveSubtree
|
||||
# OpenSCAD_RefineShapeFeature
|
||||
# OpenSCAD_IncreaseTolerance
|
||||
# OpenSCAD_Edgestofaces
|
||||
# OpenSCAD_ExpandPlacements
|
||||
# OpenSCAD_ExplodeGroup
|
||||
# OpenSCAD_MeshBoolean
|
||||
# OpenSCAD_Hull
|
||||
# OpenSCAD_Minkowski
|
||||
|
||||
begin
|
||||
|
||||
Fem_Workbench
|
||||
FEM_Analysis
|
||||
# FEM_Create
|
||||
# FEM_Material
|
||||
# FEM_Calculation
|
||||
# FEM_DefineNodes
|
||||
# FEM_FixedConstraint
|
||||
# FEM_ForceConstraint
|
||||
# FEM_BearingConstraint
|
||||
# FEM_GearConstraint
|
||||
# FEM_PulleyConstraint
|
||||
# FEM_ShowResult
|
||||
|
||||
begin
|
||||
|
||||
Plot_Module
|
||||
Plot_Save
|
||||
Plot_Basic_tutorial
|
||||
Plot_MultiAxes_tutorial
|
||||
# Plot_Axes
|
||||
# Plot_Series
|
||||
# Plot_Grid
|
||||
# Plot_Legend
|
||||
# Plot_Labels
|
||||
# Plot_Positions
|
||||
|
||||
begin
|
||||
|
||||
Mesh_Workbench
|
||||
|
||||
end
|
||||
|
||||
Macros
|
||||
Introduction_to_Python
|
||||
Python_scripting_tutorial
|
||||
Topological_data_scripting
|
||||
Mesh_Scripting
|
||||
Mesh_to_Part
|
||||
Scenegraph
|
||||
Pivy
|
||||
|
||||
begin
|
||||
|
||||
PySide
|
||||
PySide_Beginner_Examples
|
||||
PySide_Medium_Examples
|
||||
PySide_Advanced_Examples
|
||||
|
||||
end
|
||||
|
||||
Scripted_objects
|
||||
Embedding_FreeCAD
|
||||
Embedding_FreeCADGui
|
||||
Code_snippets
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user