Skip to content
Open
2 changes: 2 additions & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,5 @@
# MyST Parser Configuration

myst_enable_extensions = ["dollarmath", "amsmath"]

prf_realtyp_to_countertyp = {}
36 changes: 34 additions & 2 deletions docs/source/options.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Options

## Minimal color scheme

This package has the option to choose a more **minimal** color scheme.

The aim is to create admonitions that are clearly different to the core text with
Expand All @@ -15,7 +17,7 @@ compared to the current default

To enable the `minimal` color scheme you can use the following.

## Jupyter Book Project
### Jupyter Book Project

Add `proof_minimal_theme = True` to your `_config.yml`

Expand All @@ -25,6 +27,36 @@ sphinx:
proof_minimal_theme: true
```

## Sphinx Project
### Sphinx Project

Add `proof_minimal_theme = True` to your `conf.py`


## Shared numbering

By default, each type of theorem has their own numbering and counter.
This can be changed by setting the option `prf_realtyp_to_countertyp` to a dictionary associating to a prf-type which prf-type's counter it should use.

### Sphinx Project

In `conf.py`, e.g. to have a shared counter for all prf-types:

```
prf_realtyp_to_countertyp = {
"axiom": "theorem",
"theorem": "theorem",
"lemma": "theorem",
"algorithm": "theorem",
"definition": "theorem",
"remark": "theorem",
"conjecture": "theorem",
"corollary": "theorem",
"criterion": "theorem",
"example": "theorem",
"property": "theorem",
"observation": "theorem",
"proposition": "theorem",
"assumption": "theorem",
"notation": "theorem",
}
```
1 change: 1 addition & 0 deletions sphinx_proof/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ def copy_asset_files(app: Sphinx, exc: Union[bool, Exception]):
def setup(app: Sphinx) -> Dict[str, Any]:

app.add_config_value("proof_minimal_theme", False, "html")
app.add_config_value("prf_realtyp_to_countertyp", {}, "env")

app.add_css_file("proof.css")
app.connect("build-finished", copy_asset_files)
Expand Down
51 changes: 37 additions & 14 deletions sphinx_proof/directive.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,25 @@
logger = logging.getLogger(__name__)


DEFAULT_REALTYP_TO_COUNTERTYP = {
"axiom": "axiom",
"theorem": "theorem",
"lemma": "lemma",
"algorithm": "algorithm",
"definition": "definition",
"remark": "remark",
"conjecture": "conjecture",
"corollary": "corollary",
"criterion": "criterion",
"example": "example",
"property": "property",
"observation": "observation",
"proposition": "proposition",
"assumption": "assumption",
"notation": "notation",
}


class ElementDirective(SphinxDirective):
"""A custom Sphinx Directive"""

Expand All @@ -36,13 +55,16 @@ class ElementDirective(SphinxDirective):

def run(self) -> List[Node]:
env = self.env
typ = self.name.split(":")[1]
realtyp = self.name.split(":")[1]
countertyp = env.config.prf_realtyp_to_countertyp.get(
realtyp, DEFAULT_REALTYP_TO_COUNTERTYP[realtyp]
)
serial_no = env.new_serialno()
if not hasattr(env, "proof_list"):
env.proof_list = {}

# If class in options add to class array
classes, class_name = ["proof", typ], self.options.get("class", [])
classes, class_name = ["proof", realtyp], self.options.get("class", [])
if class_name:
classes.extend(class_name)

Expand All @@ -53,15 +75,15 @@ def run(self) -> List[Node]:
node_id = f"{label}"
else:
self.options["noindex"] = True
label = f"{typ}-{serial_no}"
node_id = f"{typ}-{serial_no}"
label = f"{realtyp}-{serial_no}"
node_id = f"{realtyp}-{serial_no}"
ids = [node_id]

# Duplicate label warning
if not label == "" and label in env.proof_list.keys():
path = env.doc2path(env.docname)[:-3]
other_path = env.doc2path(env.proof_list[label]["docname"])
msg = f"duplicate {typ} label '{label}', other instance in {other_path}"
msg = f"duplicate {realtyp} label '{label}', other instance in {other_path}"
logger.warning(msg, location=path, color="red")

title_text = ""
Expand All @@ -70,13 +92,13 @@ def run(self) -> List[Node]:

textnodes, messages = self.state.inline_text(title_text, self.lineno)

section = nodes.section(classes=[f"{typ}-content"], ids=["proof-content"])
section = nodes.section(classes=[f"{realtyp}-content"], ids=["proof-content"])
self.state.nested_parse(self.content, self.content_offset, section)

if "nonumber" in self.options:
node = unenumerable_node()
else:
node_type = NODE_TYPES[typ]
node_type = NODE_TYPES[countertyp]
node = node_type()

node.document = self.state.document
Expand All @@ -88,17 +110,18 @@ def run(self) -> List[Node]:
node["classes"].extend(classes)
node["title"] = title_text
node["label"] = label
node["type"] = typ
node["countertype"] = countertyp
node["realtype"] = realtyp

env.proof_list[label] = {
"docname": env.docname,
"type": typ,
"countertype": countertyp,
"realtype": realtyp,
"ids": ids,
"label": label,
"prio": 0,
"nonumber": True if "nonumber" in self.options else False,
}

return [node]


Expand All @@ -115,16 +138,16 @@ class ProofDirective(SphinxDirective):
}

def run(self) -> List[Node]:
typ = self.name.split(":")[1]
realtyp = self.name.split(":")[1]

# If class in options add to class array
classes, class_name = ["proof", typ], self.options.get("class", [])
classes, class_name = ["proof", realtyp], self.options.get("class", [])
if class_name:
classes.extend(class_name)

section = nodes.admonition(classes=classes, ids=[typ])
section = nodes.admonition(classes=classes, ids=[realtyp])

self.content[0] = "{}. ".format(typ.title()) + self.content[0]
self.content[0] = "{}. ".format(realtyp.title()) + self.content[0]
self.state.nested_parse(self.content, 0, section)

node = proof_node()
Expand Down
10 changes: 5 additions & 5 deletions sphinx_proof/domain.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def generate(self, docnames=None) -> Tuple[Dict[str, Any], bool]:
return content, True

proofs = self.domain.env.proof_list
# {'theorem-0': {'docname': 'start/overview', 'type': 'theorem', 'ids': ['theorem-0'], 'label': 'theorem-0', 'prio': 0, 'nonumber': False}} # noqa: E501
# {'theorem-0': {'docname': 'start/overview', 'realtype': 'theorem', 'countertype': 'theorem', 'ids': ['theorem-0'], 'label': 'theorem-0', 'prio': 0, 'nonumber': False}} # noqa: E501

# name, subtype, docname, typ, anchor, extra, qualifier, description
for anchor, values in proofs.items():
Expand All @@ -57,7 +57,7 @@ def generate(self, docnames=None) -> Tuple[Dict[str, Any], bool]:
anchor,
values["docname"],
"",
values["type"],
values["realtype"],
)
)

Expand Down Expand Up @@ -157,11 +157,11 @@ def resolve_xref(
if target in contnode[0]:
number = ""
if not env.proof_list[target]["nonumber"]:
typ = env.proof_list[target]["type"]
countertyp = env.proof_list[target]["countertype"]
number = ".".join(
map(str, env.toc_fignumbers[todocname][typ][target])
map(str, env.toc_fignumbers[todocname][countertyp][target])
)
title = nodes.Text(f"{translate(match['type'].title())} {number}")
title = nodes.Text(f"{translate(match["realtype"].title())} {number}")
# builder, fromdocname, todocname, targetid, child, title=None
return make_refnode(builder, fromdocname, todocname, target, title)
else:
Expand Down
30 changes: 18 additions & 12 deletions sphinx_proof/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
from sphinx.writers.latex import LaTeXTranslator
from sphinx.locale import get_translation


from sphinx.util import logging

logger = logging.getLogger(__name__)

MESSAGE_CATALOG_NAME = "proof"
_ = get_translation(MESSAGE_CATALOG_NAME)

Expand All @@ -31,17 +36,18 @@ def visit_enumerable_node(self, node: Node) -> None:


def depart_enumerable_node(self, node: Node) -> None:
typ = node.attributes.get("type", "")
countertyp = node.attributes.get("countertype", "")
realtyp = node.attributes.get("realtype", "")
if isinstance(self, LaTeXTranslator):
number = get_node_number(self, node, typ)
number = get_node_number(self, node, countertyp)
idx = list_rindex(self.body, latex_admonition_start) + 2
self.body.insert(idx, f"{typ.title()} {number}")
self.body.insert(idx, f"{realtyp.title()} {number}")
self.body.append(latex_admonition_end)
else:
# Find index in list of 'Proof #'
number = get_node_number(self, node, typ)
idx = self.body.index(f"{typ} {number} ")
self.body[idx] = f"{_(typ.title())} {number} "
number = get_node_number(self, node, countertyp)
idx = self.body.index(f"{countertyp} {number} ")
self.body[idx] = f"{_(realtyp.title())} {number} "
self.body.append("</div>")


Expand All @@ -55,18 +61,18 @@ def visit_unenumerable_node(self, node: Node) -> None:


def depart_unenumerable_node(self, node: Node) -> None:
typ = node.attributes.get("type", "")
realtyp = node.attributes.get("realtype", "")
title = node.attributes.get("title", "")
if isinstance(self, LaTeXTranslator):
idx = list_rindex(self.body, latex_admonition_start) + 2
self.body.insert(idx, f"{typ.title()}")
self.body.insert(idx, f"{realtyp.title()}")
self.body.append(latex_admonition_end)
else:
if title == "":
idx = list_rindex(self.body, '<p class="admonition-title">') + 1
else:
idx = list_rindex(self.body, title)
element = f"<span>{_(typ.title())} </span>"
element = f"<span>{_(realtyp.title())} </span>"
self.body.insert(idx, element)
self.body.append("</div>")

Expand All @@ -79,10 +85,10 @@ def depart_proof_node(self, node: Node) -> None:
pass


def get_node_number(self, node: Node, typ) -> str:
def get_node_number(self, node: Node, countertyp) -> str:
"""Get the number for the directive node for HTML."""
ids = node.attributes.get("ids", [])[0]
key = typ
key = countertyp
if isinstance(self, LaTeXTranslator):
docname = find_parent(self.builder.env, node, "section")
fignumbers = self.builder.env.toc_fignumbers.get(
Expand All @@ -91,7 +97,7 @@ def get_node_number(self, node: Node, typ) -> str:
else:
fignumbers = self.builder.fignumbers
if self.builder.name == "singlehtml":
key = "%s/%s" % (self.docnames[-1], typ)
key = "%s/%s" % (self.docnames[-1], countertyp)
number = fignumbers.get(key, {}).get(ids, ())
return ".".join(map(str, number))

Expand Down