sphinx_galleria/sphinx_galleria/directive.py

183 lines
5.7 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Galleria directive
"""
import uuid
import json
from docutils import nodes
from docutils.parsers.rst import Directive
import docutils.parsers.rst.directives as directives
from sphinx.writers.html import HTMLTranslator
from sphinx.writers.latex import LaTeXTranslator
from sphinx.writers.texinfo import TexinfoTranslator
from sphinx.writers.text import TextTranslator
from sphinx.writers.manpage import ManualPageTranslator
from sphinx.util.osutil import relative_uri
from sphinx.locale import _
class galleria(nodes.General, nodes.Element):
pass
def html_visit_galleria(self: HTMLTranslator, node: galleria) -> None:
self.body.append(
"<div id='%s' class='%s' style='width: %s; height: %s;'>" % (
node['options']['galleria'],
node['class'] + ' align-%s sphinxgalleria-core' %
node['options']['align'],
node['options']['width'],
node['options']['height'],
)
)
if len(node['images']) > 0:
self.body.append("<figure><div class='row'>")
self.body.append("<img src='%s' title='%s' alt='%s'>" % (
node['images'][0]['path'],
node['images'][0]['title'],
node['images'][0]['alt']
))
self.body.append('</div></figure>')
for img in node['images']:
img['path'] = relative_uri(
self.builder.get_target_uri(self.builder.current_docname),
img['path']
)
img['thumb'] = relative_uri(
self.builder.get_target_uri(self.builder.current_docname),
img['thumb']
)
self.body.append(
"</div><script type='module'>" +
"import {SphinxGalleria} from './%s';\n" %
relative_uri(
self.builder.get_target_uri(self.builder.current_docname),
'_static/sphinxgalleria/sphinxgalleria.mjs') +
"new SphinxGalleria('%s', %s, %s).init();</script>" % (
node['options']['galleria'],
json.dumps(node['options']),
json.dumps(node['images'])
)
)
raise nodes.SkipNode
def latex_visit_galleria(self: LaTeXTranslator, node: galleria) -> None:
for image in node['images']:
self.body.append('[%s]' % image['alt'])
raise nodes.SkipNode
def texinfo_visit_galleria(self: TexinfoTranslator, node: galleria) -> None:
for image in node['images']:
self.body.append('[%s]' % image['alt'])
raise nodes.SkipNode
def text_visit_galleria(self: TextTranslator, node: galleria) -> None:
for image in node['images']:
self.body.append('[%s]' % image['alt'])
raise nodes.SkipNode
def gemini_visit_galleria(self, node: galleria) -> None:
for image in node['images']:
self.body += '=> %s %s' % (image['path'], image['alt'])
raise nodes.SkipNode
def man_visit_galleria(self: ManualPageTranslator, node: galleria) -> None:
if 'alt' in node.attributes:
self.body.append('[%s]' % node['alt'])
raise nodes.SkipNode
def align_choices(argument):
return directives.choice(argument, ('left', 'right', 'center'))
class GalleriaDirective(Directive):
has_content = False
required_arguments = 1
final_argument_whitespace = True
option_spec = {
"class": directives.class_option,
"galleria": directives.unchanged,
"alt": directives.unchanged,
"title": directives.unchanged,
"thumbsize": directives.unchanged,
'width': directives.length_or_percentage_or_unitless,
'height': directives.length_or_unitless,
'align': align_choices,
'hide_title': directives.flag,
'hide_alt': directives.flag,
'no_transition': directives.flag,
}
def run(self):
source = self.state_machine.document.settings._source
env = self.state_machine.document.settings.env
try:
if source not in env.galleria_nodes:
env.galleria_nodes[source] = {}
except AttributeError:
env.galleria_nodes = {}
env.galleria_nodes[source] = {}
galleria_name = self.options.get('galleria')
galleria_name = galleria_name or str(uuid.uuid4()).replace('-', '')
created = False
if galleria_name in env.galleria_nodes[source]:
node = env.galleria_nodes[source][galleria_name]
else:
node = galleria()
node['class'] = 'galleria'
node['options'] = {
'galleria': 'galleria-' + galleria_name,
'label_prev': _('Previous'),
'label_next': _('Next'),
'label_close': _('Close'),
'label_thumbnail': _('Thumbnail, click to enlarge'),
}
node['images'] = []
env.galleria_nodes[source][galleria_name] = node
created = True
if self.options.get('class'):
node['class'] = ' '.join(self.options['class'])
node['options']["width"] = self.options.get('width') or 'auto'
node['options']["height"] = self.options.get('height') or 'auto'
node['options']["align"] = self.options.get('align') or 'center'
node['options']["no_transition"] = 'no_transition' in self.options
images_path = self.arguments
for path in images_path:
image = {}
image["alt"] = self.options.get('alt')
image["title"] = self.options.get('title')
image["thumbsize"] = self.options.get('thumbsize') or '100x100'
image["hide_alt"] = 'hide_alt' in self.options
image["hide_title"] = 'hide_title' in self.options
image["path"] = path
node['images'].append(image)
if created:
return [node]
return []