Expand description
Shared rule infrastructure — spec 018 Phase 2. Ports the parts of
_helpers.py and per-rule-module helper functions that more than
one bib rule needs: citation-scope resolution
(_iter_referenced_entries / _collect_cited_keys), the
entry_line/entry_violation factories, and the source-rescan
technique naming.py/house_style.py use to locate a field value’s
byte span for a Fix (bibtexparser exposes no field-level offsets,
only entry.start_line).
Modules§
- abbreviations
- Abbreviations rule — mirrors
journals/jss/rules/abbreviations.py(JSS-ABBR-001). - bibtex
- BibTeX mechanical rules — mirrors
journals/jss/rules/bibtex.py(JSS-BIBTEX-001..005). - capitalization
- Capitalization rules — mirrors
journals/jss/rules/capitalization.py(JSS-CAP-001/002/004; JSS-CAP-003 is retired — seespecs/003-jss-rule-catalogue/catalogue.yaml’sretired_rule_ids). - citations
- Citations rules — mirrors
journals/jss/rules/citations.py(JSS-CITE-002/003/004). - code_
style - Code-style rules — mirrors
journals/jss/rules/code_style.py(JSS-CODE-001/002/003). - code_
width - Code-width rule — mirrors
journals/jss/rules/code_width.py(JSS-WIDTH-001). - crossrefs
- Cross-reference rules — mirrors
journals/jss/rules/crossrefs.py(JSS-XREF-001..007). Position convention: same asmarkup.rs— helpers scoped to oneCharsNode’s own text use byte offsets as an approximation, but any offset that becomes aViolation/Fixposition is converted to an exact codepoint offset via the usualc.span.pos + c.chars[..byte_off].chars().count()idiom before use. - house_
style - House-style rules — mirrors
journals/jss/rules/house_style.py: JSS-HOUSE-001/003 (tex_files) and JSS-HOUSE-002 (bib_files). - markup
- Markup rules — mirrors
journals/jss/rules/markup.py(JSS-MARKUP-001..004). The noisiest, most heuristic-laden rule module in the Python codebase (per the porting plan). - naming
- Naming rules — mirrors
journals/jss/rules/naming.py(JSS-NAME-001 tex_files, JSS-NAME-002 bib_files). - operators
- Operator/math-notation rules — mirrors
journals/jss/rules/operators.py(JSS-OPER-001/002/003/004). - preamble
- Preamble rules — mirrors
journals/jss/rules/preamble.py(JSS-PRE-001..008). Single-file scope simplification per other Phase 3 modules; the.tex/.rnw-only format restriction Python encodes viaRule(..., formats=_PREAMBLE_FORMATS)is an engine (Phase 4) concern, not modeled at the rule-function level here. - references
- References rules — mirrors
journals/jss/rules/references.py’s bib-facing rules (JSS-REFS-001/003/004/005/006/007). All operate on plain field-value strings (title/journal/note/year) — most need neither the tex surface nor a byte-offsetFix. - structure
- Structure rules — mirrors
journals/jss/rules/structure.py(JSS-STRUCT-001..006). - tex_
common - Shared tex-rule infrastructure — spec 018 Phase 3. Ports
_helpers.py’smake_violation/tex_violation/_lineno_colfactories (the tex-side counterparts ofentry_violationinrules::mod). - typography
- Typography rules — mirrors
journals/jss/rules/typography.py(JSS-TYPO-001/002/003/004).
Functions§
- collect_
cited_ keys (cited_keys, include_all)from every\cite*/\nocitemacro across the given tex-like node lists. Mirrors_helpers.py::_collect_cited_keys.- entry_
line - 1-based line of an entry’s
@type{opening. Mirrors_helpers.py::entry_line(entry.start_lineis 0-based). - entry_
source_ span - The
[start, end)char-offset slice ofsourcecoveringentry: from the start of its@type{line through just before the next line-starting@(or EOF). Mirrorsnaming.py::_entry_source_span. - entry_
violation - A catalogue-backed violation anchored to a bib entry’s first line.
Mirrors
_helpers.py::entry_violation. - entry_
violation_ with_ fix - Same as
entry_violationbut with an attachedFix. - field_
value_ span - Locates
field_name = <delim><expected_value><delim>withinentry’s source span and returns the[start, end)char-offset span of JUST the value (delimiters excluded, whitespace trimmed) — the same span aFixshould cover so the rewrite preserves the surrounding{}/""style. Mirrorsnaming.py::_field_value_span, including its non-nested-brace limitation: the value scanner stops at the first}/", it does not balance nested braces (this is a deliberate parity choice, not an oversight — replicating Python’s regex[^{}]*exactly). - py_repr
- Mimics Python’s
repr()for a plain string — used everywhere a rule message embeds a value via Python’s!r(e.g.f"key {entry.key!r} ..."). Rust’s{:?}always double-quotes; Python’srepr()prefers single quotes and only switches to double when the string contains a'but no"(CPython’sunicode_repr). Covers the common cases (quotes, backslash,\n/\r/\t); does not attempt full\xXX-escaping of arbitrary control characters, which none of these rules’ inputs produce. - referenced_
entries - Entries referenced from the paper’s tex-like surface (or every
entry, per the bib-only /
\nocite{*}scope-widening rules). Mirrors_helpers.py::_iter_referenced_entries.tex_likeempty means “no tex/rnw/rmd input present” — the bib-only widening case.