5 <meta name=
"viewport" content=
"width=device-width, initial-scale=1, shrink-to-fit=no">
6 <title>NATO Phonetic Alphabet Speller
</title>
7 <!-- The page supports both light and dark color schemes, with light being default -->
8 <meta name=
"color-scheme" content=
"light dark">
10 <!-- Bootstrap CSS (as per normal) -->
11 <link href=
"https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel=
"stylesheet">
12 <!-- Add the Bootstrap-Nightfall Variant CSS (the media attribute is for dark auto-switching) -->
13 <link href=
"https://cdn.jsdelivr.net/npm/bootstrap-dark-5@1.1.3/dist/css/bootstrap-nightfall.min.css" rel=
"stylesheet" media=
"(prefers-color-scheme: dark)">
15 <!-- Optional Meta Theme Color is also supported on Safari and Chrome -->
16 <meta name=
"theme-color" content=
"#111111" media=
"(prefers-color-scheme: light)">
17 <meta name=
"theme-color" content=
"#eeeeee" media=
"(prefers-color-scheme: dark)">
21 'a': 'Alpha', 'b': 'Bravo', 'c': 'Charlie', 'd': 'Delta',
22 'e': 'Echo', 'f': 'Foxtrot', 'g': 'Golf', 'h': 'Hotel',
23 'i': 'India', 'j': 'Juliet', 'k': 'Kilo', 'l': 'Lima',
24 'm': 'Mike', 'n': 'November', 'o': 'Oscar', 'p': 'Papa',
25 'q': 'Quebec', 'r': 'Romeo', 's': 'Sierra', 't': 'Tango',
26 'u': 'Uniform', 'v': 'Victor', 'w': 'Whiskey', 'x': 'Xray',
27 'y': 'Yankee', 'z': 'Zulu', '0': 'Zero', '1': 'One',
28 '2': 'Two', '3': 'Three', '4': 'Four', '5': 'Five',
29 '6': 'Six', '7': 'Seven', '8': 'Eight', '9': 'Niner',
31 return tbl
[c
.toLowerCase()];
34 function str2nato(nmode
='NFD') {
38 //case 'NFKC': Do not use, will mangle output with no benefit
41 console
.log('str2nato: nmode isn\'t one of NFC, NFD, NFKD. Defaulting to NFD');
45 /* Normalize to base letter + combining marks and remove marks; this effectively
46 removes accents. Default is NFD, We could decompose even further using NFKD.
47 The *C modes recompose characters and prevent base letters from being translated.
48 For more info on normalisation forms see: https://unicode.org/reports/tr15/
50 var src
= document
.getElementById('src').value
.normalize(nmode
).replace(/[\u0300-\u036f]/g, '');
54 // Convert to array to handle multiplanar unicode (those won't be converted
55 // but they will be copied as-is correctly)
57 for (i
=0; i
<clist
.length
; i
++) {
58 /* Counting the previous Nato word's a single space becomes 3; Turns out
59 3 space makes a nice separation of word so don't skip spaces (commented)
61 continue; // Skip spaces, we already add them */
63 /* Multiplanar falls into last statement, but if we need it in the future...
64 if (clist[i].length > 1)
65 dst += clist[i] + ' '; // Multiplanar unicode.. (ex. emojis) */
68 dst
+= '\n'; // No space after newline
69 else if ((c
= nato(clist
[i
])) !== undefined)
72 dst
+= clist
[i
] + ' ';
74 document
.getElementById('nato').value
= dst
;
79 <div class=
"w-75 container-fluid">
80 <h3>NATO Phonetic Alphabet Speller
</h3>
81 <!-- TODO: add unicode combination mode selector:
82 NFC: Do not decompose (accents and special chars primted as-is
83 NFD: Reversible decompose (ligatures and special character form retained_
84 NFKD: Decompose all characters
86 <p>Enter text to be converted:
<br>
87 <textarea class=
"form-control" rows=
"10" id=
"src" autofocus
onchange=
"str2nato(nmode='NFD')" onkeyup=
"str2nato()"></textarea>
88 <p><button type=
"button" class=
"btn btn-primary" onclick=
"var d=document.getElementById('src'); d.value = ''; str2nato(); d.focus();">Clear
</button>
90 <textarea class=
"form-control" rows=
20 id=
"nato" readonly
></textarea>
93 <!-- vim:set filetype=html.javascript: -->