Implement expand/collapse heading buttons
This commit is contained in:
parent
af00a10cfb
commit
05e239b9ff
@ -20,6 +20,7 @@ import flask
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import pickle
|
import pickle
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
app = flask.Flask(__name__, template_folder='jinja2')
|
app = flask.Flask(__name__, template_folder='jinja2')
|
||||||
|
|
||||||
@ -98,7 +99,27 @@ def page_view(path):
|
|||||||
page_source = f.read()
|
page_source = f.read()
|
||||||
|
|
||||||
md = WNMarkdown()
|
md = WNMarkdown()
|
||||||
page_content = md.convert(page_source)
|
#page_content = md.convert(page_source)
|
||||||
|
root = md.parse(page_source)
|
||||||
|
|
||||||
|
# Add expand/collapse buttons to h2
|
||||||
|
for elem in root:
|
||||||
|
if elem.tag == 'h2':
|
||||||
|
elem.text += ' '
|
||||||
|
btn = ET.SubElement(elem, 'button')
|
||||||
|
btn.text = '±'
|
||||||
|
btn.set('class', 'expcol')
|
||||||
|
btn.set('onclick', 'onClickExpCol(this);')
|
||||||
|
|
||||||
|
# Handle collapsed sections
|
||||||
|
if root == '':
|
||||||
|
page_content = ''
|
||||||
|
else:
|
||||||
|
if 'collapsed' in flask.request.args:
|
||||||
|
for elem in root:
|
||||||
|
if elem.tag == 'section':
|
||||||
|
elem.set('class', 'collapsed')
|
||||||
|
page_content = md.serialise(root)
|
||||||
|
|
||||||
return flask.render_template('page_rendered.html', page={
|
return flask.render_template('page_rendered.html', page={
|
||||||
'path': path,
|
'path': path,
|
||||||
@ -109,29 +130,6 @@ def page_view(path):
|
|||||||
'children': children
|
'children': children
|
||||||
})
|
})
|
||||||
|
|
||||||
@app.route('/toc/<path:path>')
|
|
||||||
def page_toc(path):
|
|
||||||
fname = flask.safe_join('./data/pages', path) + '.md'
|
|
||||||
|
|
||||||
if not os.path.exists(fname):
|
|
||||||
return flask.render_template('page_404.html', page={
|
|
||||||
'path': path,
|
|
||||||
'title': path.split('/')[-1],
|
|
||||||
'children': []
|
|
||||||
})
|
|
||||||
|
|
||||||
with(open(fname, 'r')) as f:
|
|
||||||
page_source = f.read()
|
|
||||||
|
|
||||||
md = WNMarkdown()
|
|
||||||
_ = md.convert(page_source)
|
|
||||||
|
|
||||||
return flask.render_template('page_toc.html', page={
|
|
||||||
'path': path,
|
|
||||||
'title': path.split('/')[-1],
|
|
||||||
'toc': md.toc_tokens
|
|
||||||
})
|
|
||||||
|
|
||||||
@app.route('/preview/<path:path>')
|
@app.route('/preview/<path:path>')
|
||||||
def page_preview(path):
|
def page_preview(path):
|
||||||
fname = flask.safe_join('./data/pages', path) + '.md'
|
fname = flask.safe_join('./data/pages', path) + '.md'
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
{% extends 'page_base.html' %}
|
{% extends 'page_base.html' %}
|
||||||
|
|
||||||
{% block page_content %}
|
{% block page_content %}
|
||||||
|
<h1>{{ page.title }}</h1>
|
||||||
|
|
||||||
<img src="{{ url_for('image_view', name=page.path) }}">
|
<img src="{{ url_for('image_view', name=page.path) }}">
|
||||||
|
|
||||||
{{ page.content|safe }}
|
{{ page.content|safe }}
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
{% extends 'page_base.html' %}
|
{% extends 'page_base.html' %}
|
||||||
|
|
||||||
{% block page_content %}
|
{% block page_content %}
|
||||||
|
<h1>{{ page.title }}</h1>
|
||||||
|
|
||||||
<div class="admonition error">
|
<div class="admonition error">
|
||||||
There is no page with the name <em>{{ page.title }}</em>.
|
There is no page with the name <em>{{ page.title }}</em>.
|
||||||
</div>
|
</div>
|
||||||
|
@ -33,8 +33,6 @@
|
|||||||
</nav>
|
</nav>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<h1>{{ page.title }}</h1>
|
|
||||||
|
|
||||||
{% block page_content %}{% endblock %}
|
{% block page_content %}{% endblock %}
|
||||||
|
|
||||||
<script src="{{ url_for('static', filename='js/page.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/page.js') }}"></script>
|
||||||
|
@ -18,7 +18,21 @@
|
|||||||
|
|
||||||
{% extends 'page_base.html' %}
|
{% extends 'page_base.html' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{{ super() }}
|
||||||
|
<script>
|
||||||
|
function onClickExpCol(el) {
|
||||||
|
if (el.parentNode.nextElementSibling.matches('section')) {
|
||||||
|
var section = el.parentNode.nextElementSibling;
|
||||||
|
section.classList.toggle('collapsed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
{% block page_content %}
|
{% block page_content %}
|
||||||
|
<h1>{{ page.title }} <button class="expcol" onclick="onClickExpCol(this);">±</button></h1>
|
||||||
|
|
||||||
{{ page.content|safe }}
|
{{ page.content|safe }}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
@ -93,6 +93,8 @@ class WNMarkdown(markdown.Markdown):
|
|||||||
# Put it together
|
# Put it together
|
||||||
def convert(self, source):
|
def convert(self, source):
|
||||||
root = self.parse(source)
|
root = self.parse(source)
|
||||||
|
if root == '':
|
||||||
|
return ''
|
||||||
return self.serialise(root)
|
return self.serialise(root)
|
||||||
|
|
||||||
def detab(self, text):
|
def detab(self, text):
|
||||||
@ -187,7 +189,7 @@ class WrapSectionProcessor(markdown.treeprocessors.Treeprocessor):
|
|||||||
section = ET.Element('section')
|
section = ET.Element('section')
|
||||||
|
|
||||||
for child in list(root):
|
for child in list(root):
|
||||||
if child.tag in ('h1', 'h2', 'h3'):
|
if child.tag in ('h1', 'h2'):
|
||||||
if len(section) > 0:
|
if len(section) > 0:
|
||||||
root.insert(list(root).index(child), section)
|
root.insert(list(root).index(child), section)
|
||||||
section = ET.Element('section')
|
section = ET.Element('section')
|
||||||
|
@ -359,3 +359,19 @@ div.footnote {
|
|||||||
div.footnote ol {
|
div.footnote ol {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Expanding and collapsing */
|
||||||
|
|
||||||
|
button.expcol {
|
||||||
|
border: 1px solid #888a85;
|
||||||
|
font-size: 0.5rem;
|
||||||
|
padding: 3px;
|
||||||
|
vertical-align: middle;
|
||||||
|
opacity: 0.2;
|
||||||
|
}
|
||||||
|
h1:hover button.expcol, h2:hover button.expcol {
|
||||||
|
opacity: 1.0;
|
||||||
|
}
|
||||||
|
section.collapsed {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user