1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18\startluacode
19
20moduledata.morse = moduledata.morse or { }
21local morse = moduledata.morse
22
23local utfcharacters, gsub = string.utfcharacters, string.gsub
24local ucchars, shchars = characters.ucchars, characters.shchars
25
26local codes = {
27
28 ["A"] = "·—",
29 ["B"] = "—···",
30 ["C"] = "—·—·",
31 ["D"] = "—··",
32 ["E"] = "·",
33 ["F"] = "··—·",
34 ["G"] = "——·",
35 ["H"] = "····",
36 ["I"] = "··",
37 ["J"] = "·———",
38 ["K"] = "—·—",
39 ["L"] = "·—··",
40 ["M"] = "——",
41 ["N"] = "—·",
42 ["O"] = "———",
43 ["P"] = "·——·",
44 ["Q"] = "——·—",
45 ["R"] = "·—·",
46 ["S"] = "···",
47 ["T"] = "—",
48 ["U"] = "··—",
49 ["V"] = "···—",
50 ["W"] = "·——",
51 ["X"] = "—··—",
52 ["Y"] = "—·——",
53 ["Z"] = "——··",
54
55 ["0"] = "—————",
56 ["1"] = "·————",
57 ["2"] = "··———",
58 ["3"] = "···——",
59 ["4"] = "····—",
60 ["5"] = "·····",
61 ["6"] = "—····",
62 ["7"] = "——···",
63 ["8"] = "———··",
64 ["9"] = "————·",
65
66 ["."] = "·—·—·—",
67 [","] = "——··——",
68 [":"] = "———···",
69 [";"] = "—·—·—",
70
71 ["?"] = "··——··",
72 ["!"] = "—·—·——",
73
74 ["-"] = "—····—",
75 ["/"] = "—··—· ",
76
77 ["("] = "—·——·",
78 [")"] = "—·——·—",
79
80 ["="] = "—···—",
81 ["@"] = "·——·—·",
82
83 ["'"] = "·————·",
84 ['"'] = "·—··—·",
85
86 ["À"] = "·——·—",
87 ["Å"] = "·——·—",
88 ["Ä"] = "·—·—",
89 ["Æ"] = "·—·—",
90 ["Ç"] = "—·—··",
91 ["É"] = "··—··",
92 ["È"] = "·—··—",
93 ["Ñ"] = "——·——",
94 ["Ö"] = "———·",
95 ["Ø"] = "———·",
96 ["Ü"] = "··——",
97 ["ß"] = "··· ···",
98
99}
100
101morse.codes = codes
102
103local fallbackself = false
104
105local function codefallback(t,k)
106 if k then
107 local u = ucchars[k]
108 local v = rawget(t,u) or rawget(t,shchars[u]) or false
109 t[k] = v
110 return v
111 elseif fallbackself then
112 return k
113 else
114 return false
115 end
116end
117
118table.setmetatableindex(codes,codefallback)
119
120local MorseBetweenWords = context.MorseBetweenWords
121local MorseBetweenCharacters = context.MorseBetweenCharacters
122local MorseLong = context.MorseLong
123local MorseShort = context.MorseShort
124local MorseSpace = context.MorseSpace
125local MorseUnknown = context.MorseUnknown
126
127local function toverbose(str)
128 str = gsub(str,"%s*+%s*","+")
129 str = gsub(str,"%s+"," ")
130 local done = false
131 for m in utfcharacters(str) do
132 if done then
133 MorseBetweenCharacters()
134 end
135 if m == "·" or m == "." then
136 MorseShort()
137 done = true
138 elseif m == "—" or m == "-" then
139 MorseLong()
140 done = true
141 elseif m == " " then
142 if done then
143 MorseBetweenCharacters()
144 end
145 done = false
146 elseif m == "+" then
147 MorseBetweenWords()
148 done = false
149 else
150 MorseUnknown(m)
151 end
152 end
153end
154
155local function toregular(str)
156 local inmorse = false
157 for s in utfcharacters(str) do
158 local m = codes[s]
159 if m then
160 if inmorse then
161 MorseBetweenWords()
162 else
163 inmorse = true
164 end
165 local done = false
166 for m in utfcharacters(m) do
167 if done then
168 MorseBetweenCharacters()
169 else
170 done = true
171 end
172 if m == "·" then
173 MorseShort()
174 elseif m == "—" then
175 MorseLong()
176 elseif m == " " then
177 MorseBetweenCharacters()
178 end
179 end
180 inmorse = true
181 elseif s == "\n" or s == " " then
182 MorseSpace()
183 inmorse = false
184 else
185 if inmorse then
186 MorseBetweenWords()
187 else
188 inmorse = true
189 end
190 MorseUnknown(s)
191 end
192 end
193end
194
195local function tomorse(str,verbose)
196 if verbose then
197 toverbose(str)
198 else
199 toregular(str)
200 end
201end
202
203morse.tomorse = tomorse
204
205function morse.filetomorse(name,verbose)
206 tomorse(resolvers.loadtexfile(name),verbose)
207end
208
209function morse.showtable()
210 context.starttabulate { "|l|l|" }
211 for k, v in table.sortedpairs(codes) do
212 context.NC() context(k)
213
214 context.NC() tomorse(v,true)
215 context.NC() context.NR()
216 end
217 context.stoptabulate()
218end
219
220\stopluacode
221
222\unprotect
223
224
225
226\def\MorseWidth {0.4em}
227\def\MorseHeight {0.2em}
228
229
230\def\MorseShort {\dontleavehmode\vrule\s!width \dimexpr\MorseWidth\s!height\MorseHeight\s!depth\zeropoint\relax}
231\def\MorseLong {\dontleavehmode\vrule\s!width3\dimexpr\MorseWidth\s!height\MorseHeight\s!depth\zeropoint\relax}
232\def\MorseBetweenCharacters {\kern\MorseWidth}
233\def\MorseBetweenWords {\hskip3\dimexpr\MorseWidth\relax}
234\def\MorseSpace {\hskip7\dimexpr\MorseWidth\relax}
235\def\MorseUnknown #text{[\detokenize{#text}]}
236
237\unexpanded\def\MorseCode #text{\ctxlua{moduledata.morse.tomorse(\!!bs#text\!!es,true)}}
238\unexpanded\def\MorseString #text{\ctxlua{moduledata.morse.tomorse(\!!bs#text\!!es)}}
239\unexpanded\def\MorseFile #text{\ctxlua{moduledata.morse.filetomorse("#text")}}
240\unexpanded\def\MorseTable {\ctxlua{moduledata.morse.showtable()}}
241
242\let\Morse \MorseString
243
244
245
246
247\protect
248
249\continueifinputfile{mmorse.mkvi}
250
251\starttext
252
253\MorseTable
254
255\startlines
256\MorseCode{—·—· ——— —· — · —··— ——— —·— ·· ···—}
257\MorseCode{—·—· ——— —· — · —··— — —— —·— ·· ···—}
258\Morse{ÀÁÂÃÄÅàáâãäå}
259\Morse{ÆÇæç}
260\Morse{ÈÉÊËèéêë}
261\Morse{ÌÍÎÏìíîï}
262\Morse{Ññ}
263\Morse{ÒÓÔÕÖòóôõö}
264\Morse{Øø}
265\Morse{ÙÚÛÜùúû}
266\Morse{Ýýÿ}
267\Morse{ß}
268\Morse{Ţţ}
269\stoplines
270
271\Morse{A B C D E F G H I J K L M N O P Q R S T U V W X Y Z}
272
273\stoptext
274 |