Tools: Updated offline doc scripts

This commit is contained in:
Yorik van Havre
2021-02-22 14:07:33 +01:00
parent d761c9d2c0
commit 442b1a5db5
4 changed files with 73 additions and 305 deletions

View File

@@ -30,6 +30,8 @@ __url__ = "http://www.freecadweb.org"
This script builds a pdf file from a local copy of the wiki
"""
Workbenches=["Part","PartDesign","Sketcher","Constraints","Draft","Path","Fem","Arch","TechDraw","Raytracing","OpenSCAD","Robot","Mesh"]
TOC="""Online_Help_Startpage
About_FreeCAD
Feature_list
@@ -41,269 +43,7 @@ Property_editor
Import_Export
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_Arc3Point
# 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_Solver
# 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
WorkbenchesList
Interface_Customization
Preferences_Editor
@@ -476,7 +216,7 @@ def joinpdf():
result.addPage(inputfile.getPage(0))
count = 1
tocfile = TOC.split("\n")
tocfile = createTOC()
parent = False
for page in tocfile:
page = page.strip()
@@ -517,6 +257,31 @@ def joinpdf():
print('Successfully created '+FOLDER+os.sep+'freecad.pdf')
def createTOC():
"populates the TOC"
tocfile = TOC.split("\n")
files = [f for f in os.listdir(FOLDER) if f.endswith(".pdf")]
wbpages = []
for wb in Workbenches:
wbpage += "begin"
if wb+"_Workbench" in files:
wbpages.append(wb+"_Workbench")
for f in files:
if f.lower().startswith(wb.lower()+"_"):
if (not f.lower().endswith("_workbench")) and (not f.lower().endswith("tutorial")):
wb.append(f)
if wb+"_tutorial" in files:
wbpages.append(wb+"_tutorial")
wbpages.append("end")
toc = []
for i in tocfile:
if i == "WorkbenchesList":
toc.extend(wbpages)
else:
toc.append(i)
return toc
def local(page,image=False):
"returns a local path for a given page/image"
if image:

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
#***************************************************************************
#* *
@@ -31,7 +31,7 @@ This script builds qhrlp files from a local copy of the wiki
"""
import sys, os, re, tempfile, getopt, shutil
from urllib2 import urlopen, HTTPError
from urllib.request import urlopen, HTTPError
# CONFIGURATION #################################################
@@ -39,8 +39,7 @@ FOLDER = "./localwiki"
INDEX = "Online_Help_Toc" # the start page from where to crawl the wiki
VERBOSE = True # to display what's going on. Otherwise, runs totally silent.
QHELPCOMPILER = 'qhelpgenerator'
QCOLLECTIOMGENERATOR = 'qcollectiongenerator'
RELEASE = '0.18'
RELEASE = '0.19'
# END CONFIGURATION ##############################################
@@ -54,25 +53,25 @@ def crawl():
if os.system(QHELPCOMPILER +' -v'):
print ("Error: QAssistant not fully installed, exiting.")
return 1
if os.system(QCOLLECTIOMGENERATOR +' -v'):
print ("Error: QAssistant not fully installed, exiting.")
return 1
# run ########################################################
qhp = buildtoc()
qhcp = createCollProjectFile()
shutil.copy("../../Gui/Icons/freecad-icon-64.png","localwiki/freecad-icon-64.png")
if generate(qhcp) or compile(qhp):
print ("Error at compiling")
if generate(qhcp):
print ("Error while generating")
return 1
if compile(qhp):
print ("Error while compiling")
return 1
if VERBOSE: print ("All done!")
i=raw_input("Copy the files to their correct location in the source tree? y/n (default=no) ")
if i.upper() in ["Y","YES"]:
shutil.copy("localwiki/freecad.qch","../../Doc/freecad.qch")
shutil.copy("localwiki/freecad.qhc","../../Doc/freecad.qhc")
else:
print ('Files are in localwiki. Test with "assistant -collectionFile localwiki/freecad.qhc"')
#i=raw_input("Copy the files to their correct location in the source tree? y/n (default=no) ")
#if i.upper() in ["Y","YES"]:
# shutil.copy("localwiki/freecad.qch","../../Doc/freecad.qch")
# shutil.copy("localwiki/freecad.qhc","../../Doc/freecad.qhc")
#else:
print ('Files freecad.qch and freecad.qhc are in localwiki. Test with "assistant -collectionFile localwiki/freecad.qhc"')
return 0
def compile(qhpfile):
@@ -81,6 +80,7 @@ def compile(qhpfile):
if not os.system(QHELPCOMPILER + ' '+qhpfile+' -o '+qchfile):
if VERBOSE: print ("Successfully created",qchfile)
return 0
return 1
def generate(qhcpfile):
"generates qassistant-specific settings like icon, title, ..."
@@ -92,9 +92,10 @@ def generate(qhcpfile):
about.write(txt)
about.close()
qhcfile = FOLDER + os.sep + "freecad.qhc"
if not os.system(QCOLLECTIOMGENERATOR+' '+qhcpfile+' -o '+qhcfile):
if not os.system(QHELPCOMPILER+' '+qhcpfile+' -o '+qhcfile):
if VERBOSE: print ("Successfully created ",qhcfile)
return 0
return 1
def createCollProjectFile():
qprojectfile = '''<?xml version="1.0" encoding="UTF-8"?>
@@ -109,9 +110,6 @@ def createCollProjectFile():
</aboutMenuText>
<aboutDialog>
<file>about.txt</file>
<!--
<icon>images/icon.png</icon>
-->
<icon>freecad-icon-64.png</icon>
</aboutDialog>
<enableDocumentationManager>true</enableDocumentationManager>
@@ -136,7 +134,7 @@ def createCollProjectFile():
f = open(qfilename,'w')
f.write(qprojectfile)
f.close()
if VERBOSE: print ("Done writing qhcp file",qfilename)
if VERBOSE: print ("Done writing qhcp file:",qfilename)
return qfilename
def buildtoc():
@@ -180,6 +178,9 @@ def buildtoc():
title = re.findall('<a[^>]*>(.*?)</a>',line)[0].strip()
link = re.findall('href="(.*?)"',line)[0].strip()
if not link: link = 'default.html'
if title.startswith("<img"):
title=None
link=None
return title,link
if VERBOSE: print ("Building table of contents...")
@@ -196,14 +197,15 @@ def buildtoc():
for item in items:
if not ("<ul>" in item):
if ("</ul>" in item):
inserttoc += '</section>\n'
inserttoc += ' </section>\n'
else:
link = ''
title,link=getname(item)
if link:
link='" ref="'+link
insertkeywords += ('<keyword name="'+title+link+'"/>\n')
inserttoc += ('<section title="'+title+link+'"></section>\n')
if link and title:
inserttoc += (' <section title="'+title+link+'"></section>\n')
else:
subitems = item.split("<ul>")
for i in range(len(subitems)):
@@ -214,7 +216,8 @@ def buildtoc():
insertkeywords += ('<keyword name="'+title+link+'"/>\n')
trail = ''
if i == len(subitems)-1: trail = '</section>'
inserttoc += ('<section title="'+title+link+'">'+trail+'\n')
if link and title:
inserttoc += (' <section title="'+title+link+'">'+trail+'\n')
inserttoc += '</section>\n'
insertfiles = "<files>\n"
@@ -226,10 +229,10 @@ def buildtoc():
qhelpfile = re.compile('<inserttoc>').sub(inserttoc,qhelpfile)
qhelpfile = re.compile('<insertfiles>').sub(insertfiles,qhelpfile)
qfilename = FOLDER + os.sep + "freecad.qhp"
f = open(qfilename,'wb')
f = open(qfilename,'w')
f.write(qhelpfile)
f.close()
if VERBOSE: print ("Done writing qhp file",qfilename)
if VERBOSE: print ("Done writing qhp file:",qfilename)
return qfilename
if __name__ == "__main__":

View File

@@ -50,7 +50,11 @@ NORETRIEVE += ['Constraint_Concentric','Constraint_EqualLength','Constraint_Exte
'Constraint_PointOnObject','Constraint_PointOnPoint','Constraint_PointOnStart',
'Constraint_PointToObject','Constraint_Radius','Constraint_SnellsLaw',
'Constraint_Symmetric','Constraint_Tangent','Constraint_TangentToEnd',
'Constraint_TangentToStart','Constraint_Vertical'] # pages that have been renamed but still dangle around...
'Constraint_TangentToStart','Constraint_Vertical',
'Join_Cutout','Join_Embed','Part_BooleanFragment','Part_Sections','Curves_HelicalSweep',
'CurvedShapes_FlyingWingS800','CurvedShapes_HortenHIX','CurvedShapes_SurfaceCut',
'CurvedShapes_InterpolatedMiddle','CurvedShapes_CurvedSegment','Arch_Cell',
'Std_ClippingPlane','Std_AboutQt'] # pages that have been renamed but still dangle around...
GETTRANSLATIONS = False # Set true if you want to get the translations too.
MAXFAIL = 3 # max number of retries if download fails
VERBOSE = True # to display what's going on. Otherwise, runs totally silent.

View File

@@ -60,15 +60,13 @@ FOLDER = "./localwiki"
LISTFILE = "wikifiles.txt"
URL = DEFAULTURL
wikiindex = "/wiki/index.php?title="
imageprefix = "/wiki/"
defaultfile = "<html><head><link type='text/css' href='wiki.css' rel='stylesheet'></head><body>&nbsp;</body></html>"
css = """/* Basic CSS for offline wiki rendering */
body {
font-family: Fira Sans,Arial,Helvetica,sans-serif;
font-size: 14px;
text-align: justify;
/*background: #fff;
color: #000;*/
max-width: 800px;
}
@@ -99,7 +97,6 @@ li {
pre, .mw-code {
text-align: left;
/*background: #eee;*/
padding: 5px 5px 5px 20px;
font-family: mono;
border-radius: 2px;
@@ -131,7 +128,6 @@ a:hover {
text-align: left;
width: 190px;
float: right;
/*background: #eee;*/
margin-top: 10px;
border-radius: 2px;
}
@@ -140,7 +136,7 @@ a:hover {
margin-left: 15px;
padding: 10px;
}
#mw-navigation {
#mw-navigation, .mw-jump-link, .docnav, .NavFrame {
display:none; /*TODO remove on next build (included below)*/
}
"""
@@ -168,7 +164,7 @@ def crawl():
indexpages = get(INDEX)
while todolist:
targetpage = todolist.pop()
if VERBOSE: print (count, ": Fetching ", targetpage)
if VERBOSE: print (count,(3-len(str(count)))*" ", ": Fetching ", targetpage)
get(targetpage)
count += 1
if VERBOSE: print ("Fetched ", count, " pages")
@@ -192,7 +188,7 @@ def get(page):
html = cleanimagelinks(html)
output(html,page)
else:
if VERBOSE: print (" skipping",page)
if VERBOSE: print (" skipping",page)
def getlinks(html):
"returns a list of wikipage links in html file"
@@ -243,7 +239,7 @@ def cleanhtml(html):
html = re.compile('<div id="mw-navigation.*?</div>').sub('',html) # removing nav stuff
html = re.compile('<table id="toc.*?</table>').sub('',html) # removing toc
html = re.compile('width=\"100%\" style=\"float: right; width: 230px; margin-left: 1em\"').sub('',html) # removing command box styling
html = re.compile('<div class="docnav.*?</div>Wlinebreak</div>').sub('',html) # removing docnav
#html = re.compile('<div class="docnav.*?</div>Wlinebreak</div>').sub('',html) # removing docnav
html = re.compile('<div class="mw-pt-translate-header.*?</div>').sub('',html) # removing translations links
if not GETTRANSLATIONS:
html = re.compile('<div class="languages.*?</div>').sub('',html) # removing translations links
@@ -280,7 +276,7 @@ def cleanimagelinks(html,links=None):
def fetchpage(page):
"retrieves given page from the wiki"
print (" fetching: ",page)
print (" downloading: ",URL + wikiindex + page)
failcount = 0
while failcount < MAXFAIL:
try:
@@ -300,8 +296,8 @@ def fetchimage(imagelink):
failcount = 0
while failcount < MAXFAIL:
try:
if VERBOSE: print (" fetching " + filename)
data = (urlopen(URL + imagelink).read())
if VERBOSE: print (" downloading " + URL + imageprefix + imagelink)
data = (urlopen(URL + imageprefix + imagelink)).read()
path = local(filename,image=True)
file = open(path,'wb')
file.write(data)
@@ -310,11 +306,11 @@ def fetchimage(imagelink):
failcount += 1
else:
processed.append(filename)
if VERBOSE: print (" saving",local(filename,image=True))
if VERBOSE: print (" saving",local(filename,image=True))
return
print ('Error: unable to fetch file ' + filename)
else:
if VERBOSE: print (" skipping",filename)
if VERBOSE: print (" skipping",filename)
def local(page,image=False):
"returns a local path for a given page/image"
@@ -349,7 +345,7 @@ def output(html,page):
filename = filename.replace("&pagefrom=","+")
filename = filename.replace("#mw-pages","")
filename = filename.replace(".html.html",".html")
print (" saving",filename)
print (" saving",filename)
file = open(filename,'wb')
file.write(html)
file.close()