Skip to content

Character replacements

Everything the two rewriting commands replace, and everything they deliberately do not.

Text pasted out of a PDF is full of characters that look like ASCII on screen and are not. A declination that reads -00:46:03.66 may actually start with U+2013 EN DASH, and nothing downstream that expects a minus sign will match it.

The work is split across two commands, and which one you want depends on the character:

Command Replaces Run it
Normalize Characters Dashes, quotes, spaces, ligatures, math relations, invisible characters First. It also takes out tabs and stray carriage returns.
Fold Letters to ASCII Accented Latin letters and Greek letters After Normalize Characters, and only when you want the letters flattened.

They are separate commands because flattening Balázs to Balazs is a decision about your data rather than a typographic cleanup, and because one table of 313 characters does not fit in the 4096 instructions a macro gets.

Run Normalize Characters on its own and it reports the accented and Greek letters in its "no safe ASCII spelling" report, which is the nudge toward the second command.

The tables below are generated from the macros themselves by tools/gen_docs.py, so they cannot drift apart.

Whitespace

Handled by Normalize Characters, outside the character table.

What Becomes Note
Tab One space Not tab-stop aware, so the columns close up. When the layout has to survive, run Expand Tabs instead: it writes the spaces each tab stands for. See cleaning up a pasted table.
CR LF LF A DOS-format file never shows these, because XNEdit strips carriage returns on open and restores them on save. A pasted block can still carry them into a Unix-format buffer.
Lone CR LF Same reason.

The character tables

Fold Letters to ASCII

240 characters, every one of them replaced by plain ASCII. From macros/commands/fold-letters-to-ascii.nm.

Accented capitals, Latin-1 Supplement

Character Code point Name Becomes
À U+00C0 LATIN CAPITAL LETTER A WITH GRAVE A
Á U+00C1 LATIN CAPITAL LETTER A WITH ACUTE A
 U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX A
à U+00C3 LATIN CAPITAL LETTER A WITH TILDE A
Ä U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS A
Å U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE A
Ç U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA C
È U+00C8 LATIN CAPITAL LETTER E WITH GRAVE E
É U+00C9 LATIN CAPITAL LETTER E WITH ACUTE E
Ê U+00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX E
Ë U+00CB LATIN CAPITAL LETTER E WITH DIAERESIS E
Ì U+00CC LATIN CAPITAL LETTER I WITH GRAVE I
Í U+00CD LATIN CAPITAL LETTER I WITH ACUTE I
Î U+00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX I
Ï U+00CF LATIN CAPITAL LETTER I WITH DIAERESIS I
Ð U+00D0 LATIN CAPITAL LETTER ETH D
Ñ U+00D1 LATIN CAPITAL LETTER N WITH TILDE N
Ò U+00D2 LATIN CAPITAL LETTER O WITH GRAVE O
Ó U+00D3 LATIN CAPITAL LETTER O WITH ACUTE O
Ô U+00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX O
Õ U+00D5 LATIN CAPITAL LETTER O WITH TILDE O
Ö U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS O
Ø U+00D8 LATIN CAPITAL LETTER O WITH STROKE O
Ù U+00D9 LATIN CAPITAL LETTER U WITH GRAVE U
Ú U+00DA LATIN CAPITAL LETTER U WITH ACUTE U
Û U+00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX U
Ü U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS U
Ý U+00DD LATIN CAPITAL LETTER Y WITH ACUTE Y

Accented small letters, Latin-1 Supplement

Character Code point Name Becomes
à U+00E0 LATIN SMALL LETTER A WITH GRAVE a
á U+00E1 LATIN SMALL LETTER A WITH ACUTE a
â U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX a
ã U+00E3 LATIN SMALL LETTER A WITH TILDE a
ä U+00E4 LATIN SMALL LETTER A WITH DIAERESIS a
å U+00E5 LATIN SMALL LETTER A WITH RING ABOVE a
ç U+00E7 LATIN SMALL LETTER C WITH CEDILLA c
è U+00E8 LATIN SMALL LETTER E WITH GRAVE e
é U+00E9 LATIN SMALL LETTER E WITH ACUTE e
ê U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX e
ë U+00EB LATIN SMALL LETTER E WITH DIAERESIS e
ì U+00EC LATIN SMALL LETTER I WITH GRAVE i
í U+00ED LATIN SMALL LETTER I WITH ACUTE i
î U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX i
ï U+00EF LATIN SMALL LETTER I WITH DIAERESIS i
ð U+00F0 LATIN SMALL LETTER ETH d
ñ U+00F1 LATIN SMALL LETTER N WITH TILDE n
ò U+00F2 LATIN SMALL LETTER O WITH GRAVE o
ó U+00F3 LATIN SMALL LETTER O WITH ACUTE o
ô U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX o
õ U+00F5 LATIN SMALL LETTER O WITH TILDE o
ö U+00F6 LATIN SMALL LETTER O WITH DIAERESIS o
ø U+00F8 LATIN SMALL LETTER O WITH STROKE o
ù U+00F9 LATIN SMALL LETTER U WITH GRAVE u
ú U+00FA LATIN SMALL LETTER U WITH ACUTE u
û U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX u
ü U+00FC LATIN SMALL LETTER U WITH DIAERESIS u
ý U+00FD LATIN SMALL LETTER Y WITH ACUTE y
ÿ U+00FF LATIN SMALL LETTER Y WITH DIAERESIS y

Latin Extended-A

Character Code point Name Becomes
Ā U+0100 LATIN CAPITAL LETTER A WITH MACRON A
ā U+0101 LATIN SMALL LETTER A WITH MACRON a
Ă U+0102 LATIN CAPITAL LETTER A WITH BREVE A
ă U+0103 LATIN SMALL LETTER A WITH BREVE a
Ą U+0104 LATIN CAPITAL LETTER A WITH OGONEK A
ą U+0105 LATIN SMALL LETTER A WITH OGONEK a
Ć U+0106 LATIN CAPITAL LETTER C WITH ACUTE C
ć U+0107 LATIN SMALL LETTER C WITH ACUTE c
Ĉ U+0108 LATIN CAPITAL LETTER C WITH CIRCUMFLEX C
ĉ U+0109 LATIN SMALL LETTER C WITH CIRCUMFLEX c
Ċ U+010A LATIN CAPITAL LETTER C WITH DOT ABOVE C
ċ U+010B LATIN SMALL LETTER C WITH DOT ABOVE c
Č U+010C LATIN CAPITAL LETTER C WITH CARON C
č U+010D LATIN SMALL LETTER C WITH CARON c
Ď U+010E LATIN CAPITAL LETTER D WITH CARON D
ď U+010F LATIN SMALL LETTER D WITH CARON d
Đ U+0110 LATIN CAPITAL LETTER D WITH STROKE D
đ U+0111 LATIN SMALL LETTER D WITH STROKE d
Ē U+0112 LATIN CAPITAL LETTER E WITH MACRON E
ē U+0113 LATIN SMALL LETTER E WITH MACRON e
Ĕ U+0114 LATIN CAPITAL LETTER E WITH BREVE E
ĕ U+0115 LATIN SMALL LETTER E WITH BREVE e
Ė U+0116 LATIN CAPITAL LETTER E WITH DOT ABOVE E
ė U+0117 LATIN SMALL LETTER E WITH DOT ABOVE e
Ę U+0118 LATIN CAPITAL LETTER E WITH OGONEK E
ę U+0119 LATIN SMALL LETTER E WITH OGONEK e
Ě U+011A LATIN CAPITAL LETTER E WITH CARON E
ě U+011B LATIN SMALL LETTER E WITH CARON e
Ĝ U+011C LATIN CAPITAL LETTER G WITH CIRCUMFLEX G
ĝ U+011D LATIN SMALL LETTER G WITH CIRCUMFLEX g
Ğ U+011E LATIN CAPITAL LETTER G WITH BREVE G
ğ U+011F LATIN SMALL LETTER G WITH BREVE g
Ġ U+0120 LATIN CAPITAL LETTER G WITH DOT ABOVE G
ġ U+0121 LATIN SMALL LETTER G WITH DOT ABOVE g
Ģ U+0122 LATIN CAPITAL LETTER G WITH CEDILLA G
ģ U+0123 LATIN SMALL LETTER G WITH CEDILLA g
Ĥ U+0124 LATIN CAPITAL LETTER H WITH CIRCUMFLEX H
ĥ U+0125 LATIN SMALL LETTER H WITH CIRCUMFLEX h
Ħ U+0126 LATIN CAPITAL LETTER H WITH STROKE H
ħ U+0127 LATIN SMALL LETTER H WITH STROKE h
Ĩ U+0128 LATIN CAPITAL LETTER I WITH TILDE I
ĩ U+0129 LATIN SMALL LETTER I WITH TILDE i
Ī U+012A LATIN CAPITAL LETTER I WITH MACRON I
ī U+012B LATIN SMALL LETTER I WITH MACRON i
Ĭ U+012C LATIN CAPITAL LETTER I WITH BREVE I
ĭ U+012D LATIN SMALL LETTER I WITH BREVE i
Į U+012E LATIN CAPITAL LETTER I WITH OGONEK I
į U+012F LATIN SMALL LETTER I WITH OGONEK i
İ U+0130 LATIN CAPITAL LETTER I WITH DOT ABOVE I
ı U+0131 LATIN SMALL LETTER DOTLESS I i
Ĵ U+0134 LATIN CAPITAL LETTER J WITH CIRCUMFLEX J
ĵ U+0135 LATIN SMALL LETTER J WITH CIRCUMFLEX j
Ķ U+0136 LATIN CAPITAL LETTER K WITH CEDILLA K
ķ U+0137 LATIN SMALL LETTER K WITH CEDILLA k
ĸ U+0138 LATIN SMALL LETTER KRA k
Ĺ U+0139 LATIN CAPITAL LETTER L WITH ACUTE L
ĺ U+013A LATIN SMALL LETTER L WITH ACUTE l
Ļ U+013B LATIN CAPITAL LETTER L WITH CEDILLA L
ļ U+013C LATIN SMALL LETTER L WITH CEDILLA l
Ľ U+013D LATIN CAPITAL LETTER L WITH CARON L
ľ U+013E LATIN SMALL LETTER L WITH CARON l
Ŀ U+013F LATIN CAPITAL LETTER L WITH MIDDLE DOT L
ŀ U+0140 LATIN SMALL LETTER L WITH MIDDLE DOT l
Ł U+0141 LATIN CAPITAL LETTER L WITH STROKE L
ł U+0142 LATIN SMALL LETTER L WITH STROKE l
Ń U+0143 LATIN CAPITAL LETTER N WITH ACUTE N
ń U+0144 LATIN SMALL LETTER N WITH ACUTE n
Ņ U+0145 LATIN CAPITAL LETTER N WITH CEDILLA N
ņ U+0146 LATIN SMALL LETTER N WITH CEDILLA n
Ň U+0147 LATIN CAPITAL LETTER N WITH CARON N
ň U+0148 LATIN SMALL LETTER N WITH CARON n
Ŋ U+014A LATIN CAPITAL LETTER ENG N
ŋ U+014B LATIN SMALL LETTER ENG n
Ō U+014C LATIN CAPITAL LETTER O WITH MACRON O
ō U+014D LATIN SMALL LETTER O WITH MACRON o
Ŏ U+014E LATIN CAPITAL LETTER O WITH BREVE O
ŏ U+014F LATIN SMALL LETTER O WITH BREVE o
Ő U+0150 LATIN CAPITAL LETTER O WITH DOUBLE ACUTE O
ő U+0151 LATIN SMALL LETTER O WITH DOUBLE ACUTE o
Ŕ U+0154 LATIN CAPITAL LETTER R WITH ACUTE R
ŕ U+0155 LATIN SMALL LETTER R WITH ACUTE r
Ŗ U+0156 LATIN CAPITAL LETTER R WITH CEDILLA R
ŗ U+0157 LATIN SMALL LETTER R WITH CEDILLA r
Ř U+0158 LATIN CAPITAL LETTER R WITH CARON R
ř U+0159 LATIN SMALL LETTER R WITH CARON r
Ś U+015A LATIN CAPITAL LETTER S WITH ACUTE S
ś U+015B LATIN SMALL LETTER S WITH ACUTE s
Ŝ U+015C LATIN CAPITAL LETTER S WITH CIRCUMFLEX S
ŝ U+015D LATIN SMALL LETTER S WITH CIRCUMFLEX s
Ş U+015E LATIN CAPITAL LETTER S WITH CEDILLA S
ş U+015F LATIN SMALL LETTER S WITH CEDILLA s
Š U+0160 LATIN CAPITAL LETTER S WITH CARON S
š U+0161 LATIN SMALL LETTER S WITH CARON s
Ţ U+0162 LATIN CAPITAL LETTER T WITH CEDILLA T
ţ U+0163 LATIN SMALL LETTER T WITH CEDILLA t
Ť U+0164 LATIN CAPITAL LETTER T WITH CARON T
ť U+0165 LATIN SMALL LETTER T WITH CARON t
Ŧ U+0166 LATIN CAPITAL LETTER T WITH STROKE T
ŧ U+0167 LATIN SMALL LETTER T WITH STROKE t
Ũ U+0168 LATIN CAPITAL LETTER U WITH TILDE U
ũ U+0169 LATIN SMALL LETTER U WITH TILDE u
Ū U+016A LATIN CAPITAL LETTER U WITH MACRON U
ū U+016B LATIN SMALL LETTER U WITH MACRON u
Ŭ U+016C LATIN CAPITAL LETTER U WITH BREVE U
ŭ U+016D LATIN SMALL LETTER U WITH BREVE u
Ů U+016E LATIN CAPITAL LETTER U WITH RING ABOVE U
ů U+016F LATIN SMALL LETTER U WITH RING ABOVE u
Ű U+0170 LATIN CAPITAL LETTER U WITH DOUBLE ACUTE U
ű U+0171 LATIN SMALL LETTER U WITH DOUBLE ACUTE u
Ų U+0172 LATIN CAPITAL LETTER U WITH OGONEK U
ų U+0173 LATIN SMALL LETTER U WITH OGONEK u
Ŵ U+0174 LATIN CAPITAL LETTER W WITH CIRCUMFLEX W
ŵ U+0175 LATIN SMALL LETTER W WITH CIRCUMFLEX w
Ŷ U+0176 LATIN CAPITAL LETTER Y WITH CIRCUMFLEX Y
ŷ U+0177 LATIN SMALL LETTER Y WITH CIRCUMFLEX y
Ÿ U+0178 LATIN CAPITAL LETTER Y WITH DIAERESIS Y
Ź U+0179 LATIN CAPITAL LETTER Z WITH ACUTE Z
ź U+017A LATIN SMALL LETTER Z WITH ACUTE z
Ż U+017B LATIN CAPITAL LETTER Z WITH DOT ABOVE Z
ż U+017C LATIN SMALL LETTER Z WITH DOT ABOVE z
Ž U+017D LATIN CAPITAL LETTER Z WITH CARON Z
ž U+017E LATIN SMALL LETTER Z WITH CARON z
ſ U+017F LATIN SMALL LETTER LONG S s

Letters with no one-letter answer

Character Code point Name Becomes
Æ U+00C6 LATIN CAPITAL LETTER AE AE
Þ U+00DE LATIN CAPITAL LETTER THORN TH
ß U+00DF LATIN SMALL LETTER SHARP S ss
æ U+00E6 LATIN SMALL LETTER AE ae
þ U+00FE LATIN SMALL LETTER THORN th
IJ U+0132 LATIN CAPITAL LIGATURE IJ IJ
ij U+0133 LATIN SMALL LIGATURE IJ ij
ʼn U+0149 LATIN SMALL LETTER N PRECEDED BY APOSTROPHE 'n
Œ U+0152 LATIN CAPITAL LIGATURE OE OE
œ U+0153 LATIN SMALL LIGATURE OE oe

Greek capitals

Character Code point Name Becomes
Α U+0391 GREEK CAPITAL LETTER ALPHA A
Β U+0392 GREEK CAPITAL LETTER BETA B
Γ U+0393 GREEK CAPITAL LETTER GAMMA G
Δ U+0394 GREEK CAPITAL LETTER DELTA D
Ε U+0395 GREEK CAPITAL LETTER EPSILON E
Ζ U+0396 GREEK CAPITAL LETTER ZETA Z
Η U+0397 GREEK CAPITAL LETTER ETA E
Θ U+0398 GREEK CAPITAL LETTER THETA T
Ι U+0399 GREEK CAPITAL LETTER IOTA I
Κ U+039A GREEK CAPITAL LETTER KAPPA K
Λ U+039B GREEK CAPITAL LETTER LAMDA L
Μ U+039C GREEK CAPITAL LETTER MU U
Ν U+039D GREEK CAPITAL LETTER NU N
Ξ U+039E GREEK CAPITAL LETTER XI X
Ο U+039F GREEK CAPITAL LETTER OMICRON O
Π U+03A0 GREEK CAPITAL LETTER PI P
Ρ U+03A1 GREEK CAPITAL LETTER RHO R
Σ U+03A3 GREEK CAPITAL LETTER SIGMA S
Τ U+03A4 GREEK CAPITAL LETTER TAU T
Υ U+03A5 GREEK CAPITAL LETTER UPSILON U
Φ U+03A6 GREEK CAPITAL LETTER PHI F
Χ U+03A7 GREEK CAPITAL LETTER CHI C
Ψ U+03A8 GREEK CAPITAL LETTER PSI Y
Ω U+03A9 GREEK CAPITAL LETTER OMEGA O

Greek small letters

Character Code point Name Becomes
α U+03B1 GREEK SMALL LETTER ALPHA a
β U+03B2 GREEK SMALL LETTER BETA b
γ U+03B3 GREEK SMALL LETTER GAMMA g
δ U+03B4 GREEK SMALL LETTER DELTA d
ε U+03B5 GREEK SMALL LETTER EPSILON e
ζ U+03B6 GREEK SMALL LETTER ZETA z
η U+03B7 GREEK SMALL LETTER ETA e
θ U+03B8 GREEK SMALL LETTER THETA t
ι U+03B9 GREEK SMALL LETTER IOTA i
κ U+03BA GREEK SMALL LETTER KAPPA k
λ U+03BB GREEK SMALL LETTER LAMDA l
μ U+03BC GREEK SMALL LETTER MU u
ν U+03BD GREEK SMALL LETTER NU n
ξ U+03BE GREEK SMALL LETTER XI x
ο U+03BF GREEK SMALL LETTER OMICRON o
π U+03C0 GREEK SMALL LETTER PI p
ρ U+03C1 GREEK SMALL LETTER RHO r
ς U+03C2 GREEK SMALL LETTER FINAL SIGMA s
σ U+03C3 GREEK SMALL LETTER SIGMA s
τ U+03C4 GREEK SMALL LETTER TAU t
υ U+03C5 GREEK SMALL LETTER UPSILON u
φ U+03C6 GREEK SMALL LETTER PHI f
χ U+03C7 GREEK SMALL LETTER CHI c
ψ U+03C8 GREEK SMALL LETTER PSI y
ω U+03C9 GREEK SMALL LETTER OMEGA o

A Greek letter with a second code point

Character Code point Name Becomes
µ U+00B5 MICRO SIGN u

Normalize Characters

73 characters, every one of them replaced by plain ASCII. From macros/commands/normalize-characters.nm.

Dashes and hyphens

Character Code point Name Becomes
‐ U+2010 HYPHEN -
‑ U+2011 NON-BREAKING HYPHEN -
‒ U+2012 FIGURE DASH -
– U+2013 EN DASH -
— U+2014 EM DASH -
― U+2015 HORIZONTAL BAR -
⁃ U+2043 HYPHEN BULLET -
− U+2212 MINUS SIGN -
﹘ U+FE58 SMALL EM DASH -
﹣ U+FE63 SMALL HYPHEN-MINUS -
- U+FF0D FULLWIDTH HYPHEN-MINUS -

Single quotes, apostrophes, primes

Character Code point Name Becomes
´ U+00B4 ACUTE ACCENT '
ʹ U+02B9 MODIFIER LETTER PRIME '
ʼ U+02BC MODIFIER LETTER APOSTROPHE '
‘ U+2018 LEFT SINGLE QUOTATION MARK '
’ U+2019 RIGHT SINGLE QUOTATION MARK '
‚ U+201A SINGLE LOW-9 QUOTATION MARK '
‛ U+201B SINGLE HIGH-REVERSED-9 QUOTATION MARK '
′ U+2032 PRIME '
‵ U+2035 REVERSED PRIME '
' U+FF07 FULLWIDTH APOSTROPHE '

Double quotes and double primes

Character Code point Name Becomes
ʺ U+02BA MODIFIER LETTER DOUBLE PRIME "
“ U+201C LEFT DOUBLE QUOTATION MARK "
” U+201D RIGHT DOUBLE QUOTATION MARK "
„ U+201E DOUBLE LOW-9 QUOTATION MARK "
‟ U+201F DOUBLE HIGH-REVERSED-9 QUOTATION MARK "
″ U+2033 DOUBLE PRIME "
‶ U+2036 REVERSED DOUBLE PRIME "
" U+FF02 FULLWIDTH QUOTATION MARK "

Spaces

Character Code point Name Becomes
(not printable) U+00A0 NO-BREAK SPACE a space
(not printable) U+1680 OGHAM SPACE MARK a space
(not printable) U+2000 EN QUAD a space
(not printable) U+2001 EM QUAD a space
(not printable) U+2002 EN SPACE a space
(not printable) U+2003 EM SPACE a space
(not printable) U+2004 THREE-PER-EM SPACE a space
(not printable) U+2005 FOUR-PER-EM SPACE a space
(not printable) U+2006 SIX-PER-EM SPACE a space
(not printable) U+2007 FIGURE SPACE a space
(not printable) U+2008 PUNCTUATION SPACE a space
(not printable) U+2009 THIN SPACE a space
(not printable) U+200A HAIR SPACE a space
(not printable) U+202F NARROW NO-BREAK SPACE a space
(not printable) U+205F MEDIUM MATHEMATICAL SPACE a space
(not printable) U+3000 IDEOGRAPHIC SPACE a space

Invisible characters, deleted outright

Character Code point Name Becomes
(not printable) U+00AD SOFT HYPHEN removed
(not printable) U+200B ZERO WIDTH SPACE removed
(not printable) U+200C ZERO WIDTH NON-JOINER removed
(not printable) U+200D ZERO WIDTH JOINER removed
(not printable) U+2060 WORD JOINER removed
(not printable) U+FEFF ZERO WIDTH NO-BREAK SPACE (BOM) removed

Line separators

Character Code point Name Becomes
(not printable) U+2028 LINE SEPARATOR a newline
(not printable) U+2029 PARAGRAPH SEPARATOR a newline

Ligatures

Character Code point Name Becomes
ff U+FB00 LATIN SMALL LIGATURE FF ff
fi U+FB01 LATIN SMALL LIGATURE FI fi
fl U+FB02 LATIN SMALL LIGATURE FL fl
ffi U+FB03 LATIN SMALL LIGATURE FFI ffi
ffl U+FB04 LATIN SMALL LIGATURE FFL ffl
ſt U+FB05 LATIN SMALL LIGATURE LONG S T st
st U+FB06 LATIN SMALL LIGATURE ST st

Other punctuation

Character Code point Name Becomes
• U+2022 BULLET *
… U+2026 HORIZONTAL ELLIPSIS ...
× U+00D7 MULTIPLICATION SIGN x
÷ U+00F7 DIVISION SIGN /
⁄ U+2044 FRACTION SLASH /
∕ U+2215 DIVISION SLASH /

Math relations

Character Code point Name Becomes
± U+00B1 PLUS-MINUS SIGN +/-
∓ U+2213 MINUS-OR-PLUS SIGN -/+
≈ U+2248 ALMOST EQUAL TO ~
∼ U+223C TILDE OPERATOR ~
≠ U+2260 NOT EQUAL TO !=
≤ U+2264 LESS-THAN OR EQUAL TO <=
≥ U+2265 GREATER-THAN OR EQUAL TO >=

How the letters were chosen

Normalize Characters' table is a lookup: an en dash has one obvious ASCII spelling and that is the end of it. Fold Letters to ASCII is a set of judgement calls.

Accented letters

An accented letter becomes its base letter and keeps its case: Balázs becomes Balazs, Ångström becomes Angstrom. For the 161 letters that have a Unicode decomposition, the replacement is the first character of it. The other 19 do not decompose and were set by hand, among them Ø to O, ð to d, ı to i and Ł to L.

Ten letters have no one-letter answer and get longer instead:

Character Becomes
Æ æ AE ae
Œ œ OE oe
Þ þ TH th
ß ss
IJ ij IJ ij
ʼn 'n

These are the only rows that widen a line. A capital expands to two capitals, so Ærø comes out AEro rather than Æro; title-casing it would mean looking at the character after it, and that is a second rule the table cannot carry. They lengthen rather than fold because they turn up in names, where Weiß to Weis is a misspelling and Weiss is not.

An accent fold is silent

A Greek letter gets a report. An accented letter does not. Balázs becomes Balazs, the terminal names U+00E1, and nothing in the file itself records that the accent was ever there. Keep the original if the spelling of a name matters.

Greek letters

A Greek letter becomes the first letter of its English name, keeping its case, so α becomes a and Δ becomes D.

Α α → A a Β β → B b Γ γ → G g Δ δ → D d Ε ε → E e Ζ ζ → Z z
Η η → E e Θ θ → T t Ι ι → I i Κ κ → K k Λ λ → L l Μ μ → U u
Ν ν → N n Ξ ξ → X x Ο ο → O o Π π → P p Ρ ρ → R r Σ σ → S s
Τ τ → T t Υ υ → U u Φ φ → F f Χ χ → C c Ψ ψ → Y y Ω ω → O o

Three of those are not the first letter of the name:

μ and Μ give u, not m. 24 µm turning into 24 mm is a factor of a thousand in a column of wavelengths, and mm is a real unit, so nothing downstream would catch it. um is the usual ASCII spelling in this field. U+00B5 MICRO SIGN gives the same answer as U+03BC GREEK SMALL LETTER MU, so the reading does not depend on which of the two the PDF happened to emit.

φ gives f and ψ gives y, because π already has p. y is psi's letter in Beta Code.

Five readings collide, and nothing can tell a pair apart afterwards:

Reading Comes from
e epsilon, eta
o omicron, omega
s sigma, final sigma
t tau, theta
u upsilon, mu

That is why every Greek letter the macro replaces is listed in the terminal with the line and column it was on, and why the cursor lands on the first one. Read that list before the file goes any further. σ and ς both giving s also means word-final position is not recoverable, so do not reach for this macro on Greek prose; it is built for a data column.

Two published schemes avoid the collisions and are not used here. Beta Code (ω to W) is bijective, so the original is always recoverable, and ISO 843 (β to v) follows modern Greek pronunciation; both need a reader who knows the standard before an astronomy file makes sense. Spelling the name out, α to alpha, would widen the line, and the point of running this before the pipes go in is that nothing moves.

Every Greek letter is in the table, including the fourteen that look like a Latin letter already. Ο U+039F is pixel-identical to O, and nothing downstream will match it, so leaving it alone would leave an invisible fault rather than avoid one.

What is left alone

Nothing here has a safe ASCII spelling, so both commands leave it exactly as it is. Guessing would quietly corrupt data, which is worse than leaving a character that at least looks wrong.

Character Why it stays
° U+00B0 DEGREE SIGN deg, d and o all appear in real files. Picking one would silently change what the number means.
Ω U+2126 OHM SIGN A unit symbol with its own code point, not a letter, and folding it to O would destroy it. Greek Ω U+03A9 is a different character and Fold Letters to ASCII does replace that one.
ά έ ώ accented Greek Never seen in this data, so it is not in either table.
≪ ≫ ∝ ≃ and other relations not in the table Add them if your files use them consistently.
Bytes that are not valid UTF-8 XNEdit replaces each byte it cannot decode with U+FFFD REPLACEMENT CHARACTER as it reads the file, and locks the buffer, so both commands refuse the file rather than reach the byte. See when the file is locked.

Normalize Characters is the command that reports these. After it runs it counts what is left, puts the cursor on the first one, and lists them in the terminal with a count per character, so each case can be decided by hand. That count includes the accented and Greek letters until you run Fold Letters to ASCII, which is what makes the report a pointer to the second command rather than a dead end.

Fold Letters to ASCII says nothing about what it left. It only ever reports the Greek it replaced, because that is the one thing it does that cannot be reversed by reading the result.

What is deliberately not automated

A ##refcode of 2026A+A...707A..13L should read 2026A&A...707A..13L. That is a plain ASCII + standing in for &, not an encoding problem, and it is not in the table on purpose: a blanket + to & replacement would destroy every positive declination in the file. Fix refcodes by hand.

Adding a character

A punctuation character goes in macros/commands/normalize-characters.nm, as two lines keyed on its UTF-8 bytes:

fix["\xe2\x80\x93"] = "-"
nam["\xe2\x80\x93"] = "U+2013 EN DASH"

A letter goes in macros/commands/fold-letters-to-ascii.nm, as one line. That macro carries no nam[] labels, because 240 entries plus a label each will not fit in the 4096 instructions a macro gets, and tools/gen_docs.py works the Unicode name out from the key instead:

fix["\xc3\xa9"] = "e"

Either way fix[] is where a new character goes. grk[] is the second table in the fold macro, and it exists because the macro records where each Greek letter sits before it replaces it, which is what lets the report give a line and column. That arithmetic assumes every grk[] replacement is exactly one character, so a character that replaces to more or fewer belongs in fix[] whatever it is. fix[] runs first and nothing measures it.

Both macros still have room, but a macro compiles into 4096 instructions and no more, and past that the editor refuses it with macro too large at parse time. Do not work from a headroom figure written on a page: every edit to either macro moves it. test_command_has_room_to_grow asks the editor instead, padding each command with 40 more assignments and failing while there is still room to act. The answer then is a third command rather than a bigger table, the way Fold Letters to ASCII was split off in the first place.

Get the bytes with:

python3 -c 'print("".join("\\x%02x" % b for b in chr(0x2013).encode()))'

Then regenerate this page:

uv run python tools/gen_docs.py

Keys are written as escapes rather than as literal characters so the macro survives being pasted through the Customize Menus dialog, and so the entries you cannot see stay readable in the source. Order does not matter, because every replacement is ASCII and no entry can feed another.

Keep the layout of the tables as it is. The group heading is the comment line directly above a fix[...] or grk[...] line with no blank line between them, and that is how tools/gen_docs.py tells a heading apart from ordinary prose earlier in the file.

Two things to watch if you edit either macro:

  • The search type must stay "case". NEdit's "literal" is case-insensitive, and XNEdit folds case over UTF-8, where uppercasing the fi ligature gives the two characters FI. A "literal" search for a multi-byte character can match text you never intended, and with both cases of every Greek letter in the table, a "literal" search for α matches Α. nedkit.checks fails the build over this rather than leaving it to review.
  • replace_in_string() needs its "copy" argument. Without it the call returns an empty string whenever the pattern does not match, and the loop would erase the buffer on its first miss.