Add more features
Cross-reference tracking/redlinks Page title customisation Last modified
This commit is contained in:
parent
a32795fbe6
commit
205a9a8c82
@ -123,12 +123,13 @@ def page_view(path):
|
||||
|
||||
return flask.render_template('page_rendered.html', page={
|
||||
'path': path,
|
||||
'title': path.split('/')[-1],
|
||||
'title': md.meta['title'] if 'title' in md.meta else path.split('/')[-1],
|
||||
'content': page_content,
|
||||
'toc': md.toc_tokens,
|
||||
'meta': md.meta,
|
||||
'children': children
|
||||
})
|
||||
'children': children,
|
||||
'xrefs': index['xrefs'].get(path, [])
|
||||
}, collapsed='collapsed' in flask.request.args)
|
||||
|
||||
@app.route('/preview/<path:path>')
|
||||
def page_preview(path):
|
||||
@ -214,11 +215,12 @@ def cli_index():
|
||||
|
||||
with app.app_context():
|
||||
tags = {}
|
||||
xrefs = {}
|
||||
|
||||
base_path = './data/pages'
|
||||
for dirpath, dirnames, filenames in os.walk(base_path):
|
||||
for fname in filenames:
|
||||
if fname.endswith('.md'):
|
||||
if fname.endswith('.md') and not os.path.islink(flask.safe_join(dirpath, fname)):
|
||||
page_path = dirpath[len(base_path)+1:] + '/' + fname[:-3]
|
||||
|
||||
with(open(flask.safe_join(dirpath, fname), 'r')) as f:
|
||||
@ -231,6 +233,16 @@ def cli_index():
|
||||
tags[tag] = []
|
||||
tags[tag].append({'kind': 'page', 'path': page_path})
|
||||
|
||||
for ref in md.meta.get('refs', []):
|
||||
fname_ref = flask.safe_join('./data/pages', ref) + '.md'
|
||||
if os.path.islink(fname_ref):
|
||||
ref = '/'.join(ref.split('/')[:-1]) + '/' + os.path.splitext(os.readlink(fname_ref))[0]
|
||||
|
||||
if ref not in xrefs:
|
||||
xrefs[ref] = []
|
||||
if page_path not in xrefs[ref]:
|
||||
xrefs[ref].append(page_path)
|
||||
|
||||
base_path = './data/images'
|
||||
for dirpath, dirnames, filenames in os.walk(base_path):
|
||||
for fname in filenames:
|
||||
@ -251,5 +263,32 @@ def cli_index():
|
||||
|
||||
with open('index.pickle', 'wb') as f:
|
||||
pickle.dump({
|
||||
'tags': tags
|
||||
'tags': tags,
|
||||
'xrefs': xrefs
|
||||
}, f)
|
||||
|
||||
@app.cli.command('redlinks')
|
||||
def cli_redlinks():
|
||||
app.config['SERVER_NAME'] = 'localhost'
|
||||
|
||||
redlinks = set()
|
||||
|
||||
with app.app_context():
|
||||
base_path = './data/pages'
|
||||
for dirpath, dirnames, filenames in os.walk(base_path):
|
||||
for fname in filenames:
|
||||
if fname.endswith('.md'):
|
||||
page_path = dirpath[len(base_path)+1:] + '/' + fname[:-3]
|
||||
|
||||
with(open(flask.safe_join(dirpath, fname), 'r')) as f:
|
||||
page_source = f.read()
|
||||
md = WNMarkdown()
|
||||
md.convert(page_source)
|
||||
|
||||
for redlink in md.meta.get('redlinks', []):
|
||||
redlinks.add(redlink)
|
||||
|
||||
redlinks = sorted(list(redlinks))
|
||||
|
||||
for redlink in redlinks:
|
||||
print(redlink)
|
||||
|
@ -37,7 +37,7 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block leftbox %}
|
||||
{% if page.toc or page.meta.tags %}
|
||||
{% if page.toc or page.meta.tags or (page.xrefs and not collapsed) %}
|
||||
<div>
|
||||
{% if page.toc %}
|
||||
<ul class="toc">
|
||||
@ -55,6 +55,23 @@
|
||||
{% endfor %}
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
{% if page.xrefs and not collapsed %}
|
||||
<div style="font-size: small;">
|
||||
<p><em>Cross-references:</em></p>
|
||||
<ul>
|
||||
{% for xref in page.xrefs %}
|
||||
<li><a href="{{ url_for('page_view', path=xref) }}">{{ xref.replace('/', ' › ') }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if page.meta.lastmod %}
|
||||
<div style="font-size: small;">
|
||||
<p><em>Last modified:</em> {{ page.meta.lastmod }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
@ -50,6 +50,16 @@ def capitalise(n):
|
||||
return '(' + capitalise(n[1:])
|
||||
return n[0].upper() + n[1:]
|
||||
|
||||
class DirectiveTitle(Directive):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.md.meta['title'] = self.arg
|
||||
|
||||
def render(self):
|
||||
return DirectiveElement('div')
|
||||
|
||||
directives['title'] = DirectiveTitle
|
||||
|
||||
class DirectiveTag(Directive):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
@ -60,6 +70,16 @@ class DirectiveTag(Directive):
|
||||
|
||||
directives['tag'] = DirectiveTag
|
||||
|
||||
class DirectiveLastmod(Directive):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.md.meta['lastmod'] = self.arg
|
||||
|
||||
def render(self):
|
||||
return DirectiveElement('div')
|
||||
|
||||
directives['lastmod'] = DirectiveLastmod
|
||||
|
||||
class DirectiveInclude(Directive):
|
||||
def render(self):
|
||||
el = DirectiveElement('div')
|
||||
@ -102,6 +122,8 @@ def make_role_ref(is_upper):
|
||||
div.set('class', 'tooltip-content')
|
||||
div.text = 'Loading…'
|
||||
|
||||
self.md.meta['refs'] = self.md.meta.get('refs', []) + [path]
|
||||
|
||||
return el
|
||||
return RoleRef
|
||||
|
||||
@ -119,6 +141,9 @@ class RoleImage(Role):
|
||||
img.set('src', flask.url_for('image_view', name=image))
|
||||
if style:
|
||||
img.set('style', style)
|
||||
|
||||
self.md.meta['refs'] = self.md.meta.get('refs', []) + [image]
|
||||
|
||||
return el
|
||||
|
||||
roles['image'] = RoleImage
|
||||
|
@ -77,7 +77,7 @@ html, body {
|
||||
max-height: calc(100% - 1cm);
|
||||
}
|
||||
|
||||
aside.leftbox > div :last-child, aside.rightbox > div :last-child {
|
||||
aside.leftbox > div p:last-child, aside.rightbox > div p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
@ -141,9 +141,11 @@ h4, h5, h6 {
|
||||
font-size: 1rem; /* 10.5pt */
|
||||
margin-top: 0.4cm;
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
section > div.two-columns > aside > h3:first-child {
|
||||
section > div.two-columns > aside > h3:first-child,
|
||||
section > div.two-columns > aside > h4:first-child {
|
||||
margin-top: 0.15cm; /* Adjust for 0.25cm of heading above */
|
||||
}
|
||||
|
||||
@ -243,7 +245,8 @@ div.two-columns > aside:not(:last-of-type) {
|
||||
|
||||
/* Remove trailing margins */
|
||||
|
||||
div.admonition > p:last-child,
|
||||
div.admonition > p:last-child, div.admonition > div > p:last-child,
|
||||
div.admonition > ul:last-child, div.admonition > ol:last-child,
|
||||
td > ul:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
@ -291,13 +294,23 @@ div.admonition.pharm a.drug {
|
||||
color: black;
|
||||
font-weight: 600;
|
||||
}
|
||||
div.admonition.pharm span.alt-drugs {
|
||||
span.alt-drugs {
|
||||
color: #888a85;
|
||||
text-decoration: underline;
|
||||
text-decoration-style: dashed;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
div.admonition.buzzword {
|
||||
background-color: #d8f6bcff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
div.admonition.buzzword > img {
|
||||
width: 32px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
/* Tooltips */
|
||||
.tooltip {
|
||||
position: relative;
|
||||
|
Reference in New Issue
Block a user