diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index d6be253..1ada016 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -67,6 +67,9 @@ jobs: - name: Install the package and requirements run: python -m pip install `ls dist/*.whl`[jupyter] + - name: Install the documentation requirements + run: python -m pip install env/requirements-docs.txt + - name: List installed packages run: python -m pip freeze diff --git a/doc/build.py b/doc/build.py index c90df46..7fd5061 100644 --- a/doc/build.py +++ b/doc/build.py @@ -2,14 +2,20 @@ # Distributed under the terms of the MIT License. # SPDX-License-Identifier: MIT """Trying out the API to build the site with a script instead of the CLI.""" +import functools import sys +from PIL import Image, ImageDraw, ImageFont import nene -if __name__ == "__main__": + +def build(config_file, verbose=True): + """ + Build the website from the sources + """ # Create a Rich Console for printing status updates. To omit the messages, # don't pass the console and style to the functions below. - console, style = nene.printing.make_console(verbose=True) + console, style = nene.printing.make_console(verbose=verbose) # So we know that we're using this script and not the "nene" app. console.rule() console.print(":snake: Building from the 'build.py' Python script.", style=style) @@ -17,7 +23,7 @@ # Generate the website structure based on the YAML configuration file. site, source_files, config, build = nene.build( - "config.yml", console=console, style=style + config_file, console=console, style=style ) # Render the HTML for the website. nene.render(site, config, build, console=console, style=style) @@ -26,7 +32,19 @@ nene.export( site, source_files["copy"], config["output_dir"], console=console, style=style ) + return config, source_files + + +if __name__ == "__main__": + config, source_files = build("config.yml", verbose=True) + console, style = nene.printing.make_console(verbose=True) # If the script is called with the "-s" command line option, serve the # website and open it in a browser. if "-s" in sys.argv: - nene.serve(config, source_files, console=console, style=style) + nene.serve( + config, + source_files, + console=console, + style=style, + rebuild=functools.partial(build, verbose=False), + ) diff --git a/doc/images/thumbnail/og_background.svg b/doc/images/thumbnail/og_background.svg new file mode 100644 index 0000000..c486228 --- /dev/null +++ b/doc/images/thumbnail/og_background.svg @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Nēnē + A no-frills static site generator + + + + leouieda/nene + + + diff --git a/env/requirements-docs.txt b/env/requirements-docs.txt new file mode 100644 index 0000000..7591324 --- /dev/null +++ b/env/requirements-docs.txt @@ -0,0 +1 @@ +pillow==10.3.* diff --git a/environment.yml b/environment.yml index 5588083..47cfb58 100644 --- a/environment.yml +++ b/environment.yml @@ -9,6 +9,7 @@ dependencies: - make - pip: - -r env/requirements-build.txt + - -r env/requirements-docs.txt - -r env/requirements-style.txt - -r env/requirements-test.txt - -e .[jupyter] diff --git a/nene/_api.py b/nene/_api.py index f47d47a..c848302 100644 --- a/nene/_api.py +++ b/nene/_api.py @@ -2,6 +2,7 @@ # Distributed under the terms of the MIT License. # SPDX-License-Identifier: MIT """Public functions used for building and serving the website.""" +import functools import itertools import logging import shutil @@ -269,7 +270,7 @@ def export(site, files_to_copy, output_dir, console=None, style=""): ) -def serve(config, source_files, port=None, console=None, style=""): +def serve(config, source_files, port=None, console=None, style="", rebuild=None): """ Serve the output folder with livereload and watch the sources for changes. @@ -290,6 +291,11 @@ def serve(config, source_files, port=None, console=None, style=""): printed. style : str Style string used to format console status messages. + rebuild : function or callable + A function or other callable that will be used to rebuild the website + when changes are detected. The function takes a single argument: the + config_file path. Defaults to building using the ``build``, ``render``, + and ``export`` functions with no console output. """ # Note: Can't really quite the livereload server since it sets the logging # level and handler when "serve" is called. So we can't set it before @@ -299,6 +305,11 @@ def serve(config, source_files, port=None, console=None, style=""): console, style = make_console(verbose=False) config_file = config["config_file"] + + if rebuild is None: + rebuild = _default_rebuild + rebuild = functools.partial(rebuild, config_file) + watch = [config_file, config["templates_dir"]] for category in source_files: watch.extend(source_files[category]) @@ -306,12 +317,6 @@ def serve(config, source_files, port=None, console=None, style=""): # from livereload watch = sorted([str(fname) for fname in watch]) - def rebuild(): - """Rebuild the website.""" - site, source_files, config, build_info = build(config_file) - render(site, config, build_info) - export(site, source_files["copy"], config["output_dir"]) - console.print(":eyes: Watching these source files for changes:", style=style) server = livereload.Server() for fname in watch: @@ -345,3 +350,10 @@ def rebuild(): # Clear the logger to avoid having livereload duplicate the # handlers causing multiple prints of the same log messages. livereload_logger.handlers.clear() + + +def _default_rebuild(config_file): + """Rebuild the website.""" + site, source_files, config, build_info = build(config_file) + render(site, config, build_info) + export(site, source_files["copy"], config["output_dir"])