diff --git a/.gitignore b/.gitignore
index 4b20705d3..3f95ade70 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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
diff --git a/src/Tools/offlinedoc/buildpdf.py b/src/Tools/offlinedoc/buildpdf.py
index cc0438b9e..815483453 100755
--- a/src/Tools/offlinedoc/buildpdf.py
+++ b/src/Tools/offlinedoc/buildpdf.py
@@ -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("
",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()
diff --git a/src/Tools/offlinedoc/buildwikiindex.py b/src/Tools/offlinedoc/buildwikiindex.py
index e32878820..620d032ea 100755
--- a/src/Tools/offlinedoc/buildwikiindex.py
+++ b/src/Tools/offlinedoc/buildwikiindex.py
@@ -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:
diff --git a/src/Tools/offlinedoc/toc.txt b/src/Tools/offlinedoc/toc.txt
new file mode 100644
index 000000000..ee6b8f9ec
--- /dev/null
+++ b/src/Tools/offlinedoc/toc.txt
@@ -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
+
+
+
+
+
+
+
+