New: Image support

This commit is contained in:
Kujiu 2021-02-01 02:51:32 +01:00
parent dba8119eba
commit d60c947335
Signed by: kujiu
GPG key ID: ABBB2CAC6855599F
5 changed files with 66 additions and 5 deletions

View file

@ -2,6 +2,12 @@
Changes Changes
======= =======
1.0.0 (*2021-02-01*)
====================
- Support tables (not nested)
- Copy images and download files
0.0.1 (*2021-01-11*) 0.0.1 (*2021-01-11*)
==================== ====================

View file

@ -14,6 +14,4 @@ good url in links.
TODO TODO
---- ----
- Table support
- Copy images
- ablog support with RSS generation - ablog support with RSS generation

View file

@ -28,7 +28,7 @@ with open("README.rst", "r") as fh:
setup( setup(
name="sphinx_gemini_builder", name="sphinx_gemini_builder",
version="0.0.1", version="1.0.0",
url="https://procrastinator.nerv-project.eu/nerv-project/sphinx_gemini_builder", url="https://procrastinator.nerv-project.eu/nerv-project/sphinx_gemini_builder",
license="EUPL 1.2", license="EUPL 1.2",
author="Kujiu", author="Kujiu",

View file

@ -5,17 +5,22 @@
Build Gemini blog from Sphinx. Build Gemini blog from Sphinx.
""" """
__version_info__ = (0, 0, 1) __version_info__ = (1, 0, 0)
__version__ = '.'.join([str(val) for val in __version_info__]) __version__ = '.'.join([str(val) for val in __version_info__])
from os import path
from typing import Set, Dict, Any from typing import Set, Dict, Any
from urllib.parse import quote from urllib.parse import quote
from sphinx.builders.text import TextBuilder 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.locale import __
from sphinx.application import Sphinx 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 from .writer import GeminiTranslator, GeminiWriter
@ -39,13 +44,63 @@ class GeminiBuilder(TextBuilder):
def __init__(self, app) -> None: def __init__(self, app) -> None:
super().__init__(app) super().__init__(app)
self.baseurl = self.config.gemini_baseurl self.baseurl = self.config.gemini_baseurl
self.images = []
def prepare_writing(self, docnames: Set[str]) -> None: def prepare_writing(self, docnames: Set[str]) -> None:
self.writer = GeminiWriter(self) 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: def get_target_uri(self, docname: str, typ: str = None) -> str:
return self.baseurl + quote(docname) + self.out_suffix 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]: def setup(app: Sphinx) -> Dict[str, Any]:
app.add_builder(GeminiBuilder) app.add_builder(GeminiBuilder)

View file

@ -6,6 +6,7 @@ Writer for .gmi files
""" """
from typing import cast, Iterable from typing import cast, Iterable
import posixpath
from docutils import writers, nodes from docutils import writers, nodes
from docutils.nodes import Element, Text, Node from docutils.nodes import Element, Text, Node
@ -396,6 +397,7 @@ class GeminiTranslator(SphinxTranslator):
else: else:
self.add_link(uri) self.add_link(uri)
self.end_block() self.end_block()
self.builder.images.append(posixpath.join(self.builder.imgpath, uri))
raise nodes.SkipNode raise nodes.SkipNode
def visit_transition(self, node: Element) -> None: def visit_transition(self, node: Element) -> None: