m-morse.mkvi /size: 7232 b    last modification: 2021-10-28 13:51
1%D \module
2%D   [       file=m-morse,
3%D        version=2010.12.10,
4%D          title=\CONTEXT\ Extra Modules,
5%D       subtitle=Morse,
6%D         author=Hans Hagen,
7%D           date=\currentdate,
8%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
9%C
10%C This module is part of the \CONTEXT\ macro||package and is
11%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
12%C details.
13
14% todo: act upon the node list
15% make it a buffer operation
16% nice in cld manual
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|" } -- { "|l|l|l|" }
211    for k, v in table.sortedpairs(codes) do
212        context.NC() context(k)
213     -- context.NC() context(v)
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% todo: \setupmorse, but probably it's not worth the trouble.
225
226\def\MorseWidth             {0.4em}
227\def\MorseHeight            {0.2em}
228%def\MorseShort             {\dontleavehmode\blackrule[\c!height=\MorseHeight,\c!width=\dimexpr\MorseWidth]}
229%def\MorseLong              {\dontleavehmode\blackrule[\c!height=\MorseHeight,\c!width=3\dimexpr\MorseWidth]}
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%def\MorseShort             {·}
245%def\MorseLong              {—}
246
247\protect
248
249\continueifinputfile{m-morse.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