diff --git a/README.md b/README.md index df3c866..9ae4ef4 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,24 @@

zona

-[zona](https://git.ficd.sh/ficd/zona) is an _opinionated_ static site generator -written in Python. From a structured directory of Markdown content, zona builds -a simple static website. It's designed to get out of your way and let you focus -on writing. +[zona](https://sr.ht/~ficd/zona) is an _opinionated_ static site generator +written in Python. From a structured directory of Markdown content, zona +builds a simple static website. It's designed to get out of your way and +let you focus on writing. -**What do I mean by opinionated?** I built zona primarily for myself. I've tried -making it flexible by exposing as many variables as possible to the template -engine. However, if you're looking for something stable, complete, and fully -configurable, zona may not be for you. If you want a minimal Markdown blog and -are comfortable with modifying `jinja2` templates and CSS, then you're in luck. +**What do I mean by opinionated?** I built zona primarily for myself. I've +tried making it flexible by exposing as many variables as possible to the +template engine. However, if you're looking for something stable, +complete, and fully configurable, zona may not be for you. If you want a +minimal Markdown blog and are comfortable with modifying `jinja2` +templates and CSS, then you're in luck. -**Note:** This project is in early development, there are no versioned releases -yet, and breaking changes are likely. Versioned releases will be made and zona -will be published to PyPI once it's stable. zona was previously implemented in -Go; I decided to rewrite the project in Python. If you're interested in seeing -the previous codebase (which is feature incomplete), visit the -[zona-go](https://git.ficd.sh/ficd/zona-go) repository. +**Note:** This project is in early development, there are no versioned +releases yet, and breaking changes are likely. Versioned releases will be +made and zona will be published to PyPI once it's stable. zona was +previously implemented in Go; I decided to rewrite the project in Python. +If you're interested in seeing the previous codebase (which is feature +incomplete), visit the [~ficd/zona-go](https://git.sr.ht/~ficd/zona-go) +repository. For an example of a website built with zona, please see [ficd.sh](https://ficd.sh). @@ -29,7 +31,6 @@ For an example of a website built with zona, please see - [Getting Started](#getting-started) - [Building](#building) - [Live Preview](#live-preview) - - [Live Reload](#live-reload) - [How It Works](#how-it-works) - [Site Layout](#site-layout) - [Templates](#templates) @@ -59,15 +60,15 @@ For an example of a website built with zona, please see - Easily configurable sitemap header. - Site footer written in Markdown. - Smart site layout discovery. - - Blog posts are automatically discovered and rendered accordingly (can be - overridden in frontmatter). + - Blog posts are automatically discovered and rendered accordingly (can + be overridden in frontmatter). - Extended Markdown renderer: - Smart internal link resolution. - Syntax highlighting. - Includes Kakoune syntax and [Ashen] highlighting. - [Image labels](#image-labels). - - Many `python-markdown` extensions enabled, including footnotes, tables, - abbreviations, etc. + - Many `python-markdown` extensions enabled, including footnotes, + tables, abbreviations, etc. - LaTeX support. ## Installation @@ -76,7 +77,7 @@ zona is not yet packaged on PyPI. You may use `uv` to install it from this repository: ```sh -uv tool install 'git+https://git.ficd.sh/ficd/zona' +uv tool install 'git+https://git.sr.ht/~ficd/zona' ``` ## Usage @@ -86,78 +87,71 @@ available options and arguments._ ### Getting Started -To set up a new website, create a new directory and run `zona init` inside of -it. This creates the required directory structure and writes the default -configuration file. The default templates and default stylesheet are also -written. +To set up a new website, create a new directory and run `zona init` inside +of it. This creates the required directory structure and writes the +default configuration file. The default templates and default stylesheet +are also written. ### Building -To build the website, run `zona build`. The project root is discovered according -to the location of `config.yml`. By default, the output directory is called -`public`, and saved inside the root directory. +To build the website, run `zona build`. The project root is discovered +according to the location of `config.yml`. By default, the output +directory is called `public`, and saved inside the root directory. 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. +`--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._ +_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 -preview server. It spins up an HTTP server, meaning that internal links work -properly (this is not the case if you simply open the `.html` files in your -browser.) +To make the writing process as frictionless as possible, zona ships with a +live preview server. It spins up an HTTP server, meaning that internal +links work properly (this is not the case if you simply open the `.html` +files in your browser.) -Additionally, the server watches for changes to all source files, and rebuilds -the website when they're modified. _Note: the entire website is rebuilt — this -ensures that links are properly resolved._ +Additionally, the server watches for changes to all source files, and +rebuilds the website when they're modified. _Note: the entire website is +rebuilt — this ensures that links are properly resolved._ -Drafts are enabled by default in live preview. Use `--final/-f` to disable them. -By default, the build outputs to a temporary directory. Use `-o/--output` to -override this. +Optionally, live reloading of the browser is also provided. With this +feature (enabled by default), your browser will automatically refresh open +pages whenever the site is rebuilt. The live reloading requires JavaScript +support from the browser — this is why the feature is optional. -**Note**: if the live preview isn't working as expected, try restarting the -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. +To start a preview server, use `zona serve`. You can specify the root +directory as its first argument. Use the `--host` to specify a host name +(`localhost` by default) and `--port/-p` to specify a port (default: +`8000`). The `--no-live-reload/-n` disables the live browser reloading +(_automatic site rebuilds are not disabled_). -#### Live Reload +Drafts are enabled by default in live preview. Use `--final/-f` to disable +them. By default, the build outputs to a temporary directory. Use +`-o/--output` to override this. -Optionally, live reloading of the browser is also provided. With this feature -(enabled by default), your browser will automatically refresh open pages -whenever the site is rebuilt. The live reloading requires JavaScript support -from the browser — this is why the feature is optional. - -To start a preview server, use `zona serve`. You can specify the root directory -as its first argument. Use the `--host` to specify a host name (`localhost` by -default) and `--port/-p` to specify a port (default: `8000`). - -The `--live-reload/--no-live-reload` option overrides the value set in the -[config](#configuration) (`true` by default). _Automatic site rebuilds are not -affected_. - -If you are scrolled to the bottom of the page in the browser, and you extend the -height of the page by adding new content, you will automatically be scrolled to -the _new_ bottom after reloading. You may tune the tolerance threshold in the -[configuration](#configuration). +**Note**: if the live preview isn't working as expected, try restarting +the 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. #### How It Works -The basic idea is this: after a rebuild, the server needs to notify your browser -to refresh the open pages. We implement this using a small amount of JavaScript. -The server injects a tiny script into any HTML page it serves; which causes your -browser to open a WebSocket connection with the server. When the site is -rebuilt, the server notifies your browser via the WebSocket, which reloads the -page. +The basic idea is this: after a rebuild, the server needs to notify your +browser to refresh the open pages. We implement this using a small amount +of JavaScript. The server injects a tiny script into any HTML page it +serves; which causes your browser to open a WebSocket connection with the +server. When the site is rebuilt, the server notifies your browser via the +WebSocket, which reloads the page. Unfortunately, there is no way to implement this feature without using -JavaScript. **JavaScript is _only_ used for the live preview feature. The script -is injected by the server, and never written to the HTML files in the output -directory.** +JavaScript. **JavaScript is _only_ used for the live preview feature. The +script is injected by the server, and never written to the HTML files in +the output directory.** ### Site Layout @@ -170,30 +164,32 @@ templates/ public/ ``` -The **root** of the zona **project** _must_ contain the configuration file, -`config.yml`, and a directory called `content`. A directory called `templates` -is optional, and prioritized if it exists. `public` is the built site output — -it's recommended to add this path to your `.gitignore`. +The **root** of the zona **project** _must_ contain the configuration +file, `config.yml`, and a directory called `content`. A directory called +`templates` is optional, and prioritized if it exists. `public` is the +built site output — it's recommended to add this path to your +`.gitignore`. The `content` directory is the **root of the website**. Think of it as the -**content root**. For example, suppose your website is hosted at `example.com`. -`content/blog/index.md` corresponds to `example.com/blog`, +**content root**. For example, suppose your website is hosted at +`example.com`. `content/blog/index.md` corresponds to `example.com/blog`, `content/blog/my-post.md` becomes `example.com/blog/my-post`, etc. - Internal links are resolved **relative to the `content` directory.** - Templates are resolved relative to the `template` directory. Markdown files inside a certain directory (`content/blog` by default) are -automatically treated as _blog posts_. This means they are rendered with the -`page` template, and included in the `post_list`, which can be included in your -site using the `post_list` template. +automatically treated as _blog posts_. This means they are rendered with +the `page` template, and included in the `post_list`, which can be +included in your site using the `post_list` template. ### Templates The `templates` directory may contain any `jinja2` template files. You may -modify the existing templates or create your own. 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: +modify the existing templates or create your own. 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 | | ---------- | ------------------------------------------------------ | @@ -205,40 +201,43 @@ following public variables are made available to the template engine: #### Markdown Footer -The `templates` directory can contain a file called `footer.md`. If it exists, -it's parsed and rendered into HTML, then made available to other templates as -the `footer` variable. If `footer.md` is missing but `footer.html` exists, then -it's used instead. **Note: links are _not_ resolved in the footer.** +The `templates` directory can contain a file called `footer.md`. If it +exists, it's parsed and rendered into HTML, then made available to other +templates as the `footer` variable. If `footer.md` is missing but +`footer.html` exists, then it's used instead. **Note: links are _not_ +resolved in the footer.** ### Internal Link Resolution -When zona encounters links in Markdown documents, it attempts to resolve them as -internal links. Links beginning with `/` are resolved relative to the content -root; otherwise, they are resolved relative to the Markdown file. If the link -resolves to an existing file that is part of the website, it's replaced with an -appropriate web-server-friendly link. Otherwise, the link isn't changed. +When zona encounters links in Markdown documents, it attempts to resolve +them as internal links. Links beginning with `/` are resolved relative to +the content root; otherwise, they are resolved relative to the Markdown +file. If the link resolves to an existing file that is part of the +website, it's replaced with an appropriate web-server-friendly link. +Otherwise, the link isn't changed. -For example, suppose the file `blog/post1.md` has a link `./post2.md`. The HTML -output will contain the link `/blog/post2` (which corresponds to -`/blog/post2/index.html`). Link resolution is applied to _all_ internal links, -including those pointing to static resources like images. Links are only -modified if they point to a real file that's not included in the ignore list. +For example, suppose the file `blog/post1.md` has a link `./post2.md`. The +HTML output will contain the link `/blog/post2` (which corresponds to +`/blog/post2/index.html`). Link resolution is applied to _all_ internal +links, including those pointing to static resources like images. Links are +only modified if they point to a real file that's not included in the +ignore list. ### Syntax Highlighting -Zona uses [Pygments] to provide syntax highlighting for fenced code blocks. The -following Pygments plugins are included: +Zona uses [Pygments] to provide syntax highlighting for fenced code +blocks. The following Pygments plugins are included: -- [pygments-kakoune](https://codeberg.com/ficd/pygments-kakoune) - - A lexer providing for highlighting Kakoune code. Available under the `kak` - and `kakrc` aliases. -- [pygments-ashen](https://codeberg.com/ficd/ashen/tree/main/item/pygments/README.md) - - An implementation of the [Ashen](https://codeberg.com/ficd/ashen) theme for - Pygments. +- [pygments-kakoune](https://git.sr.ht/~ficd/pygments-kakoune) + - A lexer providing for highlighting Kakoune code. Available under the + `kak` and `kakrc` aliases. +- [pygments-ashen](https://git.sr.ht/~ficd/ashen/tree/main/item/pygments/README.md) + - An implementation of the [Ashen](https://git.sr.ht/~ficd/ashen) theme + for Pygments. If you want to use any external Pygments styles or lexers, they must be -available in zona's Python environment. For example, you can give zona access to -[Catppucin](https://github.com/catppuccin/python): +available in zona's Python environment. For example, you can give zona +access to [Catppucin](https://github.com/catppuccin/python): ```yaml # config.yml @@ -253,9 +252,9 @@ Then, run zona with the following `uv` command: uvx --with catppucin zona build ``` -Inline syntax highlighting is also provided via a `python-markdown` extension. -If you prefix inline code with a shebang followed by the language identifier, it -will be highlighted. For example: +Inline syntax highlighting is also provided via a `python-markdown` +extension. If you prefix inline code with a shebang followed by the +language identifier, it will be highlighted. For example: ``` `#!python print(f"I love {foobar}!", end="")` @@ -281,9 +280,10 @@ will be rendered as ### Image Labels -A feature unique to zona is **image labels**. They make it easy to annotate -images in your Markdown documents. The alt text Markdown element is rendered as -the label — with support for inline Markdown. Consider this example: +A feature unique to zona is **image labels**. They make it easy to +annotate images in your Markdown documents. The alt text Markdown element +is rendered as the label — with support for inline Markdown. Consider this +example: ```markdown ![This **image** has _markup_.](static/markdown.png) @@ -298,14 +298,14 @@ The above results in the following HTML: ``` The `image-container` class is provided as a convenience for styling. The -default stylesheet centers the label under the image. Note: _links_ inside image -captions are not currently supported. I am looking into a solution. +default stylesheet centers the label under the image. Note: _links_ inside +image captions are not currently supported. I am looking into a solution. ### Frontmatter -YAML frontmatter can be used to configure the metadata of documents. All of them -are optional. `none` is used when the option is unset. The following options are -available: +YAML frontmatter can be used to configure the metadata of documents. All +of them are optional. `none` is used when the option is unset. The +following options are available: | Key | Type & Default | Description | | ------------ | --------------------------------- | ------------------------------------------------------------------------------------------------------ | @@ -338,9 +338,10 @@ template: post_list Welcome to my blog! Please find a list of my posts below. ``` -Setting `post: false` is necessary because, by default, all documents inside -`content/blog` are considered to be posts unless explicitly disabled in the -frontmatter. We don't want the post list to list _itself_ as a post. +Setting `post: false` is necessary because, by default, all documents +inside `content/blog` are considered to be posts unless explicitly +disabled in the frontmatter. We don't want the post list to list _itself_ +as a post. Then, you'd create `content/blog/my-post.md` and populate it: @@ -351,32 +352,32 @@ date: July 5, 2025 --- ``` -Because `my-post` is inside the `blog` directory, `post: true` is implied. If -you wanted to put it somewhere outside `blog`, you would need to set +Because `my-post` is inside the `blog` directory, `post: true` is implied. +If you wanted to put it somewhere outside `blog`, you would need to set `post: true` for it to be included in the post list. ## Configuration -Zona is configured in YAML format. The configuration file is called `config.yml` -and it **must** be located in the root of the project — in the same directory as -`content` and `templates`. +Zona is configured in YAML format. The configuration file is called +`config.yml` and it **must** be located in the root of the project — in +the same directory as `content` and `templates`. -Your configuration will be merged with the defaults. `zona init` also writes a -copy of the default configuration to the correct location. If it exists, you'll -be prompted before overwriting it. +Your configuration will be merged with the defaults. `zona init` also +writes a copy of the default configuration to the correct location. If it +exists, you'll be prompted before overwriting it. -**Note:** Currently, not every configuration value is actually used. Only the -useful settings are listed here. +**Note:** Currently, not every configuration value is actually used. Only +the useful settings are listed here. Please see the default configuration: ```yaml -base_url: / sitemap: Home: / ignore: - .marksman.toml markdown: + image_labels: true tab_length: 2 syntax_highlighting: enabled: true @@ -384,60 +385,49 @@ markdown: wrap: false links: external_new_tab: true -build: - clean_output_dir: true - include_drafts: false blog: dir: blog -server: - reload: - enabled: true - scroll_tolerance: 100 ``` -| Name | Description | -| -------------------------------------- | ----------------------------------------------------------------------------------------------- | -| `sitemap` | Sitemap dictionary. See [Sitemap](#sitemap). | -| `ignore` | List of paths to ignore. See [Ignore List](#ignore-list). | -| `markdown.tab_length` | How many spaces should be considered an indentation level. | -| `markdown.syntax_highlighting.enabled` | Whether code should be highlighted. | -| `markdown.syntax_highlighting.theme` | [Pygments] style for highlighting. | -| `markdown.syntax_highlighting.wrap` | Whether the resulting code block should be word wrapped. | -| `markdown.links.external_new_tab` | Whether external links should be opened in a new tab. | -| `build.clean_output_dir` | Whether previous build artifacts should be cleared when building. Recommended to leave this on. | -| `build.include_drafts` | Whether drafts should be included by default. | -| `blog.dir` | Name of a directory relative to `content/` whose children are automatically considered posts. | -| `server.reload.enabled` | Whether the preview server should use [live reload](#live-preview). | -| `server.reload.scroll_tolerance` | The distance, in pixels, from the bottom to still count as "scrolled to bottom". | +| Name | Description | +| -------------------------------------- | --------------------------------------------------------------------------------------------- | +| `sitemap` | Sitemap dictionary. See [Sitemap](#sitemap). | +| `ignore` | List of paths to ignore. See [Ignore List](#ignore-list). | +| `markdown.tab_length` | How many spaces should be considered an indentation level. | +| `markdown.syntax_highlighting.enabled` | Whether code should be highlighted. | +| `markdown.syntax_highlighting.theme` | [Pygments] style for highlighting. | +| `markdown.syntax_highlighting.wrap` | Whether the resulting code block should be word wrapped. | +| `markdown.links.external_new_tab` | Whether external links should be opened in a new tab. | +| `blog.dir` | Name of a directory relative to `content/` whose children are automatically considered posts. | ### Sitemap -You can define a sitemap in the configuration file. This is a list of links that -will be rendered at the top of every page. The `sitemap` is a dictionary of -`string` to `string` pairs, where each key is the displayed text of the link, -and the value if the `href`. Consider this example: +You can define a sitemap in the configuration file. This is a list of +links that will be rendered at the top of every page. The `sitemap` is a +dictionary of `string` to `string` pairs, where each key is the displayed +text of the link, and the value if the `href`. Consider this example: ```yaml sitemap: Home: / About: /about Blog: /blog - Git: https://git.ficd.sh/ficd + Git: https://git.sr.ht/~ficd ``` ### Ignore List -You can set a list of glob patterns in the [configuration](#configuration) that -should be ignored by zona. This is useful because zona makes a copy of _every_ -file it encounters inside the `content` directory, regardless of its type. The -paths must be relative to the `content` directory. +You can set a list of glob patterns in the [configuration](#configuration) +that should be ignored by zona. This is useful because zona makes a copy +of _every_ file it encounters inside the `content` directory, regardless +of its type. The paths must be relative to the `content` directory. ### Drafts -zona allows you to begin writing content without including it in the final build -output. If you set `draft: true` in a page's frontmatter, it will be marked as a -draft. Drafts are completely excluded from `zona build` and `zona serve` unless -the `--draft` flag is specified. +zona allows you to begin writing content without including it in the final +build output. If you set `draft: true` in a page's frontmatter, it will be +marked as a draft. Drafts are completely excluded from `zona build` and +`zona serve` unless the `--draft` flag is specified. -[Ashen]: https://codeberg.com/ficd/ashen +[Ashen]: https://sr.ht/~ficd/ashen [Pygments]: https://pygments.org/ diff --git a/src/zona/cli.py b/src/zona/cli.py index a7e2dd5..1d32c4c 100644 --- a/src/zona/cli.py +++ b/src/zona/cli.py @@ -95,15 +95,14 @@ def serve( bool, typer.Option("--final", "-f", help="Don't include drafts."), ] = False, - live_reload: Annotated[ - bool | None, + no_live_reload: Annotated[ + bool, typer.Option( - "--live-reload/--no-live-reload", - "-l/-L", - help="Automatically reload web preview. Overrides config.", - show_default=False, + "--no-live-reload", + "-n", + help="Don't automatically reload web preview.", ), - ] = None, + ] = False, ): """ Build the website and start a live preview server. @@ -116,17 +115,13 @@ def serve( print("Preview without drafts.") else: print("Preview with drafts.") - if live_reload is None: - reload = None - else: - reload = live_reload server.serve( root=root, output=output, draft=not final, host=host, port=port, - user_reload=reload, + live_reload=not no_live_reload, ) diff --git a/src/zona/config.py b/src/zona/config.py index cc56ec2..4bd7a42 100644 --- a/src/zona/config.py +++ b/src/zona/config.py @@ -58,17 +58,6 @@ class BuildConfig: include_drafts: bool = False -@dataclass -class ReloadConfig: - enabled: bool = True - scroll_tolerance: int = 100 - - -@dataclass -class ServerConfig: - reload: ReloadConfig = field(default_factory=ReloadConfig) - - IGNORELIST = [".marksman.toml"] @@ -82,7 +71,6 @@ class ZonaConfig: markdown: MarkdownConfig = field(default_factory=MarkdownConfig) build: BuildConfig = field(default_factory=BuildConfig) blog: BlogConfig = field(default_factory=BlogConfig) - server: ServerConfig = field(default_factory=ServerConfig) @classmethod def from_file(cls, path: Path) -> "ZonaConfig": diff --git a/src/zona/data/server/inject.js b/src/zona/data/server/inject.js deleted file mode 100644 index bc00dde..0000000 --- a/src/zona/data/server/inject.js +++ /dev/null @@ -1,25 +0,0 @@ -(() => { - // if user at the bottom before reload, scroll to new bottom - if (localStorage.getItem("wasAtBottom") === "1") { - localStorage.removeItem("wasAtBottom"); - window.addEventListener("load", () => { - requestAnimationFrame(() => { - window.scrollTo(0, document.body.scrollHeight); - }); - }); - } - - const ws = new WebSocket("__SOCKET_ADDRESS__"); - const tol = __SCROLL_TOLERANCE__; - ws.onmessage = event => { - if (event.data === "reload") { - // store flag if user currently at bottom - const nearBottom = window.innerHeight + window.scrollY - >= document.body.scrollHeight - tol; - if (nearBottom) { - localStorage.setItem("wasAtBottom", "1"); - } - location.reload(); - } - }; -})(); diff --git a/src/zona/server.py b/src/zona/server.py index 23c4c0b..fa0c033 100644 --- a/src/zona/server.py +++ b/src/zona/server.py @@ -13,7 +13,6 @@ from rich import print from watchdog.events import FileSystemEvent, FileSystemEventHandler from watchdog.observers import Observer -from zona import util from zona.builder import ZonaBuilder from zona.log import get_logger from zona.websockets import WebSocketServer @@ -21,23 +20,18 @@ from zona.websockets import WebSocketServer logger = get_logger() -def make_reload_script( - host: str, port: int, scroll_tolerance: int -) -> str: +def make_reload_script(host: str, port: int) -> str: """Generates the JavaScript that must be injected into HTML pages for the live reloading to work.""" - js = util.get_resource("server/inject.js").contents - js = util.minify_js(js) - address = f"ws://{host}:{port}" - for placeholder, value in ( - ("__SOCKET_ADDRESS__", address), - ("__SCROLL_TOLERANCE__", scroll_tolerance), - ): - if placeholder not in js: - raise ValueError( - f"{placeholder} missing from reload script template!" - ) - js = js.replace(placeholder, str(value)) - return f"" + return f""" + +""" def make_handler_class(script: str): @@ -177,13 +171,12 @@ def serve( draft: bool = True, host: str = "localhost", port: int = 8000, - user_reload: bool | None = None, + live_reload: bool = True, ): """Serve preview website with live reload and automatic rebuild.""" # create temp dir, automatic cleanup with tempfile.TemporaryDirectory() as tmp: builder = ZonaBuilder(root, Path(tmp), draft) - config = builder.config # initial site build builder.build() # use discovered paths if none provided @@ -192,21 +185,13 @@ def serve( if root is None: root = builder.layout.root - # use config value unless overridden by user - reload = config.server.reload.enabled - if user_reload is not None: - reload = user_reload - if reload: - print("Live reloading is enabled.") - # spin up websocket server for live reloading + # spin up websocket server for live reloading + if live_reload: ws_port = port + 1 ws_server = WebSocketServer(host, ws_port) ws_server.start() # generate reload script for injection - scroll_tolerance = config.server.reload.scroll_tolerance - reload_script = make_reload_script( - host, ws_port, scroll_tolerance - ) + reload_script = make_reload_script(host, ws_port) # generate handler with reload script as attribute handler = make_handler_class(reload_script) else: diff --git a/src/zona/util.py b/src/zona/util.py index 2d5c514..7e80500 100644 --- a/src/zona/util.py +++ b/src/zona/util.py @@ -1,5 +1,4 @@ import fnmatch -import re import string from importlib import resources from importlib.resources.abc import Traversable @@ -13,15 +12,6 @@ class ZonaResource(NamedTuple): contents: str -def get_resource(path: str) -> ZonaResource: - """Load the packaged resource in data/path""" - file = resources.files("zona").joinpath("data", path) - if file.is_file(): - return ZonaResource(name=path, contents=file.read_text()) - else: - raise FileNotFoundError(f"{path} is not a valid Zona resource!") - - def get_resources(subdir: str) -> list[ZonaResource]: """Load the packaged resources in data/subdir""" out: list[ZonaResource] = [] @@ -75,28 +65,11 @@ def normalize_url(url: str) -> str: return url -def should_ignore(path: Path, patterns: list[str], base: Path) -> bool: +def should_ignore( + path: Path, patterns: list[str], base: Path +) -> bool: rel_path = path.relative_to(base) return any( - fnmatch.fnmatch(str(rel_path), pattern) for pattern in patterns + fnmatch.fnmatch(str(rel_path), pattern) + for pattern in patterns ) - - -MINIFY_JS_PATTERN = re.compile( - r""" - //.*?$ | - /\*.*?\*/ | - \s+ - """, - re.MULTILINE | re.DOTALL | re.VERBOSE, -) - - -def minify_js(js: str) -> str: - """Naively minifies JavaScript by stripping comments and whitespace.""" - return MINIFY_JS_PATTERN.sub( - # replace whitespace with single space, - # strip comments - lambda m: " " if m.group(0).isspace() else "", - js, - ).strip()