diff --git a/.forgejo/workflows/publish.yml b/.forgejo/workflows/publish.yml index fde3206..53dd92f 100644 --- a/.forgejo/workflows/publish.yml +++ b/.forgejo/workflows/publish.yml @@ -7,9 +7,6 @@ jobs: runs-on: based-alpine steps: - uses: actions/checkout@v4 - - name: setup cache - id: uv-cache - uses: https://git.ficd.sh/ficd/uv-cache@v1 - name: build run: | uv sync diff --git a/.forgejo/workflows/test.yml b/.forgejo/workflows/test.yml deleted file mode 100644 index 2a05ee6..0000000 --- a/.forgejo/workflows/test.yml +++ /dev/null @@ -1,18 +0,0 @@ -# this workflow checks if the project can be built successfully. -# it also serves to test whether based-alpine and uv-cache are working properly. -# Unit tests will be added here eventually -on: [push] -jobs: - test-build: - runs-on: based-alpine - steps: - - name: checkout source - uses: actions/checkout@v4 - - name: setup cache - id: uv-cache - uses: https://git.ficd.sh/ficd/uv-cache@v1 - - name: sync and build - run: | - uv sync - uv build - uv run zona --version diff --git a/.kakrc b/.kakrc index 688bcbe..7a60b1f 100644 --- a/.kakrc +++ b/.kakrc @@ -15,10 +15,6 @@ define-command readme %{ root-edit README.md } -define-command kakrc %{ - root-edit .kakrc -} - # change working directory to the package hook global -once BufCreate .* %{ change-directory %exp{%opt{project_root}/src/zona} diff --git a/CHANGELOG.md b/CHANGELOG.md index 104815a..6e65c79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,14 +1,3 @@ -# 1.2.1 - -- Added `--version` flag to CLI. - -# 1.2.0 - -- Improved the appearance and semantics of post navigation buttons. - - Navigation now follows "newer/older" logic. -- Added hover symbols to page titles. -- Improved the styling of hover symbols and links. - # 1.1.0 - Major improvements to default stylesheet. diff --git a/README.md b/README.md index c3facfb..bd7eb9b 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,10 @@ If you don't want discovery, you can specify the project root as the first argument to `zona build`. You may specify a path for the output using the `--output/-o` flag. The `--draft/-d` flag includes draft posts in the output. +_Note: the previous build is _not_ cleaned before the new site is built. If +you've deleted some pages, you may need to remove the output directory before +rebuilding._ + ### Live Preview To make the writing process as frictionless as possible, zona ships with a live @@ -117,10 +121,9 @@ By default, the build outputs to a temporary directory. Use `-o/--output` to override this. **Note**: if the live preview isn't working as expected, try restarting the -server. If you change the configuration, the server must also be restarted. The -live preview uses the same function as `zona build` internally; this means that -the output is also written to disk --- a temporary directory by default, unless -overridden with `-o/--output`. +server. If you change the configuration or any templates, the server must also +be restarted. The live preview uses the same function as `zona build` +internally; this means that the output is also written to disk. #### Live Reload @@ -193,17 +196,13 @@ the packaged defaults. To apply a certain template to a page, set the `template` option in its [frontmatter](#frontmatter). The following public variables are made available to the template engine: -| Name | Description | -| ----------- | -------------------------------------------------------- | -| `content` | The content of this page. | -| `url` | The resolved URL of this page. | -| `metadata` | The frontmatter of this page (_merged with defaults_). | -| `header` | The sitemap header in HTML form. Can be `False`. | -| `footer` | The footer in HTML form. Can be `False`. | -| `is_post` | Whether this page is a post. | -| `newer` | URL of the newer post in the post list. | -| `older` | URL of the older post in the post list. | -| `post_list` | A sorted list of `Item` objects. Meant for internal use. | +| Name | Description | +| ---------- | ------------------------------------------------------ | +| `content` | The content of this page. | +| `url` | The resolved URL of this page. | +| `metadata` | The frontmatter of this page (_merged with defaults_). | +| `header` | The sitemap header in HTML form. Can be `False`. | +| `footer` | The footer in HTML form. Can be `False`. | #### Markdown Footer diff --git a/pyproject.toml b/pyproject.toml index f0c6b14..a66fa54 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "zona" -version = "1.2.1" +version = "1.1.0" description = "Opinionated static site generator." license = "BSD-3-Clause " license-files = ["LICENSE"] diff --git a/src/zona/builder.py b/src/zona/builder.py index bd2812b..27ff2ca 100644 --- a/src/zona/builder.py +++ b/src/zona/builder.py @@ -123,8 +123,6 @@ class ZonaBuilder: def _get_post_list(self) -> list[Item]: assert self.items - # sort according to date - # descending order post_list: list[Item] = sorted( [item for item in self.items if item.post], key=lambda item: item.metadata.date @@ -132,17 +130,17 @@ class ZonaBuilder: else date.min, reverse=True, ) - # number of posts # generate RSS here posts = len(post_list) - # link post chronology for i, item in enumerate(post_list): - # prev: older post - older = post_list[i + 1] if i + 1 < posts else None - # next: newer post - newer = post_list[i - 1] if i > 0 else None - item.older = older - item.newer = newer + prev = post_list[i - 1] if i > 0 else None + next = post_list[i + 1] if i < posts - 2 else None + item.previous = prev + item.next = next + return post_list + + def _build(self): + post_list = self._get_post_list() templater = Templater( config=self.config, diff --git a/src/zona/cli.py b/src/zona/cli.py index da15a22..4b48d3a 100644 --- a/src/zona/cli.py +++ b/src/zona/cli.py @@ -1,4 +1,3 @@ -from importlib.metadata import version as __version__ from pathlib import Path from typing import Annotated @@ -135,23 +134,8 @@ def serve( ) -def version_callback(value: bool): - if value: - print(f"Zona version: {__version__('zona')}") - raise typer.Exit() - - @app.callback() def main_entry( - version: Annotated[ # pyright: ignore[reportUnusedParameter] - bool | None, - typer.Option( - "--version", - callback=version_callback, - is_eager=True, - help="Print version info and exit.", - ), - ] = None, verbosity: Annotated[ str, typer.Option( diff --git a/src/zona/data/content/static/style.css b/src/zona/data/content/static/style.css index caa0eef..f02717e 100644 --- a/src/zona/data/content/static/style.css +++ b/src/zona/data/content/static/style.css @@ -1,5 +1,4 @@ :root { - --main-placeholder-color: #b14242; --main-text-color: #b4b4b4; --main-text-opaque-color: rgba(180, 180, 180, 0.8); --main-bg-color: #121212; @@ -34,101 +33,27 @@ header { .post-nav { font-family: monospace; - font-size: 0.95em; - white-space: nowrap; -} - -.post-nav .bar { - position: relative; - bottom: 0.05em; - display: inline-block; - width: 1px; - height: 0.8em; - background-color: currentColor; - vertical-align: middle; - margin: 0 0.3em; -} - -.post-nav .placeholder { - color: var(--main-placeholder-color); } .post-nav .symbol { color: var(--main-bullet-color); - margin: 0; - padding: 0; - display: inline; } -.site-logo.hover-symbol::before { - content: "~/"; +.post-nav a { + margin: 0 2px; } -.title.hover-symbol::before { - content: "$"; -} - -.hover-symbol { +.site-logo { color: inherit; - position: relative; font-weight: bold; text-decoration: none; - transition: color 0.15s ease; -} - -.hover-symbol::before { - font-family: monospace; - content: "#"; - position: absolute; - right: 100%; - margin-right: 0.25em; - top: 50%; - transform: translateY(-50%); - opacity: 0; - transition: opacity 0.15s ease, color 0.15s ease; - color: var(--main-text-color); -} - -.hover-symbol:hover::before { - opacity: 1; - color: var(--main-placeholder-color); -} -.hover-symbol:hover { - background-color: transparent; -} - -.toc ul { - font-family: monospace; - text-transform: lowercase; - margin: auto; - width: 50%; -} - -.toc ul ul { - padding-left: 1em; - margin-left: 1em; - /* list-style-type: "–– ";*/ -} -.toc ul ul ul { - padding-left: 1em; - margin-left: 1em; - /* list-style-type: "-- ";*/ + /* font-size: 1.75rem;*/ } .toclink { position: relative; text-decoration: none; color: inherit; - transition: color 0.15s ease; - text-transform: lowercase; - font-family: monospace; -} -.post-list a { - position: relative; - text-decoration: none; - transition: color 0.15s ease; - text-transform: lowercase; - font-family: monospace; } .toclink::before { @@ -139,16 +64,7 @@ header { top: 50%; transform: translateY(-50%); opacity: 0; - transition: opacity 0.15s ease, color 0.15s ease; - color: var(--main-link-color); -} - -.toclink:hover::before { - opacity: 1; - color: var(--main-placeholder-color); -} -.toclink:hover { - background-color: transparent; + transition: opacity 0.2s ease; } h1 .toclink::before { @@ -167,6 +83,13 @@ h4 .toclink::before { content: "###"; } +.toclink:hover::before { + opacity: 1; +} +.toclink:hover { + background-color: transparent; +} + /* h1, */ h2, h3, @@ -188,11 +111,6 @@ h1 { font-family: monospace; } -.title a { - color: inherit; - text-decoration: none; -} - article h1:first-of-type { margin-block-start: 1.67rem; } @@ -236,55 +154,40 @@ h6 { font-weight: bold; } -/*ul {*/ -/* list-style-type: disc;*/ -/*}*/ - ul { - list-style-type: "– "; -} -ul ul { - padding-left: 1em; - margin-left: 1em; - list-style-type: "+ "; -} -ul ul ul { - list-style-type: "~ "; -} -ul ul ul ul { - list-style-type: "• "; -} -ul ul ul ul ul { - list-style-type: "– "; -} -ul ul ul ul ul ul { - list-style-type: "+ "; -} -ul ul ul ul ul ul ul { - list-style-type: "~ "; -} -ul ul ul ul ul ul ul ul { - list-style-type: "• "; + list-style-type: disc; + /* or any other list style */ } li::marker { color: var(--main-bullet-color); + /* Change this to your desired color */ } a { color: var(--main-link-color); - text-decoration: underline; - text-decoration-color: rgba(0, 0, 0, 0); - text-underline-offset: 2px; + text-decoration: none; + position: relative; } -a { - transition: color 0.15s ease, text-decoration-color 0.15s ease; +a::after { + content: ""; + position: absolute; + left: 0; + bottom: -2px; + width: 100%; + height: 1px; + background-color: currentColor; + transform: scaleX(0); + transform-origin: center; + transition: transform 0.1s ease; } -a:hover { - text-decoration-color: var(--main-placeholder-color); - color: var(--main-bullet-color); +a:hover::after { + transform: scaleX(1); +} +a:has(> code)::after { + display: none; } max-width: 100%; @@ -521,3 +424,23 @@ caption { font-size: 0.8rem; color: var(--main-small-text-color); } + +a > code { + text-decoration: none; + color: var(--main-link-color); + position: relative; +} + +a:has(> code) { + text-decoration: none; + background: none; + /* position: static;*/ +} + +a:hover > code { + text-decoration: underline; +} + +a:hover:has(> code) { + background: none; +} diff --git a/src/zona/data/templates/post_list.html b/src/zona/data/templates/post_list.html index 6b0bdca..85e0be8 100644 --- a/src/zona/data/templates/post_list.html +++ b/src/zona/data/templates/post_list.html @@ -1,18 +1,20 @@ -{% extends "base.html" %} {% block content %} {% if metadata.show_title %} {% -include "title.html" %} {% endif %} +{% extends "base.html" %} {% block content %} + +{% if metadata.show_title %} +{% include "title.html" %} +{% endif %}
{{ content | safe }}
{% if post_list %} -
- -
+ {% endif %} {% endblock %} + diff --git a/src/zona/data/templates/post_nav.html b/src/zona/data/templates/post_nav.html index 1e96ff5..86ac330 100644 --- a/src/zona/data/templates/post_nav.html +++ b/src/zona/data/templates/post_nav.html @@ -1,11 +1,9 @@
- <{% if newer %}newr{% - else %}null{% endif %}{% if older %}oldr{% else %}null{% endif %}> + <{% if previous %}prev{% endif %}{% if previous and next %}|{% endif %}{% if next %}next{% endif + %}>
diff --git a/src/zona/data/templates/title.html b/src/zona/data/templates/title.html index 1541095..9753365 100644 --- a/src/zona/data/templates/title.html +++ b/src/zona/data/templates/title.html @@ -1,2 +1,2 @@ -

{{ metadata.title }}

+

{{ metadata.title }}

diff --git a/src/zona/models.py b/src/zona/models.py index 7f67015..d009476 100644 --- a/src/zona/models.py +++ b/src/zona/models.py @@ -23,8 +23,8 @@ class Item: type: ItemType | None = None copy: bool = True post: bool = False - newer: Item | None = None - older: Item | None = None + next: Item | None = None + previous: Item | None = None # @dataclass diff --git a/src/zona/templates.py b/src/zona/templates.py index 4529143..d5e0f22 100644 --- a/src/zona/templates.py +++ b/src/zona/templates.py @@ -27,6 +27,7 @@ def get_footer(template_dir: Path) -> str | None: return html_footer.read_text() +# TODO: add next/prev post button logic to posts # TODO: add a recent posts element that can be included elsewhere? class Templater: def __init__( @@ -78,11 +79,11 @@ class Templater: header=header, footer=footer, is_post=item.post, - newer=util.normalize_url(item.newer.url) - if item.newer + next=util.normalize_url(item.next.url) + if item.next else None, - older=util.normalize_url(item.older.url) - if item.older + previous=util.normalize_url(item.previous.url) + if item.previous else None, post_list=self.post_list, ) diff --git a/uv.lock b/uv.lock index c81743b..c00e364 100644 --- a/uv.lock +++ b/uv.lock @@ -509,7 +509,7 @@ wheels = [ [[package]] name = "zona" -version = "1.2.1" +version = "1.1.0" source = { editable = "." } dependencies = [ { name = "dacite" },