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
+
2
9
import os
3
- from os import path
4
- import shutil
5
- from io import StringIO
10
+ import json
6
11
from datetime import datetime
7
- from io import open
12
+ from io import StringIO , open
8
13
9
14
from lxml import etree
10
15
import markdown
11
16
from markdown .extensions .toc import TocExtension
12
17
import markdown .extensions .headerid
13
18
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
19
21
20
- basepath = os .path .dirname (os .path .realpath (__file__ ))
21
22
23
+ BASEPATH = os .path .dirname (os .path .realpath (__file__ ))
22
24
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."""
24
31
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
+ ))
28
44
29
- def maketoc (html_doc , toc ):
45
+ def _maketoc (html_doc , toc ):
46
+ """Build table of contents."""
30
47
parser = etree .HTMLParser ()
31
48
doc = etree .parse (html_doc , parser )
32
49
last = - 1
@@ -61,20 +78,22 @@ def maketoc(html_doc, toc):
61
78
level -= 1
62
79
toc .write (u'</nav>\n ' )
63
80
64
- def embed_style (html_file ):
81
+ def _embed_style (html_file ):
82
+ """Embed a CSS file in the HTML."""
65
83
parser = etree .HTMLParser (encoding = 'utf-8' )
66
84
doc = etree .parse (html_file , parser )
67
85
for node in doc .xpath ('//link[@rel="stylesheet"]' ):
68
86
href = node .get ('href' )
69
- css = os .path .join (basepath , href )
87
+ css = os .path .join (BASEPATH , href )
70
88
node .tag = 'style'
71
89
node .text = '\n ' + open (css , 'r' ).read () + '\n '
72
90
node .attrib .clear ()
73
91
node .set ('id' , href )
74
92
with open (html_file , 'w' ) as f :
75
93
f .write (etree .tostring (doc , method = "html" ).decode ('utf-8' ))
76
94
77
- def get_options (html_file ):
95
+ def _get_options (html_file ):
96
+ """Get the next command-line option."""
78
97
parser = etree .HTMLParser (encoding = 'utf-8' )
79
98
doc = etree .parse (html_file , parser )
80
99
output = []
@@ -95,55 +114,61 @@ def get_options(html_file):
95
114
output .append (node )
96
115
return output
97
116
98
- def embed_options (html_file ):
117
+ def _embed_options (html_file ):
118
+ """Build the synopsis of command-line options."""
99
119
parser = etree .HTMLParser (encoding = 'utf-8' )
100
120
doc = etree .parse (html_file , parser )
101
121
for node in doc .xpath ('//span[@id="placeholder-options"]' ):
102
122
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' ))
107
126
108
127
def 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'
111
131
try :
112
- os .mkdir (basepath + '/../doc' )
132
+ os .mkdir (BASEPATH + '/../doc' )
113
133
except OSError :
114
134
# already there, ignore
115
135
pass
116
136
basic_license_stream = StringIO ()
117
137
doc_license_stream = StringIO ()
118
138
readme_stream = StringIO ()
119
139
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_' )
124
144
125
145
# get the quick-start guide out of README
126
146
quickstart = u'' .join (readme_stream .getvalue ().split (u'<hr>' )[1 :])
127
147
quickstart = quickstart .replace (u'http://pc-basic.org/doc/2.0#' , u'#' )
128
148
129
149
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
+ )
131
154
major_version = '.' .join (VERSION .split ('.' )[:2 ])
132
155
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
+ )
136
161
predoc = StringIO ()
137
162
predoc .write (quickstart_html )
138
- predoc .write (open (basepath + '/documentation.html' , 'r' ).read ())
163
+ predoc .write (open (BASEPATH + '/documentation.html' , 'r' ).read ())
139
164
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 ())
144
169
predoc .write ('<article>\n ' + ack_stream .getvalue () + '</article>\n ' )
145
170
predoc .write (licenses_html )
146
- predoc .write (open (basepath + '/footer.html' , 'r' ).read ())
171
+ predoc .write (open (BASEPATH + '/footer.html' , 'r' ).read ())
147
172
predoc .seek (0 )
148
173
now = datetime .now ().strftime ('%Y-%m-%d %H:%M:%S' )
149
174
if embedded_style :
@@ -152,7 +177,7 @@ def makedoc(header=None, output=None, embedded_style=True):
152
177
<h1>PC-BASIC documentation</h1>
153
178
<small>Version {0}</small>
154
179
</header>
155
- """ .format (VERSION , now , DESCRIPTION , LONG_DESCRIPTION )
180
+ """ .format (VERSION )
156
181
else :
157
182
subheader_html = u''
158
183
subheader_html += u"""
@@ -178,7 +203,7 @@ def makedoc(header=None, output=None, embedded_style=True):
178
203
<li><strong><a href="#dev">Developer's Guide</a></strong>, using PC-BASIC as a Python module</li>
179
204
</ul>
180
205
181
- """ .format (VERSION , now , DESCRIPTION , LONG_DESCRIPTION )
206
+ """ .format (VERSION , now , SETUP_DATA [ 'description' ], SETUP_DATA [ 'long_description' ] )
182
207
if not embedded_style :
183
208
subheader_html += u"""
184
209
<p>
@@ -203,13 +228,13 @@ def makedoc(header=None, output=None, embedded_style=True):
203
228
tocdoc .write (predoc .getvalue ())
204
229
tocdoc .seek (0 )
205
230
toc = StringIO ()
206
- maketoc (tocdoc , toc )
231
+ _maketoc (tocdoc , toc )
207
232
header_html = open (header , 'r' ).read ()
208
233
with open (output , 'w' ) as outf :
209
234
outf .write (header_html )
210
235
outf .write (subheader_html )
211
236
outf .write (toc .getvalue ())
212
237
outf .write (predoc .getvalue ())
213
- embed_options (output )
238
+ _embed_options (output )
214
239
if embedded_style :
215
- embed_style (output )
240
+ _embed_style (output )
0 commit comments