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 + + + + + + + +