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={
|
return flask.render_template('page_rendered.html', page={
|
||||||
'path': path,
|
'path': path,
|
||||||
'title': path.split('/')[-1],
|
'title': md.meta['title'] if 'title' in md.meta else path.split('/')[-1],
|
||||||
'content': page_content,
|
'content': page_content,
|
||||||
'toc': md.toc_tokens,
|
'toc': md.toc_tokens,
|
||||||
'meta': md.meta,
|
'meta': md.meta,
|
||||||
'children': children
|
'children': children,
|
||||||
})
|
'xrefs': index['xrefs'].get(path, [])
|
||||||
|
}, collapsed='collapsed' in flask.request.args)
|
||||||
|
|
||||||
@app.route('/preview/<path:path>')
|
@app.route('/preview/<path:path>')
|
||||||
def page_preview(path):
|
def page_preview(path):
|
||||||
@ -214,11 +215,12 @@ def cli_index():
|
|||||||
|
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
tags = {}
|
tags = {}
|
||||||
|
xrefs = {}
|
||||||
|
|
||||||
base_path = './data/pages'
|
base_path = './data/pages'
|
||||||
for dirpath, dirnames, filenames in os.walk(base_path):
|
for dirpath, dirnames, filenames in os.walk(base_path):
|
||||||
for fname in filenames:
|
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]
|
page_path = dirpath[len(base_path)+1:] + '/' + fname[:-3]
|
||||||
|
|
||||||
with(open(flask.safe_join(dirpath, fname), 'r')) as f:
|
with(open(flask.safe_join(dirpath, fname), 'r')) as f:
|
||||||
@ -231,6 +233,16 @@ def cli_index():
|
|||||||
tags[tag] = []
|
tags[tag] = []
|
||||||
tags[tag].append({'kind': 'page', 'path': page_path})
|
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'
|
base_path = './data/images'
|
||||||
for dirpath, dirnames, filenames in os.walk(base_path):
|
for dirpath, dirnames, filenames in os.walk(base_path):
|
||||||
for fname in filenames:
|
for fname in filenames:
|
||||||
@ -251,5 +263,32 @@ def cli_index():
|
|||||||
|
|
||||||
with open('index.pickle', 'wb') as f:
|
with open('index.pickle', 'wb') as f:
|
||||||
pickle.dump({
|
pickle.dump({
|
||||||
'tags': tags
|
'tags': tags,
|
||||||
|
'xrefs': xrefs
|
||||||
}, f)
|
}, 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 %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block leftbox %}
|
{% block leftbox %}
|
||||||
{% if page.toc or page.meta.tags %}
|
{% if page.toc or page.meta.tags or (page.xrefs and not collapsed) %}
|
||||||
<div>
|
<div>
|
||||||
{% if page.toc %}
|
{% if page.toc %}
|
||||||
<ul class="toc">
|
<ul class="toc">
|
||||||
@ -55,6 +55,23 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</p>
|
</p>
|
||||||
{% endif %}
|
{% 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>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -50,6 +50,16 @@ def capitalise(n):
|
|||||||
return '(' + capitalise(n[1:])
|
return '(' + capitalise(n[1:])
|
||||||
return n[0].upper() + 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):
|
class DirectiveTag(Directive):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
@ -60,6 +70,16 @@ class DirectiveTag(Directive):
|
|||||||
|
|
||||||
directives['tag'] = DirectiveTag
|
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):
|
class DirectiveInclude(Directive):
|
||||||
def render(self):
|
def render(self):
|
||||||
el = DirectiveElement('div')
|
el = DirectiveElement('div')
|
||||||
@ -102,6 +122,8 @@ def make_role_ref(is_upper):
|
|||||||
div.set('class', 'tooltip-content')
|
div.set('class', 'tooltip-content')
|
||||||
div.text = 'Loading…'
|
div.text = 'Loading…'
|
||||||
|
|
||||||
|
self.md.meta['refs'] = self.md.meta.get('refs', []) + [path]
|
||||||
|
|
||||||
return el
|
return el
|
||||||
return RoleRef
|
return RoleRef
|
||||||
|
|
||||||
@ -119,6 +141,9 @@ class RoleImage(Role):
|
|||||||
img.set('src', flask.url_for('image_view', name=image))
|
img.set('src', flask.url_for('image_view', name=image))
|
||||||
if style:
|
if style:
|
||||||
img.set('style', style)
|
img.set('style', style)
|
||||||
|
|
||||||
|
self.md.meta['refs'] = self.md.meta.get('refs', []) + [image]
|
||||||
|
|
||||||
return el
|
return el
|
||||||
|
|
||||||
roles['image'] = RoleImage
|
roles['image'] = RoleImage
|
||||||
|
@ -77,7 +77,7 @@ html, body {
|
|||||||
max-height: calc(100% - 1cm);
|
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;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -141,9 +141,11 @@ h4, h5, h6 {
|
|||||||
font-size: 1rem; /* 10.5pt */
|
font-size: 1rem; /* 10.5pt */
|
||||||
margin-top: 0.4cm;
|
margin-top: 0.4cm;
|
||||||
font-weight: normal;
|
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 */
|
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 */
|
/* 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 {
|
td > ul:last-child {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
@ -291,13 +294,23 @@ div.admonition.pharm a.drug {
|
|||||||
color: black;
|
color: black;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
div.admonition.pharm span.alt-drugs {
|
span.alt-drugs {
|
||||||
color: #888a85;
|
color: #888a85;
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
text-decoration-style: dashed;
|
text-decoration-style: dashed;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.admonition.buzzword {
|
||||||
|
background-color: #d8f6bcff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
div.admonition.buzzword > img {
|
||||||
|
width: 32px;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Tooltips */
|
/* Tooltips */
|
||||||
.tooltip {
|
.tooltip {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
Reference in New Issue
Block a user