# Configuration file for the Sphinx documentation builder.
#
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html

import ast
import datetime
import functools
import io
import os
import sys
import re

import pygments.lexers
import pygments.filters
import sphinx.util.logging

sys.path.insert(0, os.path.dirname(os.path.abspath('.')))

from pygments_lexer_pseudocode2.lexers.algpseudocode import (
    AlgPseudocodeLexer, AlgPseudocodeLexer_DE, AlgPseudocodeLexer_FR)
from pygments_lexer_pseudocode2.lexers.fr_pseudocode import FrPseudocodeLexer
from pygments_lexer_pseudocode2.filters import (
    TokenReplaceFilter, ErrorToGenericErrorTokenFilter)


needs_sphinx = '2.1'
"""This is the theory:

- 2.1: - :py:meth:Sphinx.add_lexer` takes a class as argument

Currently really built and tested with Sphinx 7.1.2.

"""

current_date = datetime.date.today().isoformat()

master_doc = "index"

# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information

project = 'Pygments Pseudocode Lexer'
copyright = u'2026 Franz Glasner. © Copyright 2015 Simon Wachter'
author = 'Franz Glasner'
#
# Determine "release" and other release metadata dynamically from the
# package's "__version__" or other VCS data.
#
with io.open("../pygments_lexer_pseudocode2/__init__.py",
             "rt",
             encoding="utf-8") as relfp:
    verfiledata = relfp.read()
    release = ast.literal_eval(
        re.search(r"""^\s*__version__\s*=\s*(("|')[^"']*\2)""",
                  verfiledata,
                  re.MULTILINE).group(1))
    release_date = today = (
        ast.literal_eval(
            re.search(r"""^\s*__date__\s*=\s*(("|')[^"']*\2)""",
                      verfiledata,
                      re.MULTILINE).group(1))
        or "dev:%s" % (current_date,)
    )
    release_rev = ast.literal_eval(
        re.search(r"""^\s*__revision__\s*=\s*(("|')[^"']*\2)""",
                  verfiledata,
                  re.MULTILINE).group(1))
    if release_rev.startswith("|") or release_rev.endswith("|"):
        # Assume that make export (hg kwarchive) may not has been called.
        import subprocess
        try:
            release_rev = subprocess.check_output(
                ["hg", "id", "-i"], stderr=subprocess.STDOUT)
        except Exception:
            release_rev = "<unknown>"
        else:
            if sys.version_info[0] >= 3:
                release_rev = release_rev.decode("ascii")
            release_rev = "dev:%s" % (release_rev.strip(),)
        define_rest_keywords = True
    else:
        #
        # Assume that all keywords are expanded properly everywhere:
        # do not define special VCSxxx keyword below.
        #
        define_rest_keywords = False

version = release
primary_domain = None

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

extensions = [
    "sphinx.ext.todo",
]

templates_path = ['_templates']
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', 'lexerlist.rst']

highlight_language = "none"

rst_prolog = """
.. role:: algpseudocode(code)
.. |release_date| replace:: %s
.. |release_rev| replace:: %s
""" % (release_date, release_rev)
if define_rest_keywords:
    rst_prolog += """\
.. |VCSJustDate| replace:: %s
.. |VCSRevision| replace:: %s
""" % (release_date, release_rev)
rst_epilog = """
.. _Pygments: https://pygments.org/
.. _Sphinx: https://www.sphinx-doc.org
.. _Python: https://www.python.org/
.. _Algpseudocodex: https://ctan.org/pkg/algpseudocodex
"""


# --- Options for todo extension ---------------------------------------------
todo_include_todos = True


# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output

html_static_path = ['_static']
html_extra_path = ['../LICENSES']
html_copy_source = False
html_show_sourcelink = False

#html_theme = 'alabaster'
html_theme = 'haiku'
html_css_files = ["custom-haiku.css"]
html_title = 'The %s v%s' % (project, release)
html_short_title = html_title
html_last_updated_fmt = "%s (rv:%s)" % (current_date, release_rev)
#pygments_style = "sphinx"
pygments_style = "default"

# --- Options for LaTeX output -----------------------------------------------
# https://www.sphinx-doc.org/en/master/latex.html
latex_engine = 'lualatex'
latex_elements = {
    "papersize": "a4paper",
    "babel": r"\usepackage{babel}",
    "fontpkg": r"\usepackage[adobesource]{my-doc-fonts}",
#   "fontpkg": r"\usepackage[plexmono]{my-doc-fonts}",
#   "fontpkg": r"\usepackage[spectral]{my-doc-fonts}",
#   "fontpkg": r"\usepackage[charter]{my-doc-fonts}",
    "releasename": "Version",
    "fncychap": r"\usepackage[Sonny]{fncychap}",
    "preamble": r"""
\usepackage{my-doc-style}
\builddate{%s}\vcsrevision{%s}
""" % (current_date, release_rev),
}
latex_theme = "manual"
latex_show_urls = "footnote"
latex_show_pagerefs = True
latex_domain_indices = False
latex_documents = [
    ("_latex/index-latex", "PygmentsLexerPseudocode2.tex", "The Pygments Pseudocode Lexer", "Franz Glasner", "manual", True),
]
latex_additional_files = [
    "_latex/my-doc-fonts.sty",
    "_latex/my-doc-style.sty",
    "examples/example-1.pseudocode",         # linked via \url{}
    "examples/algorithm-dinic.pseudocode",
    "examples/algorithm-ford-fulkerson.pseudocode",
    "examples/algorithm-edmonds-karp.pseudocode",
]

def setup(app):
    #
    # Custom release_date and commit id variables with a custom substitution
    # |release_date| and |release_rev|'.
    #
    app.add_config_value('release_date', '', 'env')
    app.add_config_value('release_rev', '', 'env')

    #
    # Add a custom lexer: AlgPseudocodeLexer with custom init option "no_end"
    # Given lexer must be callable: so use an indirection with "partial".
    #
    # See also:
    # - https://stackoverflow.com/questions/11413203/sphinx-pygments-lexer-filter-extension
    #
    app.add_lexer("NoEndAlgPseudocode",
                  functools.partial(AlgPseudocodeLexer, no_end=True))
    # For developing a lexer with smoother error handling
    app.add_lexer("no-raiseonerror-algpseudocode",
                  functools.partial(AlgPseudocodeLexer,
                                    prohibit_raiseonerror_filter=True))
    #
    # To test with the custom filter that maps
    # Token.Error to Token.Generic.Error
    #
    app.add_lexer("genericerror-algpseudocode",
                  functools.partial(AlgPseudocodeLexer,
                                    filters=["errortogenericerror"]))

    #
    # Prepare for building docs while the package is not installed:
    # Install by "hand" into pygments!
    # This is an ugly *HACK*!
    #
    # IMPORTANT: Synchronize names with pyproject.toml!
    #
    try:
        if not pygments.lexers.find_lexer_class("AlgPseudocode"):
            sphinx.util.logging.getLogger("conf-setup").info(
                "%s","Installing lexer `AlgPseudocode' and language variants")
            for clsname, lexer in (
                    ("AlgPseudocodeLexer", AlgPseudocodeLexer),
                    ("AlgPseudocodeLexer_DE", AlgPseudocodeLexer_DE),
                    ("AlgPseudocodeLexer_FR", AlgPseudocodeLexer_FR)):
                pygments.lexers.LEXERS[clsname] = (
                "pygments_lexer_pseudocode2.lexers.algpseudocode",
                lexer.name,
                tuple(lexer.aliases),
                tuple(lexer.filenames),
                tuple(lexer.mimetypes))
        if not pygments.lexers.find_lexer_class("FrPseudocode"):
            sphinx.util.logging.getLogger("conf-setup").info(
                "%s","Installing lexer `FrPseudocode'")
            for clsname, lexer in (
                    ("FrPseudocodeLexer", FrPseudocodeLexer),):
                pygments.lexers.LEXERS[clsname] = (
                "pygments_lexer_pseudocode2.lexers.fr_pseudocode",
                lexer.name,
                tuple(lexer.aliases),
                tuple(lexer.filenames),
                tuple(lexer.mimetypes))
        if not pygments.filters.find_filter_class("tokenreplace"):
            sphinx.util.logging.getLogger("conf-setup").info(
                "%s","Installing filter `tokenreplace'")
            pygments.filters.FILTERS["tokenreplace"] = TokenReplaceFilter
        if not pygments.filters.find_filter_class("errortogenericerror"):
            sphinx.util.logging.getLogger("conf-setup").info(
                "%s","Installing filter `errortogenericerror'")
            pygments.filters.FILTERS["errortogenericerror"]  = \
                ErrorToGenericErrorTokenFilter
    except Exception as ex:
        sphinx.util.logging.getLogger("conf-setup").error("%s", str(ex))
        sphinx.util.logging.getLogger("conf-setup").error(
            "%s",
            "No lexers/filters from pygments_lexer_pseudocode2 available;"
            " please install or call `pip install -e .' .")
