diff --git a/CHANGES b/CHANGES index acba351..c83d9ab 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,12 @@ Changes ======= +1.0.0 (*2021-02-01*) +==================== + +- Support tables (not nested) +- Copy images and download files + 0.0.1 (*2021-01-11*) ==================== diff --git a/README.rst b/README.rst index a5b0af8..87e7cb0 100644 --- a/README.rst +++ b/README.rst @@ -14,6 +14,4 @@ good url in links. TODO ---- -- Table support -- Copy images - ablog support with RSS generation diff --git a/setup.py b/setup.py index 14153b4..0b16b71 100644 --- a/setup.py +++ b/setup.py @@ -28,7 +28,7 @@ with open("README.rst", "r") as fh: setup( name="sphinx_gemini_builder", - version="0.0.1", + version="1.0.0", url="https://procrastinator.nerv-project.eu/nerv-project/sphinx_gemini_builder", license="EUPL 1.2", author="Kujiu", diff --git a/sphinx_gemini_builder/__init__.py b/sphinx_gemini_builder/__init__.py index 98d09ed..737ed85 100644 --- a/sphinx_gemini_builder/__init__.py +++ b/sphinx_gemini_builder/__init__.py @@ -5,17 +5,22 @@ Build Gemini blog from Sphinx. """ -__version_info__ = (0, 0, 1) +__version_info__ = (1, 0, 0) __version__ = '.'.join([str(val) for val in __version_info__]) +from os import path from typing import Set, Dict, Any from urllib.parse import quote from sphinx.builders.text import TextBuilder -from sphinx.util import logging +from sphinx.util import logging, status_iterator +from sphinx.util.osutil import copyfile, ensuredir, relative_uri from sphinx.locale import __ from sphinx.application import Sphinx +from sphinx.environment.adapters.asset import ImageAdapter +from docutils import nodes +from docutils.utils import relative_path from .writer import GeminiTranslator, GeminiWriter @@ -39,13 +44,63 @@ class GeminiBuilder(TextBuilder): def __init__(self, app) -> None: super().__init__(app) self.baseurl = self.config.gemini_baseurl + self.images = [] def prepare_writing(self, docnames: Set[str]) -> None: self.writer = GeminiWriter(self) + def copy_image_files(self) -> None: + """ From native HTML builder """ + if self.images: + stringify_func = ImageAdapter(self.app.env).get_original_image_uri + for src in status_iterator( + self.images, __('copying images... '), "brown", + len(self.images), self.app.verbosity, + stringify_func=stringify_func): + destdir = path.dirname(src) + destdir = path.join(self.outdir, self.imagedir, destdir) + destdir = path.normpath(destdir) + + try: + ensuredir(destdir) + copyfile(path.join(self.srcdir, src), + path.join(self.outdir, self.imagedir, src)) + except Exception as err: + logger.warning(__('cannot copy image file %r: %s'), + path.join(self.srcdir, src), err) + + def copy_download_files(self) -> None: + """ From native HTML builder """ + def to_relpath(f: str) -> str: + return relative_path(self.srcdir, f) + + # copy downloadable files + if self.env.dlfiles: + ensuredir(path.join(self.outdir, '_downloads')) + for src in status_iterator(self.env.dlfiles, __('copying downloadable files... '), + "brown", len(self.env.dlfiles), self.app.verbosity, + stringify_func=to_relpath): + try: + dest = path.join(self.outdir, '_downloads', self.env.dlfiles[src][1]) + ensuredir(path.dirname(dest)) + copyfile(path.join(self.srcdir, src), dest) + except OSError as err: + logger.warning(__('cannot copy downloadable file %r: %s'), + path.join(self.srcdir, src), err) + + def write_doc(self, docname: str, doctree: nodes.document) -> None: + self.dlpath = relative_uri(self.get_target_uri(docname), '_downloads') + self.imgpath = path.dirname(docname) + super().write_doc(docname, doctree) + def get_target_uri(self, docname: str, typ: str = None) -> str: return self.baseurl + quote(docname) + self.out_suffix + def finish(self) -> None: + self.finish_tasks.add_task(self.copy_image_files) + self.finish_tasks.add_task(self.copy_download_files) + super().finish() + def setup(app: Sphinx) -> Dict[str, Any]: app.add_builder(GeminiBuilder) diff --git a/sphinx_gemini_builder/writer.py b/sphinx_gemini_builder/writer.py index 73e97da..9e03746 100644 --- a/sphinx_gemini_builder/writer.py +++ b/sphinx_gemini_builder/writer.py @@ -6,6 +6,7 @@ Writer for .gmi files """ from typing import cast, Iterable +import posixpath from docutils import writers, nodes from docutils.nodes import Element, Text, Node @@ -396,6 +397,7 @@ class GeminiTranslator(SphinxTranslator): else: self.add_link(uri) self.end_block() + self.builder.images.append(posixpath.join(self.builder.imgpath, uri)) raise nodes.SkipNode def visit_transition(self, node: Element) -> None: