diff --git a/CHANGES b/CHANGES
index bec2a8e..414010a 100644
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,11 @@
Changes
=======
+2.0.0 (*2023-08-02*)
+====================
+
+- Sphinx 7.x compatibility
+
1.0.0 (*2021-06-06*)
====================
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..46947ce
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,97 @@
+[build-system]
+requires = ["flit_core>=3.2"]
+build-backend = "flit_core.buildapi"
+
+[project]
+name = "sphinx_fasvg"
+version = "2.0.0"
+requires-python = ">=3.8"
+dependencies = [
+ "Sphinx>=7.0.0"
+]
+license = {text = "EUPL-1.2"}
+authors = [
+ {name = "Nerv Project ASBL", email = "contact@nerv-project.eu"},
+ {name = "kujiu"},
+ {name = "ptitgnu"}
+]
+maintainers = [
+ {name = "Nerv Project ASBL", email = "contact@nerv-project.eu"},
+ {name = "kujiu"},
+ {name = "ptitgnu"}
+]
+description = "A Sphinx fontawesome wrapper for SVG format"
+readme = {file = "README.rst", content-type = "text/x-rst"}
+keywords=["sphinx", "doc", "theme"]
+classifiers=[
+ "Framework :: Sphinx",
+ "Framework :: Sphinx :: Theme",
+ "Development Status :: 5 - Production/Stable",
+ "License :: OSI Approved :: European Union Public Licence 1.2 (EUPL 1.2)",
+ "Environment :: Console",
+ "Environment :: Web Environment",
+ "Framework :: Sphinx :: Theme",
+ "Intended Audience :: Developers",
+ "Programming Language :: Python :: 3",
+ "Operating System :: OS Independent",
+ "Topic :: Documentation",
+ "Topic :: Software Development :: Documentation",
+]
+
+[project.urls]
+homepage = "https://www.nerv-project.eu"
+repository = "https://procrastinator.nerv-project.eu/nerv-project/sphinx_fasvg"
+issues = "https://procrastinator.nerv-project.eu/nerv-project/sphinx_fasvg/issues"
+editor = "https://www.nerv-project.eu"
+changelog = "https://procrastinator.nerv-project.eu/nerv-project/sphinx_fasvg/raw/branch/main/CHANGES.rst"
+
+[project.optional-dependencies]
+tests = [
+ "pytest",
+ "flake8",
+ "pylint",
+ "pytest-cov"
+]
+setup = [
+ "Sphinx",
+ "pytest-runner",
+ "flake8",
+ "pylint",
+ "babel",
+ "flit",
+]
+
+[project.scripts]
+
+[tool.pytest.ini_options]
+minversion = "6.0"
+addopts = "-ra -q"
+testpaths = [
+ "tests",
+]
+
+[tool.babel.extract_messages]
+mapping_file = "babel.cfg"
+output_file = "locale/sphinx.pot"
+keywords = ["_", "__", "l_", "lazy_gettext", "gettext", "ngettext"]
+add_comments = "Translators:"
+
+[tool.babel.init_catalog]
+domain = "sphinx"
+input_file = "locale/sphinx.pot"
+output_dir = "locale/"
+
+[tool.babel.update_catalog]
+domain = "sphinx"
+input_file = "locale/sphinx.pot"
+output_dir = "locale/"
+
+[tool.babel.compile_catalog]
+domain = "sphinx"
+directory = "locale/"
+
+[tool.flit.sdist]
+include = [
+ "*.py",
+]
+
diff --git a/setup.cfg b/setup.cfg
deleted file mode 100644
index 8ce115d..0000000
--- a/setup.cfg
+++ /dev/null
@@ -1,7 +0,0 @@
-[metadata]
-description-file = README.rst
-license-files =
- LICENSE
- LICENSE-de
- LICENSE-fr
- LICENSE-nl
diff --git a/setup.py b/setup.py
deleted file mode 100644
index c466fcc..0000000
--- a/setup.py
+++ /dev/null
@@ -1,45 +0,0 @@
-from setuptools import setup
-
-with open("README.rst", "r") as fh:
- long_description = fh.read()
-
-setup(
- name="sphinx_fasvg",
- version="1.0.0",
- url="https://procrastinator.nerv-project.eu/nerv-project/sphinx_fasvg",
- license="EUPL 1.2",
- author="Kujiu",
- author_email="kujiu-pypi@kujiu.org",
- description="Use font-awesome icons in SVG form",
- long_description=long_description,
- long_description_content_type="text/x-rst",
- packages=["sphinx_fasvg"],
- package_data={
- "sphinx_fasvg": [
- "*.py",
- ]
- },
- entry_points={"sphinx.html_themes": ["nervproject = sphinx_nervproject_theme"]},
- install_requires=["sphinx>=2.0.0"],
- classifiers=[
- "Framework :: Sphinx",
- "Framework :: Sphinx :: Extension",
- "Development Status :: 5 - Production/Stable",
- "Environment :: Console",
- "Environment :: Web Environment",
- "Intended Audience :: Developers",
- "License :: OSI Approved :: European Union Public Licence 1.2 (EUPL 1.2)",
- "Programming Language :: Python :: 3",
- "Programming Language :: Python :: 3.5",
- "Programming Language :: Python :: 3.6",
- "Programming Language :: Python :: 3.7",
- "Operating System :: OS Independent",
- "Topic :: Documentation",
- "Topic :: Software Development :: Documentation",
- ],
- keywords="sphinx fontawesome svg",
- project_urls={
- "Source": "https://procrastinator.nerv-project.eu/nerv-project/sphinx_fasvg",
- "Issues": "https://procrastinator.nerv-project.eu/nerv-project/sphinx_fasvg/issues",
- },
-)
diff --git a/sphinx_fasvg/__init__.py b/sphinx_fasvg/__init__.py
index d812fa3..3b29b77 100644
--- a/sphinx_fasvg/__init__.py
+++ b/sphinx_fasvg/__init__.py
@@ -1,6 +1,8 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
+# pylint:disable=invalid-name,unused-argument,too-many-arguments
+
"""
Use fontawesome icons
"""
@@ -10,7 +12,7 @@ import uuid
from docutils import nodes
from docutils.parsers.rst import Directive
-import docutils.parsers.rst.directives as directives
+from docutils.parsers.rst import directives
from sphinx.writers.html import HTMLTranslator
from sphinx.writers.latex import LaTeXTranslator
@@ -19,19 +21,20 @@ from sphinx.writers.text import TextTranslator
from sphinx.writers.manpage import ManualPageTranslator
from sphinx.util.osutil import relative_uri
-__version_info__ = (1, 0, 0)
+__version_info__ = (2, 0, 0)
__version__ = '.'.join([str(val) for val in __version_info__])
class fa(nodes.General, nodes.Inline, nodes.Element):
- pass
+ """Generic node for FontAwesome"""
class falink(nodes.General, nodes.Inline, nodes.Element):
- pass
+ """Generic link node for FontAwesome"""
def append_fa_image(self: HTMLTranslator, node: fa or falink) -> None:
+ """Add image to node"""
path = {
'brands': self.builder.config.fa_brands_path,
'regular': self.builder.config.fa_regular_path,
@@ -49,64 +52,71 @@ def append_fa_image(self: HTMLTranslator, node: fa or falink) -> None:
options += ' xmlns="http://www.w3.org/2000/svg"'
options += ' xmlns:xlink="http://www.w3.org/1999/xlink"'
if node.get('alt', None):
- options += ' aria-labelledby="fa_%s"' % label_uid
- title = '
%s' % (label_uid, node['alt'])
+ options += f' aria-labelledby="fa_{label_uid}"'
+ title = f'{node["alt"]}'
else:
options += ' aria-hidden="true" xlink:title=""'
if node.get('html_id', None):
- options += ' id="%s"' % node['html_id']
+ options += f' id={node["html_id"]}'
- options += ' class="fasvg %s"' % (node.get('html_class', '') or '')
+ options += f' class="fasvg {node.get("html_class", "") or ""}"'
self.body.append(
- ''
)
def html_visit_fa(self: HTMLTranslator, node: fa) -> None:
+ """Rendering FA node in HTML"""
append_fa_image(self, node)
raise nodes.SkipNode
def latex_visit_fa(self: LaTeXTranslator, node: fa) -> None:
+ """Rendering FA node in LaTeX"""
if 'alt' in node.attributes:
- self.body.append('[%s]' % node['alt'])
+ self.body.append(f'[{node["alt"]}]')
raise nodes.SkipNode
def texinfo_visit_fa(self: TexinfoTranslator, node: fa) -> None:
+ """Rendering FA node in TeXinfo"""
if 'alt' in node.attributes:
- self.body.append('[%s]' % node['alt'])
+ self.body.append(f'[{node["alt"]}]')
raise nodes.SkipNode
def text_visit_fa(self: TextTranslator, node: fa) -> None:
+ """Rendering FA node in text"""
if 'alt' in node.attributes:
- self.add_text('[%s]' % node['alt'])
+ self.add_text(f'[{node["alt"]}]')
raise nodes.SkipNode
def gemini_visit_fa(self, node: fa) -> None:
+ """Rendering FA node in Gemini"""
if 'alt' in node.attributes:
- self.add_text('[%s]' % node['alt'])
+ self.add_text(f'[{node["alt"]}]')
raise nodes.SkipNode
def man_visit_fa(self: ManualPageTranslator, node: fa) -> None:
+ """Rendering FA node in Man file"""
if 'alt' in node.attributes:
- self.body.append('[%s]' % node['alt'])
+ self.body.append(f'[{node["alt"]}]')
raise nodes.SkipNode
def create_fa_node(iconset, icon, html_id=None, html_class=None, alt=None):
+ """Create FA node"""
node = fa()
node['iconset'] = iconset
node['icon'] = icon
@@ -117,95 +127,140 @@ def create_fa_node(iconset, icon, html_id=None, html_class=None, alt=None):
def html_visit_falink(self: HTMLTranslator, node: fa) -> None:
+ """Rendering FA link node in HTML"""
self.body.append(
- '' %
- (node['icon'], node['url']))
+ f''
+ )
append_fa_image(self, node)
- self.body.append(' %s' % node['text'])
+ self.body.append(f' {node["text"]}')
raise nodes.SkipNode
def latex_visit_falink(self: LaTeXTranslator, node: fa) -> None:
- self.body.append('\\href{%s}{%s %s}' % (
- node['url'], node['alt'], node['text']))
+ """Rendering FA link node in LaTeX"""
+ self.body.append(
+ f'\\href{{{node["url"]}}}'
+ f'{{{node["alt"]} {node["text"]}}}'
+ )
raise nodes.SkipNode
def texinfo_visit_falink(self: TexinfoTranslator, node: fa) -> None:
- self.body.append('\\href{%s}{%s %s}' % (
- node['url'], node['alt'], node['text']))
+ """Rendering FA link node in TexInfo"""
+ self.body.append(
+ f'\\href{{{node["url"]}}}{{{node["alt"]} {node["text"]}}}'
+ )
raise nodes.SkipNode
def text_visit_falink(self: TextTranslator, node: fa) -> None:
- self.add_text('%s %s <%s>' % (node['alt'], node['text'], node['url']))
+ """Rendering FA link node in text"""
+ self.add_text(
+ f'{node["alt"]} {node["text"]} <{node["url"]}>'
+ )
raise nodes.SkipNode
def gemini_visit_falink(self, node: fa) -> None:
+ """Rendering FA link node in Gemini"""
self.end_block()
- self.add_text('=> %s %s %s' % (node['alt'], node['url'], node['text']))
+ self.add_text(
+ f'=> {node["alt"]} {node["url"]} {node["text"]}'
+ )
self.end_block()
raise nodes.SkipNode
def man_visit_falink(self: ManualPageTranslator, node: fa) -> None:
- self.body.append('%s %s <%s>' % (node['text'], node['alt'], node['url']))
+ """Rendering FA link node in Man file"""
+ self.body.append(f'{node["text"]} {node["alt"]} <{node["url"]}>')
raise nodes.SkipNode
def create_falink_node(iconset, text):
+ """Create a new link node depending of text and iconset"""
node = falink()
regex = re.compile(
- r'(?P[a-zA-Z-_]*):(?P.*)'
- + r'(?P\[.*\] *)<(?P.*)>')
+ r'(?P *[a-zA-Z-_]* *):(?P.*)'
+ + r'(?P\[.*\] *)?<(?P.*)>')
parsed = regex.search(text)
node['iconset'] = iconset
- node['icon'] = parsed.group('icon')
+ node['icon'] = parsed.group('icon').strip()
node['url'] = parsed.group('url').strip()
node['alt'] = (parsed.group('alt') or '').strip().strip('[]')
node['text'] = parsed.group('text').strip()
return node
-def fab(role, rawtext, text, lineno, inliner, options={}, content=[]):
- regex = re.compile(r'(?P[a-zA-Z-_]*)(?P\[.*\] *)')
+def fab(role, rawtext, text, lineno, inliner, options=None, content=None):
+ """Node for FontAwesome brand icon"""
+ if not options:
+ options = {}
+ if not content:
+ content = []
+ regex = re.compile(r'(?P[a-zA-Z-_]*)(?P\[.*\] *)?')
parsed = regex.search(text)
alt = (parsed.group('alt') or '').strip().strip('[]')
icon = parsed.group('icon').strip()
return [create_fa_node('brands', icon, alt=alt)], []
-def far(role, rawtext, text, lineno, inliner, options={}, content=[]):
- regex = re.compile(r'(?P[a-zA-Z-_]*)(?P\[.*\] *)')
+def far(role, rawtext, text, lineno, inliner, options=None, content=None):
+ """Node for FontAwesome regular icon"""
+ if not options:
+ options = {}
+ if not content:
+ content = []
+ regex = re.compile(r'(?P[a-zA-Z-_]*)(?P\[.*\] *)?')
parsed = regex.search(text)
alt = (parsed.group('alt') or '').strip().strip('[]')
icon = parsed.group('icon').strip()
return [create_fa_node('regular', icon, alt=alt)], []
-def fas(role, rawtext, text, lineno, inliner, options={}, content=[]):
- regex = re.compile(r'(?P[a-zA-Z-_]*)(?P\[.*\] *)')
+def fas(role, rawtext, text, lineno, inliner, options=None, content=None):
+ """Node for FontAwesome solid icon"""
+ if not options:
+ options = {}
+ if not content:
+ content = []
+ regex = re.compile(r'(?P[a-zA-Z-_]*)(?P\[.*\] *)?')
parsed = regex.search(text)
alt = (parsed.group('alt') or '').strip().strip('[]')
icon = parsed.group('icon').strip()
return [create_fa_node('solid', icon, alt=alt)], []
-def fablink(role, rawtext, text, lineno, inliner, options={}, content=[]):
+def fablink(role, rawtext, text, lineno, inliner, options=None, content=None):
+ """Node for link with FontAwesome brands iconset"""
+ if not options:
+ options = {}
+ if not content:
+ content = []
return [create_falink_node('brands', text)], []
-def farlink(role, rawtext, text, lineno, inliner, options={}, content=[]):
+def farlink(role, rawtext, text, lineno, inliner, options=None, content=None):
+ """Node for link with FontAwesome regular iconset"""
+ if not options:
+ options = {}
+ if not content:
+ content = []
return [create_falink_node('regular', text)], []
-def faslink(role, rawtext, text, lineno, inliner, options={}, content=[]):
+def faslink(role, rawtext, text, lineno, inliner, options=None, content=None):
+ """Node for link with FontAwesome solid iconset"""
+ if not options:
+ options = {}
+ if not content:
+ content = []
return [create_falink_node('solid', text)], []
class FaDirective(Directive):
+ """ Main directive for FontAwesome icons """
has_content = False
required_arguments = 1
@@ -229,18 +284,24 @@ class FaDirective(Directive):
class Fab(FaDirective):
+ """ Directive for FontAwesome brands iconset """
iconset = 'brands'
class Far(FaDirective):
+ """ Directive for FontAwesome regular iconset """
iconset = 'regular'
class Fas(FaDirective):
+ """ Directive for FontAwesome solid iconset """
iconset = 'solid'
def setup(app):
+ """
+ Setup Sphinx app
+ """
app.add_node(
fa,
html=(html_visit_fa, None),