This PR extends the custom sphinx extension for examples. It now allows for simple patterns in the file names and matches the file types using arbitrary regular expressions instead of just looking at the file extensions. This is necessary to integrate examples from the z3pycompat API: the examples live at a nontrivial place (in the build folder), which we inject via the file name patterns; we will have two separate examples which both end in .py but can be distinguished via the pattern used in the beginning.
| The source code for this example can be found at `examples/api/cpp/quickstart.cpp <https://github.com/cvc5/cvc5/blob/master/examples/api/cpp/quickstart.cpp>`_.
.. api-examples::
- ../../../examples/api/cpp/quickstart.cpp
- ../../../examples/api/java/QuickStart.java
- ../../../examples/api/python/quickstart.py
- ../../../examples/api/smtlib/quickstart.smt2
+ <examples>/api/cpp/quickstart.cpp
+ <examples>/api/java/QuickStart.java
+ <examples>/api/python/quickstart.py
+ <examples>/api/smtlib/quickstart.smt2
| The source code for this example can be found at `examples/api/python/quickstart.py <https://github.com/cvc5/cvc5/blob/master/examples/api/python/quickstart.cpp>`_.
.. api-examples::
- ../../../../examples/api/cpp/quickstart.cpp
- ../../../../examples/api/java/QuickStart.java
- ../../../../examples/api/python/quickstart.py
- ../../../../examples/api/smtlib/quickstart.smt2
+ <examples>/api/cpp/quickstart.cpp
+ <examples>/api/java/QuickStart.java
+ <examples>/api/python/quickstart.py
+ <examples>/api/smtlib/quickstart.smt2
| The source code for this example can be found at `examples/api/smtlib/quickstart.smt2 <https://github.com/cvc5/cvc5/blob/master/examples/api/smtlib/quickstart.smt2>`_.
.. api-examples::
- ../../examples/api/smtlib/quickstart.smt2
- ../../examples/api/cpp/quickstart.cpp
- ../../examples/api/java/QuickStart.java
- ../../examples/api/python/quickstart.py
+ <examples>/api/smtlib/quickstart.smt2
+ <examples>/api/cpp/quickstart.cpp
+ <examples>/api/java/QuickStart.java
+ <examples>/api/python/quickstart.py
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
+import os
import sys
# add path to enable extensions
html_extra_path = []
+
+ex_patterns = {
+ '<examples>': '/../examples',
+ '<z3pycompat>': '/' + os.path.relpath('${CMAKE_BINARY_DIR}/deps/src/z3pycompat-EP', '${CMAKE_CURRENT_SOURCE_DIR}'),
+}
+
# -- C++ / Breathe configuration ---------------------------------------------
breathe_default_project = "cvc5"
breathe_domain_by_extension = {"h" : "cpp"}
.. api-examples::
- ../../examples/api/cpp/bitvectors.cpp
- ../../examples/api/java/BitVectors.java
- ../../examples/api/python/bitvectors.py
- ../../examples/api/smtlib/bitvectors.smt2
+ <examples>/api/cpp/bitvectors.cpp
+ <examples>/api/java/BitVectors.java
+ <examples>/api/python/bitvectors.py
+ <examples>/api/smtlib/bitvectors.smt2
.. api-examples::
- ../../examples/api/cpp/bitvectors_and_arrays.cpp
- ../../examples/api/java/BitVectorsAndArrays.java
- ../../examples/api/python/bitvectors_and_arrays.py
- ../../examples/api/smtlib/bitvectors_and_arrays.smt2
+ <examples>/api/cpp/bitvectors_and_arrays.cpp
+ <examples>/api/java/BitVectorsAndArrays.java
+ <examples>/api/python/bitvectors_and_arrays.py
+ <examples>/api/smtlib/bitvectors_and_arrays.smt2
Theory Combination
==================
-
.. api-examples::
- ../../examples/api/cpp/combination.cpp
- ../../examples/api/java/Combination.java
- ../../examples/api/python/combination.py
- ../../examples/api/smtlib/combination.smt2
+ <examples>/api/cpp/combination.cpp
+ <examples>/api/java/Combination.java
+ <examples>/api/python/combination.py
+ <examples>/api/smtlib/combination.smt2
.. api-examples::
- ../../examples/api/cpp/datatypes.cpp
- ../../examples/api/java/Datatypes.java
- ../../examples/api/python/datatypes.py
- ../../examples/api/smtlib/datatypes.smt2
+ <examples>/api/cpp/datatypes.cpp
+ <examples>/api/java/Datatypes.java
+ <examples>/api/python/datatypes.py
+ <examples>/api/smtlib/datatypes.smt2
.. api-examples::
- ../../examples/api/java/Exceptions.java
- ../../examples/api/python/exceptions.py
+ <examples>/api/java/Exceptions.java
+ <examples>/api/python/exceptions.py
.. api-examples::
- ../../examples/api/cpp/extract.cpp
- ../../examples/api/java/Extract.java
- ../../examples/api/python/extract.py
- ../../examples/api/smtlib/extract.smt2
+ <examples>/api/cpp/extract.cpp
+ <examples>/api/java/Extract.java
+ <examples>/api/python/extract.py
+ <examples>/api/smtlib/extract.smt2
.. api-examples::
- ../../examples/api/java/FloatingPointArith.java
- ../../examples/api/python/floating_point.py
+ <examples>/api/java/FloatingPointArith.java
+ <examples>/api/python/floating_point.py
We create a solver, declare a Boolean variable and check whether it is entailed (by ``true``, as nothing has been asserted to the solver).
.. api-examples::
- ../../examples/api/cpp/helloworld.cpp
- ../../examples/api/java/HelloWorld.java
- ../../examples/api/python/helloworld.py
- ../../examples/api/smtlib/helloworld.smt2
+ <examples>/api/cpp/helloworld.cpp
+ <examples>/api/java/HelloWorld.java
+ <examples>/api/python/helloworld.py
+ <examples>/api/smtlib/helloworld.smt2
The two checks are separated by using :code:`push` and :code:`pop`.
.. api-examples::
- ../../examples/api/cpp/linear_arith.cpp
- ../../examples/api/java/LinearArith.java
- ../../examples/api/python/linear_arith.py
- ../../examples/api/smtlib/linear_arith.smt2
+ <examples>/api/cpp/linear_arith.cpp
+ <examples>/api/java/LinearArith.java
+ <examples>/api/python/linear_arith.py
+ <examples>/api/smtlib/linear_arith.smt2
.. api-examples::
- ../../examples/api/cpp/quickstart.cpp
- ../../examples/api/java/QuickStart.java
- ../../examples/api/python/quickstart.py
- ../../examples/api/smtlib/quickstart.smt2
+ <examples>/api/cpp/quickstart.cpp
+ <examples>/api/java/QuickStart.java
+ <examples>/api/python/quickstart.py
+ <examples>/api/smtlib/quickstart.smt2
.. api-examples::
- ../../examples/api/java/Relations.java
- ../../examples/api/smtlib/relations.smt2
+ <examples>/api/java/Relations.java
+ <examples>/api/smtlib/relations.smt2
.. api-examples::
- ../../examples/api/cpp/sequences.cpp
- ../../examples/api/java/Sequences.java
- ../../examples/api/python/sequences.py
- ../../examples/api/smtlib/sequences.smt2
+ <examples>/api/cpp/sequences.cpp
+ <examples>/api/java/Sequences.java
+ <examples>/api/python/sequences.py
+ <examples>/api/smtlib/sequences.smt2
.. api-examples::
- ../../examples/api/cpp/sets.cpp
- ../../examples/api/java/Sets.java
- ../../examples/api/python/sets.py
- ../../examples/api/smtlib/sets.smt2
+ <examples>/api/cpp/sets.cpp
+ <examples>/api/java/Sets.java
+ <examples>/api/python/sets.py
+ <examples>/api/smtlib/sets.smt2
.. api-examples::
- ../../examples/api/cpp/strings.cpp
- ../../examples/api/java/Strings.java
- ../../examples/api/python/strings.py
- ../../examples/api/smtlib/strings.smt2
+ <examples>/api/cpp/strings.cpp
+ <examples>/api/java/Strings.java
+ <examples>/api/python/strings.py
+ <examples>/api/smtlib/strings.smt2
.. api-examples::
- ../../examples/api/cpp/sygus-fun.cpp
- ../../examples/api/java/SygusFun.java
- ../../examples/api/python/sygus-fun.py
- ../../examples/api/smtlib/sygus-fun.sy
+ <examples>/api/cpp/sygus-fun.cpp
+ <examples>/api/java/SygusFun.java
+ <examples>/api/python/sygus-fun.py
+ <examples>/api/smtlib/sygus-fun.sy
.. api-examples::
- ../../examples/api/cpp/sygus-grammar.cpp
- ../../examples/api/java/SygusGrammar.java
- ../../examples/api/python/sygus-grammar.py
- ../../examples/api/smtlib/sygus-grammar.sy
+ <examples>/api/cpp/sygus-grammar.cpp
+ <examples>/api/java/SygusGrammar.java
+ <examples>/api/python/sygus-grammar.py
+ <examples>/api/smtlib/sygus-grammar.sy
.. api-examples::
- ../../examples/api/cpp/sygus-inv.cpp
- ../../examples/api/java/SygusInv.java
- ../../examples/api/python/sygus-inv.py
- ../../examples/api/smtlib/sygus-inv.sy
+ <examples>/api/cpp/sygus-inv.cpp
+ <examples>/api/java/SygusInv.java
+ <examples>/api/python/sygus-inv.py
+ <examples>/api/smtlib/sygus-inv.sy
import os
+import re
from docutils import nodes
from docutils.statemachine import StringList
"""
# Set tab title and language for syntax highlighting
- exts = {
- '.cpp': {'title': 'C++', 'lang': 'c++'},
- '.java': {'title': 'Java', 'lang': 'java'},
- '.py': {'title': 'Python', 'lang': 'python'},
- '.smt2': {'title': 'SMT-LIBv2', 'lang': 'smtlib'},
- '.sy': {'title': 'SyGuS', 'lang': 'smtlib'},
+ types = {
+ '\.cpp$': {
+ 'title': 'C++',
+ 'lang': 'c++',
+ 'group': 'c++'
+ },
+ '\.java$': {
+ 'title': 'Java',
+ 'lang': 'java',
+ 'group': 'java'
+ },
+ '<examples>.*\.py$': {
+ 'title': 'Python',
+ 'lang': 'python',
+ 'group': 'py-regular'
+ },
+ '<z3pycompat>.*\.py$': {
+ 'title': 'Python z3py',
+ 'lang': 'python',
+ 'group': 'py-z3pycompat'
+ },
+ '\.smt2$': {
+ 'title': 'SMT-LIBv2',
+ 'lang': 'smtlib',
+ 'group': 'smt2'
+ },
+ '\.sy$': {
+ 'title': 'SyGuS',
+ 'lang': 'smtlib',
+ 'group': 'smt2'
+ },
}
# The "arguments" are actually the content of the directive
# collect everything in a list of strings
content = ['.. tabs::', '']
- remaining = set([self.exts[e]['lang'] for e in self.exts])
+ remaining = set([t['group'] for t in self.types.values()])
location = '{}:{}'.format(*self.get_source_info())
for file in self.content:
# detect file extension
- _, ext = os.path.splitext(file)
- if ext in self.exts:
- title = self.exts[ext]['title']
- lang = self.exts[ext]['lang']
- remaining.remove(lang)
- else:
- self.logger.warning(f'{location} is using unknown file extension "{ext}"')
- title = ext
- lang = ext
+ lang = None
+ title = None
+ for type in self.types:
+ if re.search(type, file) != None:
+ lang = self.types[type]['lang']
+ title = self.types[type]['title']
+ remaining.discard(self.types[type]['group'])
+ break
+ if lang == None:
+ self.logger.warning(
+ f'file type of {location} could not be detected')
+ title = os.path.splitext(file)[1]
+ lang = title
+
+ for k, v in self.env.config.ex_patterns.items():
+ file = file.replace(k, v)
# generate tabs
content.append(f' .. tab:: {title}')
def setup(app):
app.setup_extension('sphinx_tabs.tabs')
+ app.add_config_value('ex_patterns', {}, 'env')
app.add_directive("api-examples", APIExamples)
return {
'version': '0.1',
The simplest way to get a sense of the syntax is to look at an example:
.. api-examples::
- ../../examples/api/cpp/sets.cpp
- ../../examples/api/python/sets.py
- ../../examples/api/smtlib/sets.smt2
+ <examples>/api/cpp/sets.cpp
+ <examples>/api/python/sets.py
+ <examples>/api/smtlib/sets.smt2
The source code of these examples is available at:
Example:
.. api-examples::
- ../../examples/api/smtlib/relations.smt2
+ <examples>/api/smtlib/relations.smt2
For reference, below is a short summary of the sorts, constants, functions and
predicates.
--------
.. api-examples::
- ../../examples/api/cpp/transcendentals.cpp
- ../../examples/api/python/transcendentals.py
- ../../examples/api/smtlib/transcendentals.smt2
\ No newline at end of file
+ <examples>/api/cpp/transcendentals.cpp
+ <examples>/api/python/transcendentals.py
+ <examples>/api/smtlib/transcendentals.smt2
\ No newline at end of file