Update documentation

This commit is contained in:
2026-06-22 11:44:10 +02:00
parent 189a1954f7
commit 989d6d6888
2 changed files with 142 additions and 4 deletions
+137 -2
View File
@@ -156,13 +156,137 @@ source citation.
rule of thumb.
- **Math.** Use inline `$...$`; it's rewritten to MathJax on the
card, same as for question text. Don't use display math `$$...$$`
(the deck has no MathJax support for those).
(the deck has no MathJax support for those). Getting the *inside* of
`$...$` right is its own discipline — see **§4a Math typesetting**
below. This is the single most error-prone part of this file.
- **Inline emphasis.** `<u>...</u>` is the only HTML you should
type by hand. Everything else gets HTML-escaped.
- **No spoilers about other answers.** If a distractor is a common
trap, naming the trap is fine; quoting the distractor's text is
noise.
### 4a. Math typesetting (MathJax) — get this right
Everything between `$...$` is TeX. MathJax renders **bare multi-letter
runs as a product of italic variables**, so `ohm` shows as *o·h·m*,
`log10` as *l·o·g·10*, `P_{PEP}` as *P·(P·E·P)*. A whole multi-round
review on this repo was spent fixing exactly these. The rules below are
the checklist; wrong → right.
**Units** — never leave a unit as bare letters; wrap in `\text{}` (or use
the symbol) and put a thin space `\,` after the number:
| Wrong (in `$...$`) | Right |
|---|---|
| `0.01 ohm`, `10 kOhm`, `5 MOhm` | `0.01\,\Omega`, `10\,\text{k}\Omega`, `5\,\text{M}\Omega` |
| `3 microhenry`, `3 uH` | `3\,\mu\text{H}` |
| `1 uF`, `100 nF`, `47 pF` | `1\,\mu\text{F}`, `100\,\text{nF}`, `47\,\text{pF}` |
| `5 mA`, `2 mV`, `1 kHz`, `28 MHz` | `5\,\text{mA}`, `2\,\text{mV}`, `1\,\text{kHz}`, `28\,\text{MHz}` |
| `12 dB`, `8 dBi`, `46.8 bit/s` | `12\,\text{dB}`, `8\,\text{dBi}`, `46.8\,\text{bit/s}` |
| `5 mm2`, `2.5 A/mm2` | `5\,\text{mm}^2`, `2.5\,\text{A/mm}^2` |
| `360 degrees`, `45°` | `360^\circ`, `45^\circ` |
| `20 A`, `12 V`, `100 W`, `5 m`, `50 s` | `20\,\text{A}`, `12\,\text{V}`, `100\,\text{W}`, `5\,\text{m}`, `50\,\text{s}` |
**Operators, functions, Greek, powers:**
| Wrong | Right | Why |
|---|---|---|
| `log10(x)` | `\log_{10}(x)` | bare `log` is *l·o·g* |
| `10^(20/10)` | `10^{20/10}` | `^(` superscripts only the `(`; braces group |
| `lambda`, `pi`, `tau`, `omega`, `rho`, `mu` | `\lambda`, `\pi`, `\tau`, … | bare = italic letters |
| `sin`, `cos`, `ln` | `\sin`, `\cos`, `\ln` | |
| `2 x 3`, `R1 || R2` | `2 \cdot 3`, `R_1 \parallel R_2` | `x`/`||` are not operators |
| `62.5%` | `62.5\%` | **bare `%` is a TeX comment — it silently eats the rest of the math** |
| `4,200,000` | `4{,}200{,}000` | bare `,` gets TeX punctuation spacing |
**Subscripts.** Descriptive multi-letter labels/acronyms are roman; a
single-letter subscript stays italic:
| Wrong | Right |
|---|---|
| `P_{EIRP}`, `U_{peak}`, `f_{mod}`, `V_{BE}`, `f_{sum}` | `P_\mathrm{EIRP}`, `U_\mathrm{peak}`, `f_\mathrm{mod}`, `V_\mathrm{BE}`, `f_\mathrm{sum}` |
| `R1/R2 = R3/R4` | `R_1/R_2 = R_3/R_4` |
| keep italic: `U_F`, `f_c`, `X_C`, `R_g` | (single letter = variable, leave as-is) |
A standalone acronym used as a variable (e.g. `MUF` on a formula's LHS)
also goes roman: `\mathrm{MUF}`.
**Dimensional constants keep their unit.** The field-strength constant is
`30\,\Omega`, so write `\sqrt{30\,\Omega \cdot P_\mathrm{EIRP}}` and
`(E\cdot d)^2/(30\,\Omega)`, not a bare `30`. Same idea for the dB-level
exponent: `10^{g/(10\,\text{dB})}` (the `(...)` groups the denominator —
`10^{g/10\,\text{dB}}` parses as `(g/10)·dB`).
**Unit vs. variable — don't blindly unit-ize a single letter.** `A` is
amperes in `20 A` but *area* in `N^2 A/l`; `s`/`m` are seconds/metres in
`50 s` / `5 m` but could be variables elsewhere. The tell: a *free-standing
number* immediately before the letter (`20 A`) means a unit; an exponent
base (`N^2 A`) or a symbolic factor (`S \cdot A`) means a variable. When
unsure, read the sentence.
**What stays prose — do NOT force into `$...$`:**
- Band/wavelength designations: `5/8-wave`, `20/15/10 m trap dipole`,
`the 80 m band`.
- Conceptual word-equations: `1st overtone = 2nd harmonic`,
`Region 1 = Europe/Africa`.
- Units mentioned adjectivally in a sentence: "a 50 ohm antenna",
"the 28 V/m limit", "about 11.7 V/m".
But a **worked computation with an `=`** (e.g. `230 V / 20 = 11.5 V`)
belongs in `$...$`, fully typeset.
### Verifying it — the process lessons
These review rounds kept finding *peers* of an already-fixed defect.
Avoid the repeat:
1. **Fix the whole record, not a substring.** The same formula usually
appears in *both* the explanation body *and* the `Hilfsmittel:` note.
Search the entire entry and fix every occurrence.
2. **Fix the whole class, file-wide — not just the IDs someone listed.**
If `P_{EIRP}` is wrong in one card it is wrong in twenty; sweep the
whole file for the pattern.
3. **Verify with a positive sweep, not a blacklist.** A list of
known-bad tokens always misses a new category (it missed `degrees`,
`bit`, `||`, bare seconds…). Instead: strip `\text{}`/`\mathrm{}` and
the known macros, then flag *every remaining* ≥2-letter run inside
`$...$` — each survivor must be a deliberate variable product
(`LC`, `jX`, `RC`, `di/dt`) or it's a bug.
4. **Don't claim "0 / exhaustive" unless the check actually covers that
category.** Report what you checked, not a blanket adjective.
A ready-made sweep:
```sh
python3 -c '
import json, re
d = json.load(open("explanations.json"))
span = re.compile(r"\$[^$]*\$")
def strip(s):
s = re.sub(r"\\(?:text|mathrm|operatorname)\{[^{}]*\}", " ", s)
return re.sub(r"\\[A-Za-z]+", " ", s) # drop macros (\sqrt, \pi, \cdot, ...)
for k, e in d.items():
ex = e["explanation"] if isinstance(e, dict) else ""
if ex.count("$") % 2 or ex.count("{") != ex.count("}"):
print("BALANCE", k)
for m in span.finditer(ex):
s = m.group(0)
if re.search(r"(?<!\\)%", s) or "||" in s or "°" in s \
or re.search(r"(?<!\\)\blog10\b|10\^\(", s) \
or re.search(r"_\{[A-Za-z][A-Za-z,]*\}", s) \
or re.search(r"(?<=\d),(?=\d\d\d)", s):
print("ISSUE", k, m.group(0)[:60]); break
for tok in re.findall(r"[A-Za-z]{2,}", strip(s)):
# whitelist genuine products / kept tokens; investigate the rest
if tok not in {"LC","RC","RA","UI","CU","PR","jX","fL","fC","di","dt"}:
print("TOKEN?", k, tok, "|", m.group(0)[:60])
'
```
Anything it prints is either a real defect or a new legitimate product to
add to the whitelist — look, don't assume.
### What "WHY-focused" means in practice
| Less useful | More useful |
@@ -455,7 +579,18 @@ Before saving, confirm:
- [ ] `confidence` honestly reflects how well the source supports
the explanation.
- [ ] Keys remain in alphabetical order in the file.
- [ ] `python3 -m unittest test_amateurfunk_anki` passes.
- [ ] **Math typesetting (§4a):** every formula is in `$...$`; units are
`\text{}`/symbols with a leading `\,`; no bare `log10`, `10^(`,
Greek words, `%`, `||`, multi-letter `_{...}` subscripts, or raw
thousands commas; dimensional constants keep their unit. Fix every
occurrence in **both** the body and the `Hilfsmittel:` note.
- [ ] The §4a verification sweep prints nothing unexpected (run it after
any batch of math edits — don't trust a per-ID fix to have caught
the peers).
- [ ] `python3 -m unittest test_amateurfunk_anki` passes. (The full deck
suite is `test_amateurfunk_fetch test_amateurfunk_anki
test_amateurfunk_shorthand test_amateurfunk_technical` — 95 tests;
the two-module subset that validates explanation schema is 65.)
---