146
|
146
|
|
f'''
|
147
|
147
|
|
PREFIX mp: <dokk:manpages:>
|
148
|
148
|
|
|
149
|
|
- |
SELECT DISTINCT ?package
|
|
149
|
+ |
SELECT DISTINCT ?name
|
150
|
150
|
|
WHERE {{
|
151
|
|
- |
?id mp:source [
|
152
|
|
- |
mp:distribution_name "{distribution}" ;
|
153
|
|
- |
mp:distribution_version "{version}" ;
|
154
|
|
- |
mp:package ?package ;
|
155
|
|
- |
] .
|
|
151
|
+ |
[] a mp:Distribution ;
|
|
152
|
+ |
mp:name "{distribution}" ;
|
|
153
|
+ |
mp:number {version} ;
|
|
154
|
+ |
mp:package ?package .
|
|
155
|
+ |
|
|
156
|
+ |
?package a mp:Package ;
|
|
157
|
+ |
mp:name ?name .
|
156
|
158
|
|
}}
|
157
|
|
- |
ORDER BY ?package
|
|
159
|
+ |
ORDER BY ?name
|
158
|
160
|
|
''')
|
159
|
161
|
|
|
160
|
162
|
|
return template('templates/manpages/distribution.tpl', data=data, distribution=distribution, version=version)
|
169
|
171
|
|
f'''
|
170
|
172
|
|
PREFIX mp: <dokk:manpages:>
|
171
|
173
|
|
|
172
|
|
- |
SELECT ?id ?filename
|
|
174
|
+ |
SELECT (?page as ?id) ?filename
|
173
|
175
|
|
WHERE {{
|
174
|
|
- |
?id mp:source [
|
175
|
|
- |
mp:package "{package}" ;
|
176
|
|
- |
mp:distribution_version "{version}" ;
|
177
|
|
- |
mp:distribution_name "{distribution}" ;
|
178
|
|
- |
mp:filename ?filename ;
|
179
|
|
- |
] .
|
|
176
|
+ |
[] a mp:Distribution ;
|
|
177
|
+ |
mp:name "{distribution}" ;
|
|
178
|
+ |
mp:number {version} ;
|
|
179
|
+ |
mp:package ?package .
|
|
180
|
+ |
|
|
181
|
+ |
?package a mp:Package ;
|
|
182
|
+ |
mp:name "{package}" ;
|
|
183
|
+ |
mp:page ?page .
|
|
184
|
+ |
|
|
185
|
+ |
?page a mp:Page ;
|
|
186
|
+ |
mp:filename ?filename
|
180
|
187
|
|
}}
|
181
|
188
|
|
ORDER BY ?filename
|
182
|
189
|
|
''')
|
183
|
190
|
|
|
184
|
191
|
|
return template('templates/manpages/package.tpl', data=data, distribution=distribution, version=version, package=package)
|
185
|
192
|
|
|
186
|
|
- |
@bottle.get('/manpages/<distribution>/<version>/<package>/<name>.<section>.<lang>', name='manpages_page')
|
187
|
|
- |
def manpages_page(distribution, version, package, name, section, lang):
|
|
193
|
+ |
@bottle.get('/manpages/<name>.<section>', name='manpages_disambiguation')
|
|
194
|
+ |
def manpages_disambiguation(name, section):
|
188
|
195
|
|
"""
|
189
|
|
- |
Display a single manpage.
|
|
196
|
+ |
Show a list of manpages that match <name> and <section>
|
190
|
197
|
|
"""
|
191
|
198
|
|
|
192
|
|
- |
page_id = f'<dokk:manpages:{distribution}/{version}/{package}/{name}.{section}.{lang}>'
|
193
|
|
- |
|
194
|
|
- |
# These characters where url-encoded when creating the RDF data because they
|
195
|
|
- |
# make invalid URIs. This means for example that in the graph the URIs will be
|
196
|
|
- |
# encoded with %23 instead of #
|
197
|
|
- |
page_id = page_id.replace(' ', '_') \
|
198
|
|
- |
.replace('[', '%5B') \
|
199
|
|
- |
.replace(']', '%5D') \
|
200
|
|
- |
.replace('#', '%23')
|
201
|
|
- |
|
202
|
199
|
|
data = query(
|
203
|
200
|
|
f'''
|
204
|
201
|
|
PREFIX mp: <dokk:manpages:>
|
205
|
202
|
|
|
206
|
|
- |
DESCRIBE {page_id}
|
207
|
|
- |
''',
|
208
|
|
- |
{
|
209
|
|
- |
'@context': {
|
210
|
|
- |
'mp': 'dokk:manpages:',
|
211
|
|
- |
},
|
212
|
|
- |
'mp:source': {},
|
213
|
|
- |
})
|
214
|
|
- |
|
215
|
|
- |
# Replace references to other manpages with links.
|
216
|
|
- |
# Manpages have a section "See also" at the bottom where they suggest other pages.
|
217
|
|
- |
# For example:
|
218
|
|
- |
# SEE ALSO
|
219
|
|
- |
# cdk(3), cdk_screen(3), cdk_display(3), cdk_binding(3), cdk_util(3)
|
220
|
|
- |
# We convert these strings to links to other pages.
|
221
|
|
- |
# Example: ls(1) -> <a href="...">ls(1)</a>
|
222
|
|
- |
# regex explanation:
|
223
|
|
- |
# - some manpages use a bold or italic name, so we match an optional <b>
|
224
|
|
- |
# <i> tag
|
225
|
|
- |
# - match valid characters for a manpage, assign name <page>
|
226
|
|
- |
# - match optional closing </em> or </strong> tags
|
227
|
|
- |
# - match '('
|
228
|
|
- |
# - match number, assign name <section>
|
229
|
|
- |
# - match ')'
|
230
|
|
- |
html = data['@graph'][0]['mp:html']
|
231
|
|
- |
html = re.sub (
|
232
|
|
- |
'(?:<b>|<i>)?(?P<page>[\w_.:-]+)(?:</b>|</i>)?\((?P<section>[0-9]\w*)\)',
|
233
|
|
- |
lambda match:
|
234
|
|
- |
f'''<a href="{application.get_url('manpages_disambiguation',
|
235
|
|
- |
name=match.group('page'), section=match.group('section')).lower()}"
|
236
|
|
- |
>{match.group('page')}({match.group('section')})</a>''',
|
237
|
|
- |
html)
|
238
|
|
- |
|
239
|
|
- |
data['@graph'][0]['mp:html'] = html
|
|
203
|
+ |
SELECT *
|
|
204
|
+ |
WHERE {{
|
|
205
|
+ |
?page a mp:Page ;
|
|
206
|
+ |
mp:filename ?filename ;
|
|
207
|
+ |
mp:name_lowercase "{name}" ;
|
|
208
|
+ |
mp:section_lowercase "{section}" .
|
|
209
|
+ |
|
|
210
|
+ |
?package a mp:Package ;
|
|
211
|
+ |
mp:name ?package_name ;
|
|
212
|
+ |
mp:page ?page .
|
|
213
|
+ |
|
|
214
|
+ |
?distro a mp:Distribution ;
|
|
215
|
+ |
mp:name ?distro_name ;
|
|
216
|
+ |
mp:number ?distro_number ;
|
|
217
|
+ |
mp:package ?package .
|
|
218
|
+ |
}}
|
|
219
|
+ |
ORDER BY ?distro_name ?distro_number ?package_name
|
|
220
|
+ |
''')['results']['bindings']
|
240
|
221
|
|
|
241
|
|
- |
return template('templates/manpages/manpage.tpl', data=data['@graph'][0], distribution=distribution,
|
242
|
|
- |
version=version, package=package, name=name, section=section, lang=lang)
|
|
222
|
+ |
return template('templates/manpages/disambiguation.tpl', name=name, section=section, data=data)
|
243
|
223
|
|
|
244
|
|
- |
@bottle.get('/manpages/<name>.<section>', name='manpages_disambiguation')
|
245
|
|
- |
def manpages_disambiguation(name, section):
|
|
224
|
+ |
@bottle.get('/manpages/<distro_name>/<distro_number>/<package>/<page>', name='manpages_page')
|
|
225
|
+ |
def manpages_page(distro_name, distro_number, package, page):
|
246
|
226
|
|
"""
|
247
|
|
- |
Show a list of manpages that match <name> and <section>
|
|
227
|
+ |
Display a single manpage.
|
248
|
228
|
|
"""
|
249
|
229
|
|
|
250
|
230
|
|
data = query(
|
251
|
231
|
|
f'''
|
252
|
232
|
|
PREFIX mp: <dokk:manpages:>
|
253
|
233
|
|
|
254
|
|
- |
DESCRIBE ?page
|
|
234
|
+ |
SELECT *
|
255
|
235
|
|
WHERE {{
|
256
|
|
- |
?page mp:name_lowercase "{name}" ;
|
257
|
|
- |
mp:section_lowercase "{section}" .
|
|
236
|
+ |
?page a mp:Page ;
|
|
237
|
+ |
mp:filename "{page}" ;
|
|
238
|
+ |
mp:name ?page_name ;
|
|
239
|
+ |
mp:section ?page_section ;
|
|
240
|
+ |
mp:html ?page_html .
|
|
241
|
+ |
|
|
242
|
+ |
?package a mp:Package ;
|
|
243
|
+ |
mp:name "{package}" ;
|
|
244
|
+ |
mp:page ?page .
|
|
245
|
+ |
|
|
246
|
+ |
?distro a mp:Distribution ;
|
|
247
|
+ |
mp:name "{distro_name}" ;
|
|
248
|
+ |
mp:number {distro_number} ;
|
|
249
|
+ |
mp:package ?package .
|
258
|
250
|
|
}}
|
259
|
|
- |
''',
|
260
|
|
- |
{
|
261
|
|
- |
'@context': {
|
262
|
|
- |
'mp': 'dokk:manpages:',
|
263
|
|
- |
},
|
264
|
|
- |
'mp:source': {},
|
265
|
|
- |
})
|
|
251
|
+ |
''')['results']['bindings'][0]
|
|
252
|
+ |
|
|
253
|
+ |
"""
|
|
254
|
+ |
Replace references to other manpages with links.
|
|
255
|
+ |
Manpages have a section "See also" at the bottom where they suggest other pages.
|
|
256
|
+ |
For example:
|
|
257
|
+ |
SEE ALSO
|
|
258
|
+ |
cdk(3), cdk_screen(3), cdk_display(3), cdk_binding(3), cdk_util(3)
|
|
259
|
+ |
We convert these strings to links to other pages.
|
|
260
|
+ |
Example: ls(1) -> <a href="...">ls(1)</a>
|
|
261
|
+ |
regex explanation:
|
|
262
|
+ |
- some manpages use a bold or italic name, so we match an optional <b>
|
|
263
|
+ |
<i> tag
|
|
264
|
+ |
- match valid characters for a manpage, assign name <page>
|
|
265
|
+ |
- match optional closing </em> or </strong> tags
|
|
266
|
+ |
- match '('
|
|
267
|
+ |
- match number, assign name <section>
|
|
268
|
+ |
- match ')'
|
|
269
|
+ |
"""
|
|
270
|
+ |
|
|
271
|
+ |
html = data['page_html']['value']
|
|
272
|
+ |
html = re.sub (
|
|
273
|
+ |
'(?:<b>|<i>)?(?P<page>[\w_.:-]+)(?:</b>|</i>)?\((?P<section>[0-9]\w*)\)',
|
|
274
|
+ |
lambda match:
|
|
275
|
+ |
f'''<a href="{application.get_url('manpages_disambiguation',
|
|
276
|
+ |
name=match.group('page'), section=match.group('section')).lower()}"
|
|
277
|
+ |
>{match.group('page')}({match.group('section')})</a>''',
|
|
278
|
+ |
html)
|
266
|
279
|
|
|
267
|
|
- |
return template('templates/manpages/disambiguation.tpl', name=name, section=section, data=data)
|
|
280
|
+ |
return template('templates/manpages/manpage.tpl',
|
|
281
|
+ |
distro = {'name': distro_name, 'number': distro_number},
|
|
282
|
+ |
package = package,
|
|
283
|
+ |
page = {
|
|
284
|
+ |
'filename': page,
|
|
285
|
+ |
'name': data['page_name']['value'],
|
|
286
|
+ |
'section': data['page_section']['value'],
|
|
287
|
+ |
'html': html,
|
|
288
|
+ |
})
|
268
|
289
|
|
|
269
|
290
|
|
@bottle.get('/mimi_and_eunice/<number>', name='mimi_and_eunice_strip')
|
270
|
291
|
|
def mimi_and_eunice_strip(number):
|