diff --git a/gronk.py b/gronk.py index 1c34989..cea315a 100755 --- a/gronk.py +++ b/gronk.py @@ -38,6 +38,10 @@ JINJA_TEMPLATE_INDEX = JINJA_ENV.get_template("index.html") JINJA_TEMPLATE_ARTICLE = JINJA_ENV.get_template("article.html") JINJA_TEMPLATE_PERMALINK = JINJA_ENV.get_template("permalink.html") +JINJA_TEMPLATE_BLOGINDEX = JINJA_ENV.get_template("blog_index.html") +JINJA_TEMPLATE_BLOG_INLINE_POST = JINJA_ENV.get_template("blog_inline_post.html") +JINJA_TEMPLATE_BLOG_FEED = JINJA_ENV.get_template("rss.xml") + LICENSE = None FILEMAP = None @@ -53,6 +57,11 @@ class FileMap: self.input_dir = Path(input_dir) self.output_dir = Path(output_dir) + def get_base_url(self): + props = self.get(self.input_dir.joinpath('readme.md')) + print(props) + return props['base_url'] + @staticmethod def _path_to_key(path): return str(path) @@ -112,7 +121,8 @@ class FileMap: include_index_entries=True): post = { 'title': filepath.name, - 'content_after_search': False, + 'blog': False, + 'content_after_search': None, 'automatic_index': True, 'search_bar': True, 'tags': [], @@ -125,6 +135,9 @@ class FileMap: file_pointer).to_dict().items(): post[key] = val + if post['content_after_search'] is None: + post['content_after_search'] = post['blog'] + if 'content' in post.keys(): post['content'] = render_markdown(post['content']) @@ -160,7 +173,7 @@ class FileMap: return entries def _get_file_properties(self, filepath): - post = {'title': filepath.name} + post = {'title': filepath.name, 'pub_date': False} if filepath.suffix == '.md': with open(filepath, encoding='utf-8') as file_pointer: @@ -257,6 +270,34 @@ def get_args(): ) return parser.parse_args() +def render_inline_blog_post(input_filepath): + """ + render markdown file as blog post for inlinining into blog index + returns html + """ + with open(input_filepath, encoding='utf-8') as file_pointer: + content = frontmatter.load(file_pointer).content + + properties = FILEMAP.get(input_filepath) + + html = render_markdown(content) + html = JINJA_TEMPLATE_BLOG_INLINE_POST.render( + license=LICENSE, + content=html, + lecture_slides=properties.get("lecture_slides"), + lecture_notes=properties.get("lecture_notes"), + uuid=properties.get("uuid"), + tags=properties.get("tags"), + author=properties.get("author"), + title=properties.get("title"), + published=properties.get("pub_date"), + base_url=FILEMAP.get_base_url(), + ) + + properties['dst_path']['html'].write_text(html) + + return html + def render_markdown_file(input_filepath): """ @@ -278,7 +319,9 @@ def render_markdown_file(input_filepath): uuid=properties.get("uuid"), tags=properties.get("tags"), author=properties.get("author"), - title=properties.get("title")) + title=properties.get("title"), + published=properties.get("pub_date") + ) properties['dst_path']['html'].write_text(html) @@ -476,22 +519,47 @@ def main(args): root_properties = FILEMAP.get(root) root_properties['dst_path']['raw'].mkdir(parents=True, exist_ok=True) + posts = [] + if root_properties['blog']: + for file in files: + props = FILEMAP.get(root.joinpath(file)) + post = { + 'title': props['title'], + 'link': props['dst_path']['web'], + 'pub_date': props.get('pub_date'), + 'description': render_inline_blog_post(root.joinpath(file)), + } + posts.append(post) + #pprint.pprint(root_properties) - html = JINJA_TEMPLATE_INDEX.render( + # render index + html = (JINJA_TEMPLATE_BLOGINDEX if root_properties['blog'] else JINJA_TEMPLATE_INDEX).render( gronk_commit=GRONK_COMMIT, title=root_properties.get('title', ''), content=root_properties.get('content', ''), content_after_search=root_properties['content_after_search'], automatic_index=root_properties['automatic_index'], search_bar=root_properties['search_bar'], + posts=posts, index_entries=[{ 'title': entry.get('title', ''), 'is_dir': entry.get('is_dir', False), 'path': str(entry.get('path', Path(''))), } for entry in root_properties.get('index_entries', '')], ) - root_properties['dst_path']['raw'].joinpath('index.html').write_text( - html) + root_properties['dst_path']['raw'].joinpath('index.html').write_text(html) + + # render rss feed if blog + if root_properties['blog']: + rss = JINJA_TEMPLATE_BLOG_FEED.render( + title=root_properties.get('title', ''), + description=root_properties.get('content', ''), + base_url=FILEMAP.get_base_url(), + link=f"{FILEMAP.get_base_url()}{root_properties['dst_path']['web']}", + language='en-GB', + posts=posts, + ) + root_properties['dst_path']['raw'].joinpath('feed.xml').write_text(rss) # render each file for file in files: diff --git a/readme.md b/readme.md index 0b06817..9da8ef5 100644 --- a/readme.md +++ b/readme.md @@ -57,13 +57,14 @@ To add custom content to a directory index, put it in a file called `readme.md` You can set the following frontmatter variables to customise the directory index of a directory: -| variable | default value | description | -|------------------------|-------------------|--------------------------------------------------------------------------------------------| -| `tags` | `[]` | list of tags, used by search and inherited by any notes and subdirectories | -| `uuid` | none | unique id to reference directory, used for permalinking | -| `content_after_search` | `false` | show custom content in `readme.md` after search bar and directory index | -| `automatic_index` | `true` | show the automatically generated directory index. required for search bar to function. | -| `search_bar` | `true` | show search bar to search directory items. requires `automatic_index` (enabled by default) | +| variable | default value | description | +|------------------------|----------------|--------------------------------------------------------------------------------------------| +| `blog` | `false` | enable [blog mode](#blog-mode) for this directory | +| `tags` | `[]` | list of tags, used by search and inherited by any notes and subdirectories | +| `uuid` | none | unique id to reference directory, used for permalinking | +| `content_after_search` | same as `blog` | show custom content in `readme.md` after search bar and directory index | +| `automatic_index` | `true` | show the automatically generated directory index. required for search bar to function. | +| `search_bar` | `true` | show search bar to search directory items. requires `automatic_index` (enabled by default) | ## Notes Metadata @@ -73,12 +74,21 @@ gronk reads the following YAML [frontmatter](https://jekyllrb.com/docs/front-mat | variable | description | |------------------|---------------------------------------------------------------------------------------| | `author` | The person(s) who wrote the article | +| `pub_date` | set the publish date of an article/post/note | | `tags` | A YAML list of tags which the article relates to - this is used for browsing and also | | `title` | The title of the article | | `uuid` | A unique identifier used for permalinks. | | `lecture_slides` | a list of paths pointing to lecture slides used while taking notes | | `lecture_notes` | a list of paths pointing to other notes used while taking notes | +## Blog Mode + +A directory can be turned into a blog by enabling blog mode. +This can be done by setting the `blog` variable to `true` in the `readme.md` [custom directory metadata](#custom-directory-index-and-metadata). + +Notes under this directory will be published to a blog, whose feed is accesible at `https://notes.alv.cx/notes//feed.xml`. + + ## Permalinks Permalinks are currently rather basic and requires JavaScript to be enabled on the local computer. diff --git a/templates/article.html b/templates/article.html index 1b5b4be..67f27db 100644 --- a/templates/article.html +++ b/templates/article.html @@ -32,6 +32,10 @@

uuid: {{ uuid }} (permalink)

{% endif %} +{% if published %} +

published: {{ published }}

+{% endif %} +

tags: [ {% for tag in tags %} {{ tag }}{% if loop.nextitem %},{% endif %} diff --git a/templates/blog_index.html b/templates/blog_index.html new file mode 100644 index 0000000..caadcf1 --- /dev/null +++ b/templates/blog_index.html @@ -0,0 +1,78 @@ +{% extends "base.html" %} + +{% block head %} + + + +{% endblock %} + +{% block content %} +

+ syntax highlighting based on Pygments' default + colors +

+

+ page generated by gronk +

+

+ rss feed +

+{% if license %} +
+ + License + +
{{ license }}
+
+{% endif %} +

{{ title }}

+ + {% if not content_after_search %} + {{ content|safe }} + + {% for post in posts %} + {{ post['description']|safe }} + {% endfor %} + {% endif %} + + {% if automatic_index %} +
+ +

List of posts

+
+ {% if search_bar %} +
+ +
+

+ Press (Shift+)Enter to open first result (in new tab) +

+ {% endif %} + + +
+ {% endif %} + + {% if content_after_search %} + {{ content|safe }} + + {% for post in posts %} + {{ post['description']|safe }} + {% endfor %} + {% endif %} + + + + +{% endblock %} diff --git a/templates/blog_inline_post.html b/templates/blog_inline_post.html new file mode 100644 index 0000000..14d393b --- /dev/null +++ b/templates/blog_inline_post.html @@ -0,0 +1,42 @@ +{% block content %} +

title: {{ title }}

+ {% if lecture_slides %} +

lecture_slides: [ + {% for slide in lecture_slides %} + {{ slide }}{% if loop.nextitem %},{% endif %} + {% endfor %} + ]

+ {% endif %} + {% if lecture_notes %} +

lecture_notes: [ + {% for note in lecture_notes %} + {{ note }}{% if loop.nextitem %},{% endif %} + {% endfor %} + ]

+ {% endif %} + + {% if uuid %} +

uuid: {{ uuid }} (permalink)

+ {% endif %} + + {% if published %} +

published: {{ published }}

+ {% endif %} + +

tags: [ + {% for tag in tags %} + {{ tag }}{% if loop.nextitem %},{% endif %} + {% endfor %} + ]

+ +

+ {% if author is string %} + written by: {{ author }} + {% elif author is iterable %} + written by: [ {% for auth in author %}{{ auth }}{% if loop.nextitem %}, {% endif %}{% endfor %} ] + {% endif %} +

+ {% block body_content %} + {{ content|safe }} + {% endblock %} +{% endblock %} diff --git a/templates/rss.xml b/templates/rss.xml new file mode 100644 index 0000000..99e992a --- /dev/null +++ b/templates/rss.xml @@ -0,0 +1,23 @@ + + + + + {{ title }} + {{ description }} + {{ language }} +{{ link }} + + +{% for post in posts %} + + {{ post['title']}} + {{ base_url }}{{ post['link'] }} + {% if post['pub_date'] %} + {{ post['pub_date'] }} + {% endif %} + + +{% endfor %} + + +