Compare commits
No commits in common. "276a77b67e6b35caf9a19e92d70d5b609b2011a3" and "c43053f3455ec0ba324a059a3d1c86f219c24b62" have entirely different histories.
276a77b67e
...
c43053f345
|
@ -1,69 +0,0 @@
|
||||||
"""
|
|
||||||
Logic for operations that depend on a whole collection of documents.
|
|
||||||
"""
|
|
||||||
import os
|
|
||||||
|
|
||||||
from redstring.parser import load, TagOptions, DocumentTag, TabOptions, DocumentTab, Document
|
|
||||||
|
|
||||||
|
|
||||||
def generate_index_document(directory: str) -> Document:
|
|
||||||
"""
|
|
||||||
Generate a document describing a document collection.
|
|
||||||
"""
|
|
||||||
categories: dict = {}
|
|
||||||
|
|
||||||
for filename in os.listdir(directory):
|
|
||||||
with open(os.path.join(directory, filename)) as f:
|
|
||||||
document: Document = load(f)
|
|
||||||
|
|
||||||
# Check if this document specifies a tab, and create it if necessary.
|
|
||||||
category = document.get_tag('category')
|
|
||||||
if not category:
|
|
||||||
category = 'index'
|
|
||||||
if category not in categories:
|
|
||||||
categories[category] = {}
|
|
||||||
category_tab = categories[category]
|
|
||||||
|
|
||||||
# Check if this document specifies a topic, and create it if necessary.
|
|
||||||
topic = document.get_tag('topic')
|
|
||||||
if not topic:
|
|
||||||
topic = 'uncategorized'
|
|
||||||
if '.' in topic:
|
|
||||||
topic, subtopic = topic.split('.', maxsplit=1)
|
|
||||||
else:
|
|
||||||
subtopic = None
|
|
||||||
if topic not in category_tab:
|
|
||||||
category_tab[topic] = []
|
|
||||||
topic_tag = category_tab[topic]
|
|
||||||
|
|
||||||
# Save the title and id.
|
|
||||||
doc_id = document.get_tag('id').value
|
|
||||||
if doc_title_tag := document.get_tag('title'):
|
|
||||||
doc_title = doc_title_tag.value
|
|
||||||
else:
|
|
||||||
doc_title = None
|
|
||||||
|
|
||||||
topic_tag.append((doc_id, doc_title))
|
|
||||||
|
|
||||||
# Build an index document
|
|
||||||
def document_link(info):
|
|
||||||
doc_id, doc_title = info
|
|
||||||
return (
|
|
||||||
f'<a href="/doc/{doc_id}">{doc_title} ({doc_id})</a>'
|
|
||||||
if doc_title else
|
|
||||||
f'<a href="/doc/{doc_id}">{doc_id}</a>'
|
|
||||||
)
|
|
||||||
|
|
||||||
built_tabs: list = []
|
|
||||||
for category in sorted(categories.keys()):
|
|
||||||
built_tags: list = []
|
|
||||||
|
|
||||||
for topic in sorted(categories[category].keys()):
|
|
||||||
docs = sorted(categories[category][topic], key=lambda x: x[0])
|
|
||||||
doc_links = map(document_link, docs)
|
|
||||||
value = '- ' + '<br>- '.join(doc_links)
|
|
||||||
built_tags.append(DocumentTag(topic, value, TagOptions(), []))
|
|
||||||
|
|
||||||
built_tabs.append(DocumentTab(category, built_tags, TabOptions()))
|
|
||||||
|
|
||||||
return Document(built_tabs)
|
|
|
@ -130,12 +130,6 @@ class DocumentTab:
|
||||||
self.tags: List[DocumentTag] = tags
|
self.tags: List[DocumentTag] = tags
|
||||||
self.options: TabOptions = options
|
self.options: TabOptions = options
|
||||||
|
|
||||||
def get_tag(self, name: str):
|
|
||||||
for tag in self.tags:
|
|
||||||
if tag.name == name:
|
|
||||||
return tag
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
class Document:
|
class Document:
|
||||||
"""
|
"""
|
||||||
|
@ -147,19 +141,6 @@ class Document:
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
return self.tabs.__iter__()
|
return self.tabs.__iter__()
|
||||||
|
|
||||||
def get_tab(self, name: str):
|
|
||||||
for tab in self.tabs:
|
|
||||||
if tab.name == name:
|
|
||||||
return tab
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_tag(self, name: str):
|
|
||||||
for tab in self.tabs:
|
|
||||||
for tag in tab.tags:
|
|
||||||
if tag.name == name:
|
|
||||||
return tag
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Parsing functions
|
# Parsing functions
|
||||||
|
|
|
@ -4,17 +4,8 @@ Logic for serving a collection of documents through a web frontend.
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from flask import (
|
from flask import Flask, redirect, url_for, current_app, render_template
|
||||||
abort,
|
|
||||||
current_app,
|
|
||||||
Flask,
|
|
||||||
redirect,
|
|
||||||
render_template,
|
|
||||||
safe_join,
|
|
||||||
url_for,
|
|
||||||
)
|
|
||||||
|
|
||||||
from redstring.library import generate_index_document
|
|
||||||
from redstring.parser import load
|
from redstring.parser import load
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,18 +21,9 @@ def root():
|
||||||
|
|
||||||
@app.route('/index/')
|
@app.route('/index/')
|
||||||
def index():
|
def index():
|
||||||
document = generate_index_document(current_app.config['root'])
|
with open('scratch/test.json') as f:
|
||||||
return render_template('doc.jinja', document=document, index=True)
|
document = load(f)
|
||||||
|
return render_template('doc.jinja', document=document)
|
||||||
|
|
||||||
@app.route('/doc/<document_id>')
|
|
||||||
def document(document_id):
|
|
||||||
doc_path = safe_join(current_app.config['root'], f'{document_id}.json')
|
|
||||||
if not os.path.isfile(doc_path):
|
|
||||||
return abort(404)
|
|
||||||
with open(doc_path) as f:
|
|
||||||
doc = load(f)
|
|
||||||
return render_template('doc.jinja', document=doc, index=False)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
|
@ -24,29 +24,20 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tabs setup */
|
/* Tabs setup */
|
||||||
div#tabs {
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
div.tab {
|
div.tab {
|
||||||
|
display: inline-block;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
background-color: #333;
|
background-color: #333;
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-color: #888;
|
border-color: #888;
|
||||||
border-width: 2px 2px 0 2px;
|
border-width: 2px 2px 0 2px;
|
||||||
border-radius: 10px 10px 0px 0px;
|
border-radius: 10px 10px 0px 0px;
|
||||||
margin: 0 4px;
|
margin: 0 0 0 4px;
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #888;
|
color: #888;
|
||||||
user-select: none
|
|
||||||
}
|
|
||||||
div.tab a {
|
|
||||||
color: #888;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
div.tab-content {
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
user-select: none
|
||||||
}
|
}
|
||||||
div.tab-down {
|
div.tab-down {
|
||||||
background-color: #333;
|
background-color: #333;
|
||||||
|
@ -56,7 +47,8 @@
|
||||||
top: 2px;
|
top: 2px;
|
||||||
}
|
}
|
||||||
div.tab-right {
|
div.tab-right {
|
||||||
margin-left: auto;
|
float: right;
|
||||||
|
margin: 0 4px 0 0;
|
||||||
}
|
}
|
||||||
div.tab-page {
|
div.tab-page {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
|
@ -31,7 +31,7 @@ window.onload = function () {
|
||||||
{% endblock page_scripts %}
|
{% endblock page_scripts %}
|
||||||
|
|
||||||
{% macro make_content_tab(tab, selected) -%}
|
{% macro make_content_tab(tab, selected) -%}
|
||||||
<div id="{{ tab.name }}" class="tab tab-content{% if selected %} tab-down{% endif %}{% if index %} tab-right{% endif %}" onclick="javascript:selectTab('{{ tab.name }}')">{{ tab.name }}</div>
|
<div id="{{ tab.name }}" class="tab tab-content{% if selected %} tab-down{% endif %}" onclick="javascript:selectTab('{{ tab.name }}')">{{ tab.name }}</div>
|
||||||
{%- endmacro %}
|
{%- endmacro %}
|
||||||
|
|
||||||
{% macro make_tab_page(tab, selected) %}
|
{% macro make_tab_page(tab, selected) %}
|
||||||
|
@ -64,6 +64,6 @@ window.onload = function () {
|
||||||
|
|
||||||
{# TODO: tab.priority and tab.private support #}
|
{# TODO: tab.priority and tab.private support #}
|
||||||
{% block page_content %}
|
{% block page_content %}
|
||||||
<div id="tabs">{% for tab in document %}{{ make_content_tab(tab, loop.first) }}{% endfor %}{% if not index %}<div id="index" class="tab tab-right"><a href="/index/">index</a></div>{% endif %}</div>
|
{% for tab in document %}{{ make_content_tab(tab, loop.first) }}{% endfor %}<a href="/index/"><div id="index" class="tab tab-right">index</div></a>
|
||||||
{% for tab in document %}{{ make_tab_page(tab, loop.first) }}{% endfor %}
|
{% for tab in document %}{{ make_tab_page(tab, loop.first) }}{% endfor %}
|
||||||
{% endblock page_content %}
|
{% endblock page_content %}
|
Loading…
Reference in New Issue