|
|
@@ -1,89 +1,123 @@
|
|
|
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
|
|
# file Copyright.txt or https://cmake.org/licensing for details.
|
|
|
|
|
|
+# BEGIN imports
|
|
|
+
|
|
|
import os
|
|
|
import re
|
|
|
|
|
|
from dataclasses import dataclass
|
|
|
from typing import Any, List, Tuple, Type, cast
|
|
|
|
|
|
+import sphinx
|
|
|
+
|
|
|
+from docutils.utils.code_analyzer import Lexer, LexerError
|
|
|
+from docutils.parsers.rst import Directive, directives
|
|
|
+from docutils.transforms import Transform
|
|
|
+from docutils.nodes import Element, Node, TextElement, system_message
|
|
|
+from docutils import io, nodes
|
|
|
+
|
|
|
+from sphinx.directives import ObjectDescription, nl_escape_re
|
|
|
+from sphinx.domains import Domain, ObjType
|
|
|
+from sphinx.roles import XRefRole
|
|
|
+from sphinx.util.docutils import ReferenceRole
|
|
|
+from sphinx.util.nodes import make_refnode
|
|
|
+from sphinx.util import logging, ws_re
|
|
|
+from sphinx import addnodes
|
|
|
+
|
|
|
+# END imports
|
|
|
+
|
|
|
+# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
+
|
|
|
+# BEGIN pygments tweaks
|
|
|
+
|
|
|
# Override much of pygments' CMakeLexer.
|
|
|
# We need to parse CMake syntax definitions, not CMake code.
|
|
|
|
|
|
# For hard test cases that use much of the syntax below, see
|
|
|
-# - module/FindPkgConfig.html (with "glib-2.0>=2.10 gtk+-2.0" and similar)
|
|
|
-# - module/ExternalProject.html (with http:// https:// git@; also has command options -E --build)
|
|
|
-# - manual/cmake-buildsystem.7.html (with nested $<..>; relative and absolute paths, "::")
|
|
|
+# - module/FindPkgConfig.html
|
|
|
+# (with "glib-2.0>=2.10 gtk+-2.0" and similar)
|
|
|
+# - module/ExternalProject.html
|
|
|
+# (with http:// https:// git@; also has command options -E --build)
|
|
|
+# - manual/cmake-buildsystem.7.html
|
|
|
+# (with nested $<..>; relative and absolute paths, "::")
|
|
|
|
|
|
from pygments.lexers import CMakeLexer
|
|
|
-from pygments.token import Name, Operator, Punctuation, String, Text, Comment, Generic, Whitespace, Number
|
|
|
+from pygments.token import (Comment, Name, Number, Operator, Punctuation,
|
|
|
+ String, Text, Whitespace)
|
|
|
from pygments.lexer import bygroups
|
|
|
|
|
|
-# RE to split multiple command signatures
|
|
|
-sig_end_re = re.compile(r'(?<=[)])\n')
|
|
|
-
|
|
|
# Notes on regular expressions below:
|
|
|
# - [\.\+-] are needed for string constants like gtk+-2.0
|
|
|
-# - Unix paths are recognized by '/'; support for Windows paths may be added if needed
|
|
|
+# - Unix paths are recognized by '/'; support for Windows paths may be added
|
|
|
+# if needed
|
|
|
# - (\\.) allows for \-escapes (used in manual/cmake-language.7)
|
|
|
# - $<..$<..$>..> nested occurrence in cmake-buildsystem
|
|
|
-# - Nested variable evaluations are only supported in a limited capacity. Only
|
|
|
-# one level of nesting is supported and at most one nested variable can be present.
|
|
|
+# - Nested variable evaluations are only supported in a limited capacity.
|
|
|
+# Only one level of nesting is supported and at most one nested variable can
|
|
|
+# be present.
|
|
|
|
|
|
CMakeLexer.tokens["root"] = [
|
|
|
- (r'\b(\w+)([ \t]*)(\()', bygroups(Name.Function, Text, Name.Function), '#push'), # fctn(
|
|
|
+ # fctn(
|
|
|
+ (r'\b(\w+)([ \t]*)(\()',
|
|
|
+ bygroups(Name.Function, Text, Name.Function), '#push'),
|
|
|
(r'\(', Name.Function, '#push'),
|
|
|
(r'\)', Name.Function, '#pop'),
|
|
|
(r'\[', Punctuation, '#push'),
|
|
|
(r'\]', Punctuation, '#pop'),
|
|
|
(r'[|;,.=*\-]', Punctuation),
|
|
|
- (r'\\\\', Punctuation), # used in commands/source_group
|
|
|
+ # used in commands/source_group
|
|
|
+ (r'\\\\', Punctuation),
|
|
|
(r'[:]', Operator),
|
|
|
- (r'[<>]=', Punctuation), # used in FindPkgConfig.cmake
|
|
|
- (r'\$<', Operator, '#push'), # $<...>
|
|
|
- (r'<[^<|]+?>(\w*\.\.\.)?', Name.Variable), # <expr>
|
|
|
- (r'(\$\w*\{)([^\}\$]*)?(?:(\$\w*\{)([^\}]+?)(\}))?([^\}]*?)(\})', # ${..} $ENV{..}, possibly nested
|
|
|
- bygroups(Operator, Name.Tag, Operator, Name.Tag, Operator, Name.Tag, Operator)),
|
|
|
- (r'([A-Z]+\{)(.+?)(\})', bygroups(Operator, Name.Tag, Operator)), # DATA{ ...}
|
|
|
- (r'[a-z]+(@|(://))((\\.)|[\w.+-:/\\])+', Name.Attribute), # URL, git@, ...
|
|
|
- (r'/\w[\w\.\+-/\\]*', Name.Attribute), # absolute path
|
|
|
+ # used in FindPkgConfig.cmake
|
|
|
+ (r'[<>]=', Punctuation),
|
|
|
+ # $<...>
|
|
|
+ (r'\$<', Operator, '#push'),
|
|
|
+ # <expr>
|
|
|
+ (r'<[^<|]+?>(\w*\.\.\.)?', Name.Variable),
|
|
|
+ # ${..} $ENV{..}, possibly nested
|
|
|
+ (r'(\$\w*\{)([^\}\$]*)?(?:(\$\w*\{)([^\}]+?)(\}))?([^\}]*?)(\})',
|
|
|
+ bygroups(Operator, Name.Tag, Operator, Name.Tag, Operator, Name.Tag,
|
|
|
+ Operator)),
|
|
|
+ # DATA{ ...}
|
|
|
+ (r'([A-Z]+\{)(.+?)(\})', bygroups(Operator, Name.Tag, Operator)),
|
|
|
+ # URL, git@, ...
|
|
|
+ (r'[a-z]+(@|(://))((\\.)|[\w.+-:/\\])+', Name.Attribute),
|
|
|
+ # absolute path
|
|
|
+ (r'/\w[\w\.\+-/\\]*', Name.Attribute),
|
|
|
(r'/', Name.Attribute),
|
|
|
- (r'\w[\w\.\+-]*/[\w.+-/\\]*', Name.Attribute), # relative path
|
|
|
- (r'[A-Z]((\\.)|[\w.+-])*[a-z]((\\.)|[\w.+-])*', Name.Builtin), # initial A-Z, contains a-z
|
|
|
+ # relative path
|
|
|
+ (r'\w[\w\.\+-]*/[\w.+-/\\]*', Name.Attribute),
|
|
|
+ # initial A-Z, contains a-z
|
|
|
+ (r'[A-Z]((\\.)|[\w.+-])*[a-z]((\\.)|[\w.+-])*', Name.Builtin),
|
|
|
(r'@?[A-Z][A-Z0-9_]*', Name.Constant),
|
|
|
(r'[a-z_]((\\;)|(\\ )|[\w.+-])*', Name.Builtin),
|
|
|
(r'[0-9][0-9\.]*', Number),
|
|
|
- (r'(?s)"(\\"|[^"])*"', String), # "string"
|
|
|
+ # "string"
|
|
|
+ (r'(?s)"(\\"|[^"])*"', String),
|
|
|
(r'\.\.\.', Name.Variable),
|
|
|
- (r'<', Operator, '#push'), # <..|..> is different from <expr>
|
|
|
+ # <..|..> is different from <expr>
|
|
|
+ (r'<', Operator, '#push'),
|
|
|
(r'>', Operator, '#pop'),
|
|
|
(r'\n', Whitespace),
|
|
|
(r'[ \t]+', Whitespace),
|
|
|
(r'#.*\n', Comment),
|
|
|
- # (r'[^<>\])\}\|$"# \t\n]+', Name.Exception), # fallback, for debugging only
|
|
|
+ # fallback, for debugging only
|
|
|
+ # (r'[^<>\])\}\|$"# \t\n]+', Name.Exception),
|
|
|
]
|
|
|
|
|
|
-from docutils.utils.code_analyzer import Lexer, LexerError
|
|
|
-from docutils.parsers.rst import Directive, directives
|
|
|
-from docutils.transforms import Transform
|
|
|
-from docutils.nodes import Element, Node, TextElement, system_message
|
|
|
-from docutils import io, nodes
|
|
|
-
|
|
|
-from sphinx.directives import ObjectDescription, nl_escape_re
|
|
|
-from sphinx.domains import Domain, ObjType
|
|
|
-from sphinx.roles import XRefRole
|
|
|
-from sphinx.util.docutils import ReferenceRole
|
|
|
-from sphinx.util.nodes import make_refnode
|
|
|
-from sphinx.util import logging, ws_re
|
|
|
-from sphinx import addnodes
|
|
|
+# END pygments tweaks
|
|
|
|
|
|
-import sphinx
|
|
|
+# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
|
|
# Require at least Sphinx 2.x.
|
|
|
assert sphinx.version_info >= (2,)
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
+# RE to split multiple command signatures.
|
|
|
+sig_end_re = re.compile(r'(?<=[)])\n')
|
|
|
+
|
|
|
|
|
|
@dataclass
|
|
|
class ObjectEntry:
|
|
|
@@ -162,13 +196,15 @@ class CMakeModule(Directive):
|
|
|
self.state_machine.insert_input(lines, path)
|
|
|
return []
|
|
|
|
|
|
+
|
|
|
class _cmake_index_entry:
|
|
|
def __init__(self, desc):
|
|
|
self.desc = desc
|
|
|
|
|
|
- def __call__(self, title, targetid, main = 'main'):
|
|
|
+ def __call__(self, title, targetid, main='main'):
|
|
|
return ('pair', f'{self.desc} ; {title}', targetid, main, None)
|
|
|
|
|
|
+
|
|
|
_cmake_index_objs = {
|
|
|
'command': _cmake_index_entry('command'),
|
|
|
'cpack_gen': _cmake_index_entry('cpack generator'),
|
|
|
@@ -189,6 +225,7 @@ _cmake_index_objs = {
|
|
|
'variable': _cmake_index_entry('variable'),
|
|
|
}
|
|
|
|
|
|
+
|
|
|
class CMakeTransform(Transform):
|
|
|
|
|
|
# Run this transform early since we insert nodes we want
|
|
|
@@ -215,7 +252,8 @@ class CMakeTransform(Transform):
|
|
|
title = False
|
|
|
else:
|
|
|
for line in f:
|
|
|
- if len(line) > 0 and (line[0].isalnum() or line[0] == '<' or line[0] == '$'):
|
|
|
+ if len(line) > 0 and (line[0].isalnum() or
|
|
|
+ line[0] == '<' or line[0] == '$'):
|
|
|
title = line.rstrip()
|
|
|
break
|
|
|
f.close()
|
|
|
@@ -256,6 +294,7 @@ class CMakeTransform(Transform):
|
|
|
domain = cast(CMakeDomain, env.get_domain('cmake'))
|
|
|
domain.note_object(objtype, targetname, targetid, targetid)
|
|
|
|
|
|
+
|
|
|
class CMakeObject(ObjectDescription):
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
self.targetname = None
|
|
|
@@ -453,6 +492,7 @@ class CMakeSignatureObject(CMakeObject):
|
|
|
|
|
|
return super().run()
|
|
|
|
|
|
+
|
|
|
class CMakeReferenceRole:
|
|
|
# See sphinx.util.nodes.explicit_title_re; \x00 escapes '<'.
|
|
|
_re = re.compile(r'^(.+?)(\s*)(?<!\x00)<(.*?)>$', re.DOTALL)
|
|
|
@@ -478,6 +518,7 @@ class CMakeReferenceRole:
|
|
|
return super().__call__(name, rawtext, text, *args, **kwargs)
|
|
|
return Class
|
|
|
|
|
|
+
|
|
|
class CMakeCRefRole(CMakeReferenceRole[ReferenceRole]):
|
|
|
nodeclass: Type[Element] = nodes.reference
|
|
|
innernodeclass: Type[TextElement] = nodes.literal
|
|
|
@@ -493,6 +534,7 @@ class CMakeCRefRole(CMakeReferenceRole[ReferenceRole]):
|
|
|
|
|
|
return [refnode], []
|
|
|
|
|
|
+
|
|
|
class CMakeXRefRole(CMakeReferenceRole[XRefRole]):
|
|
|
|
|
|
_re_sub = re.compile(r'^([^()\s]+)\s*\(([^()]*)\)$', re.DOTALL)
|
|
|
@@ -530,6 +572,7 @@ class CMakeXRefRole(CMakeReferenceRole[XRefRole]):
|
|
|
# def result_nodes(self, document, env, node, is_ref):
|
|
|
# pass
|
|
|
|
|
|
+
|
|
|
class CMakeXRefTransform(Transform):
|
|
|
|
|
|
# Run this transform early since we insert nodes we want
|
|
|
@@ -570,6 +613,7 @@ class CMakeXRefTransform(Transform):
|
|
|
indexnode['entries'] = [make_index_entry(objname, targetid, '')]
|
|
|
ref.replace_self([indexnode, targetnode, ref])
|
|
|
|
|
|
+
|
|
|
class CMakeDomain(Domain):
|
|
|
"""CMake domain."""
|
|
|
name = 'cmake'
|
|
|
@@ -603,7 +647,7 @@ class CMakeDomain(Domain):
|
|
|
}
|
|
|
roles = {
|
|
|
'cref': CMakeCRefRole(),
|
|
|
- 'command': CMakeXRefRole(fix_parens = True, lowercase = True),
|
|
|
+ 'command': CMakeXRefRole(fix_parens=True, lowercase=True),
|
|
|
'cpack_gen': CMakeXRefRole(),
|
|
|
'envvar': CMakeXRefRole(),
|
|
|
'generator': CMakeXRefRole(),
|
|
|
@@ -668,6 +712,7 @@ class CMakeDomain(Domain):
|
|
|
for refname, obj in self.data['objects'].items():
|
|
|
yield (refname, obj.name, obj.objtype, obj.docname, obj.node_id, 1)
|
|
|
|
|
|
+
|
|
|
def setup(app):
|
|
|
app.add_directive('cmake-module', CMakeModule)
|
|
|
app.add_transform(CMakeTransform)
|