Skip to content

Commit a19b889

Browse files
committed
Update for replacement of various Angstrom unit variants -> \AA
1 parent c1e03f4 commit a19b889

2 files changed

Lines changed: 48 additions & 21 deletions

File tree

docs/manuals/mcstas/fix_unit_exponents.py

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/usr/bin/env python3
2-
"""
2+
r"""
33
fix_unit_exponents.py
44
55
One-off maintenance script: normalizes implicit unit exponents in McStas
@@ -8,7 +8,7 @@
88
99
cm2 -> cm^2
1010
AA-1 -> AA^-1
11-
Angs-1 -> Angs^-1
11+
Angs-1 -> AA^-1
1212
m3 -> m^3
1313
cm-2 s-1 -> cm^-2 s^-1
1414
@@ -18,6 +18,15 @@
1818
only do so if the source .comp/.instr headers actually use the "^"
1919
notation in the first place.
2020
21+
Along the way, it also canonicalizes Angstrom shorthand spelling to "AA"
22+
(the dominant convention in this codebase): "Angs", "Ang", "Angstrom" and
23+
"Angstroms" all become "AA". This is a source-level complement to
24+
_tex_with_angstrom()/_ANGSTROM_RE in mcdoc.py, which already recognize
25+
all of these spellings when rendering and turn them into the LaTeX \AA{}
26+
(ring-A, i.e. \AA{}) symbol regardless -- but keeping the source spelling
27+
consistent is worth doing too, rather than accumulating several synonyms
28+
for the same thing across the library.
29+
2130
Scope: deliberately narrow, matching exactly what _format_unit() acts on:
2231
- Only lines inside a %P / %PARAMETERS McDoc section (tracked by
2332
scanning for %-tag lines; any %-tag whose first letter isn't P exits
@@ -31,6 +40,9 @@
3140
"^" (so "AA^3" and "cm^-2" are left alone), and only where the digit
3241
run ends at a word boundary (so e.g. "H2O" is correctly left alone --
3342
the "O" right after "2" means there's no exponent there to convert).
43+
- The Angstrom-spelling canonicalization only matches whole "Angs"/
44+
"Ang"/"Angstrom"/"Angstroms" tokens (word-bounded), so it cannot
45+
touch part of a longer identifier or word.
3446
3547
Usage:
3648
# Preview changes as a unified diff; changes nothing on disk:
@@ -48,8 +60,8 @@
4860
already-correct carets, chemical-formula-shaped false positives, prose
4961
outside %P), but a human pass over a mechanical, repo-wide edit is always
5062
worthwhile. Two files (contrib/NMO.comp, samples/PowderN.comp) have
51-
already been fixed by hand as a spot-check; running this script over them
52-
again should report zero further changes.
63+
already been fixed by hand as a spot-check, using "AA" throughout; running
64+
this script over them again should report zero further changes.
5365
"""
5466
import argparse
5567
import difflib
@@ -65,15 +77,21 @@
6577
# ':' possibly being followed directly by '[' with no space).
6678
PARAM_LINE_RE = re.compile(r'^(\s*\*\s*[\w.]+\s*:)(.*)$')
6779

80+
# Angstrom shorthand spellings other than the canonical "AA", matched as
81+
# whole words only.
82+
ANGSTROM_SYNONYM_RE = re.compile(r'\b(?:Angstroms?|Angs?)\b')
83+
6884
# A "word immediately followed by an exponent" token, e.g. cm2, AA-1,
6985
# m-2.5 -- but not one already preceded by '^' (e.g. the "3" in "AA^3").
7086
EXPONENT_RE = re.compile(r'(?<!\^)\b([A-Za-z]+)(-?\d+(?:\.\d+)?)\b')
7187

7288

7389
def normalize_unit(unit):
74-
''' Converts cmN -> cm^N / AA-1 -> AA^-1 style tokens within one
75-
[unit] bracket's content; anything else (units with no numeric
76-
suffix, or already using '^') is left untouched. '''
90+
''' Canonicalizes Angstrom spelling to "AA", then converts cmN ->
91+
cm^N / AA-1 -> AA^-1 style tokens within one [unit] bracket's
92+
content; anything else (units with no numeric suffix, or already
93+
using '^') is left untouched. '''
94+
unit = ANGSTROM_SYNONYM_RE.sub('AA', unit)
7795
return EXPONENT_RE.sub(r'\1^\2', unit)
7896

7997

tools/Python/mcdoc/mcdoc.py

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,13 @@ def _tex(s):
103103
return s
104104

105105

106+
# Standalone tokens that are ASCII shorthand for Angstrom in McStas
107+
# comp/instr headers -- "AA" is the dominant convention, but "Angs",
108+
# "Ang", "Angstrom"/"Angstroms" also appear. All are converted to the
109+
# proper LaTeX \AA{} (ring-A) symbol; see _tex_with_angstrom() below.
110+
_ANGSTROM_RE = re.compile(r'\b(?:AA|Angstroms?|Angs?)\b')
111+
112+
106113
# ------------------------------------------------------------------
107114
# %D "Description" field -> flowing LaTeX (instead of one big
108115
# \verbatim block), with a small, whitelisted set of embedded HTML
@@ -201,14 +208,15 @@ def repl_img(m):
201208
# single space, exactly like ordinary paragraph reflow.
202209
s = re.sub(r'\s+', ' ', s).strip()
203210

204-
# Standalone "AA" (Angstrom) tokens -> \AA{}. Detected here, on the
205-
# raw text (with only tag-derived placeholders interspersed, which
206-
# can't create false word boundaries), and stashed via the *same*
207-
# top-level tokens list as everything else above -- this is safe
208-
# because it is a sibling top-level substitution into s, not nested
209-
# inside another not-yet-resolved stashed value (contrast with
210-
# _tex_with_angstrom(), which is for standalone/isolated use).
211-
s = re.sub(r'\bAA\b', lambda m: stash(r'\AA{}'), s)
211+
# Standalone "AA"/"Angs"/"Ang"/"Angstrom(s)" (Angstrom) tokens -> \AA{}.
212+
# Detected here, on the raw text (with only tag-derived placeholders
213+
# interspersed, which can't create false word boundaries), and
214+
# stashed via the *same* top-level tokens list as everything else
215+
# above -- this is safe because it is a sibling top-level
216+
# substitution into s, not nested inside another not-yet-resolved
217+
# stashed value (contrast with _tex_with_angstrom(), which is for
218+
# standalone/isolated use).
219+
s = _ANGSTROM_RE.sub(lambda m: stash(r'\AA{}'), s)
212220

213221
# Escape everything else exactly like normal LaTeX text (this also
214222
# correctly turns any *unrecognized* '<tag>' into literal, visible
@@ -278,12 +286,13 @@ def _mccode_label():
278286

279287
def _tex_with_angstrom(s):
280288
r'''
281-
Like _tex(), but additionally converts standalone "AA" tokens -- the
282-
common ASCII shorthand for Angstrom used throughout McStas comp/instr
283-
headers, since the actual \AA{} (Angstrom, ring-A) character is rarely
284-
typed directly -- into the proper LaTeX \AA{} symbol.
289+
Like _tex(), but additionally converts standalone Angstrom shorthand
290+
tokens -- "AA" is the dominant convention in McStas comp/instr
291+
headers, but "Angs", "Ang", "Angstrom"/"Angstroms" also appear, since
292+
the actual \AA{} (Angstrom, ring-A) character is rarely typed directly
293+
-- into the proper LaTeX \AA{} symbol.
285294
286-
The "AA" detection deliberately happens on the *raw*, not-yet-escaped
295+
The token detection deliberately happens on the *raw*, not-yet-escaped
287296
text (protected via a stash/placeholder, exactly like
288297
_convert_inline_markup does for HTML tags) rather than after _tex()
289298
has run. This matters: in raw text, '_' is a word character, so
@@ -304,7 +313,7 @@ def _tex_with_angstrom(s):
304313
def stash(repl):
305314
tokens.append(repl)
306315
return '\x01%d\x02' % (len(tokens) - 1)
307-
s = re.sub(r'\bAA\b', lambda m: stash(r'\AA{}'), s)
316+
s = _ANGSTROM_RE.sub(lambda m: stash(r'\AA{}'), s)
308317
s = _tex(s)
309318
def restore(m):
310319
return tokens[int(m.group(1))]

0 commit comments

Comments
 (0)