7 Commits

Author SHA1 Message Date
beea0c80bf CSS: slightly tweak/specify the text size/height 2020-05-28 12:18:28 -05:00
ab977f7e81 header CSS tweaks 2020-05-28 12:18:04 -05:00
05f879ab80 display untitled-page paths as /path rather than path.md 2020-05-28 12:17:27 -05:00
059108c37b rewrite generate_parent_navs
* works on a path now, not a file location
* as such is sliiiiiightly easier to understand
* now also puts the current page in the nav
* fixed failing test where this caused an error (rather than 404) on
  non-existent paths
2020-05-28 12:09:59 -05:00
0993147dea give tables a bottom margin
otherwise they look bad, for instance, at the very end of the page, too
close to the "Last modified" text.
2020-05-28 08:20:24 -05:00
9e97cb097e requirements bump; tests pass 2020-05-28 08:13:55 -05:00
da2476bbda enable table support in the markdown parser 2020-04-05 10:25:46 -05:00
5 changed files with 97 additions and 49 deletions

View File

@@ -10,7 +10,7 @@ from tzlocal import get_localzone
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
bp = Blueprint('pages', __name__, url_prefix='/') bp = Blueprint('pages', __name__, url_prefix='/')
md = markdown.Markdown(extensions=['meta']) md = markdown.Markdown(extensions=['meta', 'tables'])
@bp.route('/', defaults={'path': 'index'}) @bp.route('/', defaults={'path': 'index'})
@@ -18,11 +18,11 @@ md = markdown.Markdown(extensions=['meta'])
def display_page(path): def display_page(path):
"""Get the file contents of the requested path and render the file.""" """Get the file contents of the requested path and render the file."""
resolved_path = resolve_page_file(path) resolved_path = resolve_page_file(path)
parent_navs = generate_parent_navs(resolved_path)
logger.debug("received request for path '%s', resolved to '%s'", path, resolved_path) logger.debug("received request for path '%s', resolved to '%s'", path, resolved_path)
try: try:
with app.open_instance_resource(resolved_path, 'r') as entry_file: with app.open_instance_resource(resolved_path, 'r') as entry_file:
logger.debug("file '%s' found", resolved_path) logger.debug("file '%s' found", resolved_path)
parent_navs = generate_parent_navs(path)
mtime = datetime.datetime.fromtimestamp(os.path.getmtime(entry_file.name), get_localzone()) mtime = datetime.datetime.fromtimestamp(os.path.getmtime(entry_file.name), get_localzone())
entry = entry_file.read() entry = entry_file.read()
except FileNotFoundError: except FileNotFoundError:
@@ -52,17 +52,19 @@ def resolve_page_file(path):
def generate_parent_navs(path): def generate_parent_navs(path):
"""Create a series of paths/links to navigate up from the given path.""" """Create a series of paths/links to navigate up from the given path."""
parent_dir = os.path.dirname(path) # derive additional path/location stuff based on path
if parent_dir == 'pages': resolved_path = resolve_page_file(path)
parent_dir = os.path.dirname(resolved_path)
parent_path = '/'.join(path[:-1].split('/')[:-1]) + '/'
logger.debug("path: '%s'; parent path: '%s'; resolved path: '%s'; parent dir: '%s'",
path, parent_path, resolved_path, parent_dir)
if path in ('index', '/'):
return [(app.config['TITLE_SUFFIX'], '/')] return [(app.config['TITLE_SUFFIX'], '/')]
elif path.endswith('index.md'):
# if we're on an index.md, don't link to ourselves as we're our own parent
return generate_parent_navs(parent_dir)
else: else:
parent_path = f'{parent_dir}/'.replace('pages/', '/', 1) with app.open_instance_resource(resolved_path, 'r') as entry_file:
resolved_parent_path = resolve_page_file(parent_path)
with app.open_instance_resource(resolved_parent_path, 'r') as entry_file:
entry = entry_file.read() entry = entry_file.read()
_ = Markup(md.convert(entry)) _ = Markup(md.convert(entry))
parent_name = " ".join(md.Meta.get('title')) if md.Meta.get('title') else os.path.basename(parent_dir) page_name = " ".join(md.Meta.get('title')) if md.Meta.get('title') else path
return generate_parent_navs(parent_dir) + [(parent_name, parent_path)] return generate_parent_navs(parent_path) + [(page_name, path)]

View File

@@ -13,6 +13,30 @@ h1,h2,h3,h4,h5,h6 {
color: #811610; color: #811610;
} }
h1 {
font-size: 2em;
}
h2 {
font-size: 1.5em;
}
h3 {
font-size: 1.25em;
}
h4 {
font-size: 1.17em;
}
h5 {
font-size: 1em;
}
h6 {
font-size: .83em;
}
a:link { a:link {
color: #222; color: #222;
font-weight: bold; font-weight: bold;
@@ -55,7 +79,10 @@ section.nav a {
} }
section.content { section.content {
font-size: 11pt;
padding: 0 1em; padding: 0 1em;
line-height: 1.5em;
} }
footer { footer {
@@ -64,3 +91,17 @@ footer {
color: #999; color: #999;
padding: 0 1em; padding: 0 1em;
} }
table {
border-collapse: collapse;
}
table, th, td {
padding: 5px;
border: 1px solid #222;
margin-bottom: 15px;
}
th {
background: #eee;
}

View File

@@ -5,34 +5,33 @@
# pip-compile --output-file=requirements/requirements-dev.txt requirements/requirements-dev.in # pip-compile --output-file=requirements/requirements-dev.txt requirements/requirements-dev.in
# #
attrs==19.3.0 # via pytest attrs==19.3.0 # via pytest
click==7.0 # via flask, pip-tools click==7.1.2 # via flask, pip-tools
coverage==5.0.3 # via pytest-cov coverage==5.1 # via pytest-cov
entrypoints==0.3 # via flake8 flake8==3.8.2 # via -r requirements/requirements-dev.in
flake8==3.7.9 # via -r requirements/requirements-dev.in flask==1.1.2 # via -r requirements/requirements.in
flask==1.1.1 # via -r requirements/requirements.in importlib-metadata==1.6.0 # via flake8, markdown, pluggy, pytest
importlib-metadata==1.5.0 # via pluggy, pytest
itsdangerous==1.1.0 # via flask itsdangerous==1.1.0 # via flask
jinja2==2.11.1 # via flask jinja2==2.11.2 # via flask
markdown==3.2.1 # via -r requirements/requirements.in markdown==3.2.2 # via -r requirements/requirements.in
markupsafe==1.1.1 # via jinja2 markupsafe==1.1.1 # via jinja2
mccabe==0.6.1 # via flake8 mccabe==0.6.1 # via flake8
more-itertools==8.2.0 # via pytest more-itertools==8.3.0 # via pytest
packaging==20.3 # via pytest packaging==20.4 # via pytest
pip-tools==4.5.1 # via -r requirements/requirements-dev.in pip-tools==5.2.0 # via -r requirements/requirements-dev.in
pluggy==0.13.1 # via pytest pluggy==0.13.1 # via pytest
py==1.8.1 # via pytest py==1.8.1 # via pytest
pycodestyle==2.5.0 # via flake8 pycodestyle==2.6.0 # via flake8
pyflakes==2.1.1 # via flake8 pyflakes==2.2.0 # via flake8
pyparsing==2.4.6 # via packaging pyparsing==2.4.7 # via packaging
pytest-cov==2.8.1 # via -r requirements/requirements-dev.in pytest-cov==2.9.0 # via -r requirements/requirements-dev.in
pytest==5.3.5 # via -r requirements/requirements-dev.in, pytest-cov pytest==5.4.2 # via -r requirements/requirements-dev.in, pytest-cov
pytz==2019.3 # via tzlocal pytz==2020.1 # via tzlocal
six==1.14.0 # via packaging, pip-tools six==1.15.0 # via packaging, pip-tools
tzlocal==2.0.0 # via -r requirements/requirements.in tzlocal==2.1 # via -r requirements/requirements.in
versioneer==0.18 # via -r requirements/requirements-dev.in versioneer==0.18 # via -r requirements/requirements-dev.in
wcwidth==0.1.8 # via pytest wcwidth==0.1.9 # via pytest
werkzeug==1.0.0 # via flask werkzeug==1.0.1 # via flask
zipp==3.1.0 # via importlib-metadata zipp==3.1.0 # via importlib-metadata
# The following packages are considered to be unsafe in a requirements file: # The following packages are considered to be unsafe in a requirements file:
# setuptools # pip

View File

@@ -4,15 +4,14 @@
# #
# pip-compile --output-file=requirements/requirements.txt requirements/requirements.in # pip-compile --output-file=requirements/requirements.txt requirements/requirements.in
# #
click==7.0 # via flask click==7.1.2 # via flask
flask==1.1.1 # via -r requirements/requirements.in flask==1.1.2 # via -r requirements/requirements.in
importlib-metadata==1.6.0 # via markdown
itsdangerous==1.1.0 # via flask itsdangerous==1.1.0 # via flask
jinja2==2.11.1 # via flask jinja2==2.11.2 # via flask
markdown==3.2.1 # via -r requirements/requirements.in markdown==3.2.2 # via -r requirements/requirements.in
markupsafe==1.1.1 # via jinja2 markupsafe==1.1.1 # via jinja2
pytz==2019.3 # via tzlocal pytz==2020.1 # via tzlocal
tzlocal==2.0.0 # via -r requirements/requirements.in tzlocal==2.1 # via -r requirements/requirements.in
werkzeug==1.0.0 # via flask werkzeug==1.0.1 # via flask
zipp==3.1.0 # via importlib-metadata
# The following packages are considered to be unsafe in a requirements file:
# setuptools

View File

@@ -48,20 +48,27 @@ def test_page_has_modified_timestamp(client):
def test_generate_page_navs_index(app): def test_generate_page_navs_index(app):
with app.app_context(): with app.app_context():
assert generate_parent_navs('pages/index.md') == [('incorporeal.org', '/')] assert generate_parent_navs('/') == [('incorporeal.org', '/')]
def test_generate_page_navs_alternate_index(app):
with app.app_context():
assert generate_parent_navs('index') == [('incorporeal.org', '/')]
def test_generate_page_navs_subdir_index(app): def test_generate_page_navs_subdir_index(app):
with app.app_context(): with app.app_context():
assert generate_parent_navs('pages/subdir/index.md') == [('incorporeal.org', '/')] assert generate_parent_navs('/subdir/') == [('incorporeal.org', '/'), ('/subdir/', '/subdir/')]
def test_generate_page_navs_subdir_real_page(app): def test_generate_page_navs_subdir_real_page(app):
with app.app_context(): with app.app_context():
assert generate_parent_navs('pages/subdir/page.md') == [('incorporeal.org', '/'), ('subdir', '/subdir/')] assert generate_parent_navs('/subdir/page') == [('incorporeal.org', '/'), ('/subdir/', '/subdir/'),
('Page', '/subdir/page')]
def test_generate_page_navs_subdir_with_title_parsing_real_page(app): def test_generate_page_navs_subdir_with_title_parsing_real_page(app):
with app.app_context(): with app.app_context():
assert generate_parent_navs('pages/subdir-with-title/page.md') == [('incorporeal.org', '/'), assert generate_parent_navs('/subdir-with-title/page') == [('incorporeal.org', '/'),
('SUB!', '/subdir-with-title/')] ('SUB!', '/subdir-with-title/'),
('/subdir-with-title/page', '/subdir-with-title/page')]