1- import sys
1+ """
2+ PC-BASIC - docsrc.doc
3+ HTML documentation builder
4+
5+ (c) 2013--2020 Rob Hagemans
6+ This file is released under the GNU GPL version 3 or later.
7+ """
8+
29import os
3- from os import path
4- import shutil
5- from io import StringIO
10+ import json
611from datetime import datetime
7- from io import open
12+ from io import StringIO , open
813
914from lxml import etree
1015import markdown
1116from markdown .extensions .toc import TocExtension
1217import markdown .extensions .headerid
1318
14- # obtain metadata without importing the package (to avoid breaking setup)
15- with open (
16- path .join (path .abspath (path .dirname (__file__ )), '..' , 'pcbasic' , 'metadata.py' ),
17- encoding = 'utf-8' ) as f :
18- exec (f .read ())
19+ # we're not being called from setup.py install, so we can simply import pcbasic
20+ from pcbasic .basic import VERSION
1921
20- basepath = os .path .dirname (os .path .realpath (__file__ ))
2122
23+ BASEPATH = os .path .dirname (os .path .realpath (__file__ ))
2224
23- def mdtohtml (md_file , outf , prefix = '' , baselevel = 1 ):
25+ with open (os .path .join (BASEPATH , '..' , 'setup.json' ), encoding = 'utf-8' ) as setup_data :
26+ SETUP_DATA = json .load (setup_data )
27+
28+
29+ def _md_to_html (md_file , outf , prefix = '' , baselevel = 1 ):
30+ """Convert markdown to html."""
2431 with open (md_file , 'r' , encoding = 'utf-8' ) as inf :
25- md = inf .read ()
26- toc = TocExtension (baselevel = baselevel , slugify = lambda value , separator : prefix + markdown .extensions .headerid .slugify (value , separator ))
27- outf .write (markdown .markdown (md , extensions = ['markdown.extensions.tables' , toc ], output_format = 'html5' , lazy_ol = False ))
32+ mdown = inf .read ()
33+ toc = TocExtension (
34+ baselevel = baselevel ,
35+ slugify = (
36+ lambda value , separator :
37+ prefix + markdown .extensions .headerid .slugify (value , separator )
38+ )
39+ )
40+ outf .write (markdown .markdown (
41+ mdown , extensions = ['markdown.extensions.tables' , toc ],
42+ output_format = 'html5' , lazy_ol = False
43+ ))
2844
29- def maketoc (html_doc , toc ):
45+ def _maketoc (html_doc , toc ):
46+ """Build table of contents."""
3047 parser = etree .HTMLParser ()
3148 doc = etree .parse (html_doc , parser )
3249 last = - 1
@@ -61,20 +78,22 @@ def maketoc(html_doc, toc):
6178 level -= 1
6279 toc .write (u'</nav>\n ' )
6380
64- def embed_style (html_file ):
81+ def _embed_style (html_file ):
82+ """Embed a CSS file in the HTML."""
6583 parser = etree .HTMLParser (encoding = 'utf-8' )
6684 doc = etree .parse (html_file , parser )
6785 for node in doc .xpath ('//link[@rel="stylesheet"]' ):
6886 href = node .get ('href' )
69- css = os .path .join (basepath , href )
87+ css = os .path .join (BASEPATH , href )
7088 node .tag = 'style'
7189 node .text = '\n ' + open (css , 'r' ).read () + '\n '
7290 node .attrib .clear ()
7391 node .set ('id' , href )
7492 with open (html_file , 'w' ) as f :
7593 f .write (etree .tostring (doc , method = "html" ).decode ('utf-8' ))
7694
77- def get_options (html_file ):
95+ def _get_options (html_file ):
96+ """Get the next command-line option."""
7897 parser = etree .HTMLParser (encoding = 'utf-8' )
7998 doc = etree .parse (html_file , parser )
8099 output = []
@@ -95,55 +114,61 @@ def get_options(html_file):
95114 output .append (node )
96115 return output
97116
98- def embed_options (html_file ):
117+ def _embed_options (html_file ):
118+ """Build the synopsis of command-line options."""
99119 parser = etree .HTMLParser (encoding = 'utf-8' )
100120 doc = etree .parse (html_file , parser )
101121 for node in doc .xpath ('//span[@id="placeholder-options"]' ):
102122 node .clear ()
103- for c in get_options (html_file ):
104- node .append (c )
105- with open (html_file , 'w' ) as f :
106- f .write (etree .tostring (doc , method = "html" ).decode ('utf-8' ))
123+ node .extend (_option for _option in _get_options (html_file ))
124+ with open (html_file , 'w' ) as htmlf :
125+ htmlf .write (etree .tostring (doc , method = 'html' ).decode ('utf-8' ))
107126
108127def makedoc (header = None , output = None , embedded_style = True ):
109- header = header or basepath + '/header.html'
110- output = output or basepath + '/../doc/PC-BASIC_documentation.html'
128+ """Build HTML documentation from sources."""
129+ header = header or BASEPATH + '/header.html'
130+ output = output or BASEPATH + '/../doc/PC-BASIC_documentation.html'
111131 try :
112- os .mkdir (basepath + '/../doc' )
132+ os .mkdir (BASEPATH + '/../doc' )
113133 except OSError :
114134 # already there, ignore
115135 pass
116136 basic_license_stream = StringIO ()
117137 doc_license_stream = StringIO ()
118138 readme_stream = StringIO ()
119139 ack_stream = StringIO ()
120- mdtohtml ( basepath + '/../LICENSE.md' , basic_license_stream )
121- mdtohtml ( basepath + '/LICENSE.md' , doc_license_stream )
122- mdtohtml ( basepath + '/../README.md' , readme_stream , baselevel = 0 )
123- mdtohtml ( basepath + '/../THANKS.md' , ack_stream , 'acks_' )
140+ _md_to_html ( BASEPATH + '/../LICENSE.md' , basic_license_stream )
141+ _md_to_html ( BASEPATH + '/LICENSE.md' , doc_license_stream )
142+ _md_to_html ( BASEPATH + '/../README.md' , readme_stream , baselevel = 0 )
143+ _md_to_html ( BASEPATH + '/../THANKS.md' , ack_stream , 'acks_' )
124144
125145 # get the quick-start guide out of README
126146 quickstart = u'' .join (readme_stream .getvalue ().split (u'<hr>' )[1 :])
127147 quickstart = quickstart .replace (u'http://pc-basic.org/doc/2.0#' , u'#' )
128148
129149 quickstart_html = ('<article>\n ' + quickstart + '</article>\n ' )
130- licenses_html = '<footer>\n <h2 id="licence">Licences</h2>\n ' + basic_license_stream .getvalue () + '<hr />\n ' + doc_license_stream .getvalue () + '\n </footer>\n '
150+ licenses_html = (
151+ '<footer>\n <h2 id="licence">Licences</h2>\n ' + basic_license_stream .getvalue ()
152+ + '<hr />\n ' + doc_license_stream .getvalue () + '\n </footer>\n '
153+ )
131154 major_version = '.' .join (VERSION .split ('.' )[:2 ])
132155 settings_html = (
133- '<article>\n ' + open (basepath + '/settings.html' , 'r' ).read ().replace ('0.0' , major_version )
134- + '<hr />\n ' + open (basepath + '/options.html' , 'r' ).read ()
135- + open (basepath + '/examples.html' , 'r' ).read () + '</article>\n ' )
156+ '<article>\n '
157+ + open (BASEPATH + '/settings.html' , 'r' ).read ().replace ('0.0' , major_version )
158+ + '<hr />\n ' + open (BASEPATH + '/options.html' , 'r' ).read ()
159+ + open (BASEPATH + '/examples.html' , 'r' ).read () + '</article>\n '
160+ )
136161 predoc = StringIO ()
137162 predoc .write (quickstart_html )
138- predoc .write (open (basepath + '/documentation.html' , 'r' ).read ())
163+ predoc .write (open (BASEPATH + '/documentation.html' , 'r' ).read ())
139164 predoc .write (settings_html )
140- predoc .write (open (basepath + '/guide.html' , 'r' ).read ())
141- predoc .write (open (basepath + '/reference.html' , 'r' ).read ())
142- predoc .write (open (basepath + '/techref.html' , 'r' ).read ())
143- predoc .write (open (basepath + '/devguide.html' , 'r' ).read ())
165+ predoc .write (open (BASEPATH + '/guide.html' , 'r' ).read ())
166+ predoc .write (open (BASEPATH + '/reference.html' , 'r' ).read ())
167+ predoc .write (open (BASEPATH + '/techref.html' , 'r' ).read ())
168+ predoc .write (open (BASEPATH + '/devguide.html' , 'r' ).read ())
144169 predoc .write ('<article>\n ' + ack_stream .getvalue () + '</article>\n ' )
145170 predoc .write (licenses_html )
146- predoc .write (open (basepath + '/footer.html' , 'r' ).read ())
171+ predoc .write (open (BASEPATH + '/footer.html' , 'r' ).read ())
147172 predoc .seek (0 )
148173 now = datetime .now ().strftime ('%Y-%m-%d %H:%M:%S' )
149174 if embedded_style :
@@ -152,7 +177,7 @@ def makedoc(header=None, output=None, embedded_style=True):
152177 <h1>PC-BASIC documentation</h1>
153178 <small>Version {0}</small>
154179</header>
155- """ .format (VERSION , now , DESCRIPTION , LONG_DESCRIPTION )
180+ """ .format (VERSION )
156181 else :
157182 subheader_html = u''
158183 subheader_html += u"""
@@ -178,7 +203,7 @@ def makedoc(header=None, output=None, embedded_style=True):
178203 <li><strong><a href="#dev">Developer's Guide</a></strong>, using PC-BASIC as a Python module</li>
179204 </ul>
180205
181- """ .format (VERSION , now , DESCRIPTION , LONG_DESCRIPTION )
206+ """ .format (VERSION , now , SETUP_DATA [ 'description' ], SETUP_DATA [ 'long_description' ] )
182207 if not embedded_style :
183208 subheader_html += u"""
184209 <p>
@@ -203,13 +228,13 @@ def makedoc(header=None, output=None, embedded_style=True):
203228 tocdoc .write (predoc .getvalue ())
204229 tocdoc .seek (0 )
205230 toc = StringIO ()
206- maketoc (tocdoc , toc )
231+ _maketoc (tocdoc , toc )
207232 header_html = open (header , 'r' ).read ()
208233 with open (output , 'w' ) as outf :
209234 outf .write (header_html )
210235 outf .write (subheader_html )
211236 outf .write (toc .getvalue ())
212237 outf .write (predoc .getvalue ())
213- embed_options (output )
238+ _embed_options (output )
214239 if embedded_style :
215- embed_style (output )
240+ _embed_style (output )
0 commit comments