1# alphabet -- xstroke alphabet configuration file
2#
3# xstroke is available from ftp://ftp.handhelds.org/pub/projects/xstroke
4#
5# Rather than hacking this file directly, you probably want to start
6# with a file ~/.xstroke/alphabet that consists of a single line:
7#
8# 	include "/etc/xstroke/alphabet"
9#
10# Then, you may add your custom strokes to that file, (you'll want to
11# add them before the include line so that your custom strokes take
12# precedence over the strokes defined in /etc/xstroke/alphabet).
13
14# Here is a summary of the syntax of this file:
15
16# Blank lines are ignored.
17# Lines beginning with a '#' character are comments and are ignored.
18
19# INCLUDE STATEMENTS:
20#
21# An include statement looks like this: include "/path/to/some/file" It
22# will open and read the file, which should have the same syntax as
23# this file. File may be included to arbitrarily deep levels, but no
24# checks are made to avoid infinite include loops, so Don't Do That.
25
26# MODE DEFINITIONS:
27#
28# The alphabet file consists of a series of mode definitions which
29# will have the following form:
30#
31#	Mode <MODE_NAME> [: <PARENT_MODE_NAME>, ... ]{
32#		<stroke_definition>
33#		...
34#	}
35#
36# Where all mode names are quoted strings.
37#
38# xstroke always has one active mode, (whose name will be displayed in
39# the control window). The user may change the active mode by using
40# ModeShift and ModeLock strokes defined within the active mode, (or
41# one of its parents).
42#
43# There are two mode names that have special meaning: __GLOBAL__ and
44# __FALLBACK__. Strokes defined within the __GLOBAL__ mode take
45# precedence over any strokes defined within the active mode. Strokes
46# defined within __FALLBACK__ are available in all modes, but at a
47# precedence lower than any other stroke within the mode.
48#
49# The logic used to search for recognized strokes is as follows: When
50# the user enters a stroke, a probability is computed for each
51# candidate stroke definition. The stroke definition with the highest
52# probability is then returned. For the purpose of resolving stroke
53# definitions with equal probabilities, the first definition
54# encountered will be returned. Strokes within each mode are searched
55# in the same order they are processed within the alphabet file. Modes
56# are searched in the following order: the __GLOBAL__ mode, the active
57# mode, the parents of the active mode (and recursively, all of their
58# parents in depth-first order), and finally the __FALLBACK__ mode.
59
60# STROKE DEFINITIONS:
61#
62# The meat of the alphabet file is stroke definitions of the form:
63#
64#	<action> = <stroke_regex>
65#
66# where <action> can be any of the following:
67#
68#	Key <keysym>
69#	Button <button number>
70#	ModeShift <mode_name>
71#	ModeLock <mode_name>
72#	Exec <program args...>
73#
74# The Key action emits a key press, (and release), event for the given
75# keysym. You can find keysyms in /usr/include/X11/keysymdef.h, just
76# drop the "XK_" prefix. Modifier keysyms may also be listed and they
77# will do the Right Thing, (ie. they won't immediately cause a key
78# press but will rather modify the next Key stroke).
79#
80# The Button action emits a button press, (and release), event at
81# the location of the pointer at the end of the stroke.
82#
83# The ModeShift action performs a temporary change of the active mode
84# to the given mode. After the next stroke, (whether successful or
85# not), the active mode will revert to the current mode. (Modifier Key
86# actions do not cause the mode to revert).
87#
88# The ModeLock action performs a persistent change of the active mode
89# to the given mode. It will remain in effect until the next ModeLock
90# action.
91#
92# The Exec action will cause the given command to be invoked. The
93# command will be executed using /bin/sh so shell tricks are
94# available.
95#
96# <stroke_regex> is a modern regular expression (see regex(7))
97# consisting primarily of the the characters `, ^, ', >, l, v, /, <.
98# These expression is the sequence of slopes that appear in the stroke
99# with each character representing one of the 8 major directions as
100# shown in the following diagram:
101#
102#	` ^ '
103#	<   >
104#	/ v l
105#
106# Hopefully the shape of each character will server as an easy
107# mnemonic for the direction it represents.(I know that 'l' is a weak
108# mnemonic but '\' wouldn't work as it would have to be represented as
109# "\\" which is even worse than 'l').
110#
111# For example, an intuitive stroke for the letter L might be:
112#
113#	Key L = dir ( "v>" )
114#
115# Notice that the characters 'v' and '>' describe the path of an 'L'
116# shape, ie. down, then right. This simple stroke is sufficient for
117# defining an basic L, but unless you make an exceptionally sharp turn
118# whenever you make an 'L', you will dint that the recognized stroke
119# will often be "vl>", (ie. there is a smoother transition from down
120# to right). The regular expression syntax makes it easy to define
121# robust strokes that encompass both variations. For example, you
122# could make the 'l' optional like so:
123#
124#	Key L = dir ( "vl?>" )
125#
126# Other regular expression features such as character classes (`[' and
127# `]'), and repetition, ('*', '+'), may also be used as needed to define
128# more reliable strokes.
129#
130# Feel free to let me know any comments/suggestions you might have.
131# Have fun!
132#
133# -Carl Worth <cworth@handhelds.org>
134
135Engine dir_length { }
136#Engine grid { }
137
138Engine anchor {
139	Option "BorderWidthPercent" "5"
140}
141
142# First, the strokes for the global mode
143Mode "__GLOBAL__" {
144  Key BackSpace, OrientationCorrection 180 = {
145	dir("<")
146	doc("654")
147  }
148  Key Return = {
149	dir("/")
150	doc("357")
151  }
152  Key Control_L = {
153	dir("/<`^'>l")
154	grid("[^5]*")
155	dir("/?<`^'>l?")
156	doc("9823")
157  }
158
159  Key Meta_L = {
160	dir("'?^`</v^`</vl?")
161	doc("96[23]5[58]8[58]5[12]47")
162  }
163
164  # Full-screen bottom-to-top gives help
165  Exec "xstroke-help" = {
166	dir("`l")
167	anchor("852")
168  }
169
170  # Bit of a kludge to be including keybindings for ion here, but I like 'em.
171  Key Super_L, Key s = {
172	dir(">")
173	anchor("456")
174  }
175  Key Super_L, Key k, Key s = {
176	dir("v")
177	anchor("258")
178  }
179  Key Super_L, Key k, Key x = {
180	dir("'")
181	anchor("7[48]?5[26]?3")
182  }
183}
184
185# And some convenient fallbacks, (like __GLOBAL__ except they can be overridden)
186Mode "__FALLBACK__" {
187  Key space, OrientationCorrection 0 =  { dir(">") doc("456") }
188
189  # Pass short taps through as a button press
190  Button 1 = { dir("") doc("5") }
191}
192
193# Next, the letters. By default, letter mode gets backwards numbers,
194# but none of the backtracking capitals.
195
196Mode "abc" : "numbers_in_letter_mode",
197	     "punctuation_in_letter_mode",
198	     "no_capitals_in_lowercase_mode"
199{
200Exec "xstroke-help" = {
201	dir("`l")
202	doc("95[15]1[15]59")
203}
204
205ModeShift "Abc", Key Shift_L, OrientationCorrection -90 = {
206	dir("^")
207	doc("852")
208}
209ModeShift "123" = {
210	dir("`")
211	doc("951")
212}
213ModeShift "!@#" = {
214	dir("l")
215	doc("159")
216}
217
218### NEWLINE
219
220# stylized A
221Key a = {
222	dir("[^']+>?[lv]+")
223	doc("729:straight")
224}
225# lowercase a
226Key a = {
227	dir("`?</vl>'^vl?")
228	grid("[^5]*[321].*")
229	doc("3286[36]3[36]69")
230}
231
232# B with optional bar
233Key b = {
234#	dir("v?^?.>.v.<>.v.<")
235	dir("v?(/?<?`?|l?>?'?)^?'?(>?lv?|>l?v)/<?(`?^?'?|/?v?l?)>?lv?/<?[`^]*'?")
236	doc("125[45]4[45]587")
237	doc("74125[45]4[45]587")
238	doc("14[47]7[47]4125[45]4[45]587")
239}
240
241# lowercase b
242Key b = {
243	dir("v^'>l?v/?<`?")
244	grid("[^789]*[789][^123]*")
245	doc("14[47]7[47]587")
246}
247
248# the letter c
249Key c = {
250	dir("`?</vl>'?")
251	doc("3289")
252}
253
254# D shape with optional bar
255Key d = {
256	dir("v?`?^?'?>lv?/<`?^?")
257	grid("[^5]*[87]4?")
258	doc("1287")
259	doc("741287")
260	doc("14[47]7[47]41287")
261}
262
263# lowercase d starting with bar
264Key d = {
265	dir("vl?>?'?^`</vl>'?")
266	doc("36[69]9[69][58]9")
267}
268
269# lowercase d starting with circle
270Key d = {
271	dir("`?</?vl>'^v?")
272	grid("[^321]*5.*")
273	doc("[69][58]963")
274	doc("[69][58]96[36]3[36]69")
275}
276
277# stylized E shape like a mirror-image of a 3
278# This is simply the the mirror-image of the B stroke
279Key e = {
280	dir("`?</vl>'?^?`?</vl>'?")
281	doc("325[56]6[56]589")
282}
283
284# lowercase e shape
285Key e = {
286	dir(">'?^`</vl>?'?")
287	doc("45524[78][89]")
288}
289
290# stylized F shape with optional initial curl
291Key f = {
292	dir("^?`?</?v")
293	doc("[23]2[12][14]47")
294	doc("[25][12][14]47")
295}
296
297Key f = {
298	dir("^'?>")
299	doc("7412[23]")
300}
301
302# G shape (in or in-and-out at end)
303Key g = {
304	dir("`?</vl>'^`?</?v?l?>?'?")
305	grid("[^789]*[789][^123]*")
306	doc("[23]24865")
307}
308
309# lowercase g shape with tail to left
310Key g = {
311	dir("`?</vl>'^v/?<?`?")
312	doc("32[25][36]3[36][69][58]")
313}
314
315# typical lowercase h
316Key h = {
317	dir("vl?>?'?(^'?|^?')>lv")
318	grid("[^789]*[789][^123]*")
319	doc("14[47]7[47][58]8")
320}
321
322# i as vertical line down
323Key i, OrientationCorrection 90 = {
324	dir("v")
325	doc("258")
326}
327
328# stylized J shape as backwards L
329Key j = {
330	dir("v/?<")
331	doc("3698[78]")
332}
333
334# loopy sort of k-like shape
335Key k = {
336	dir("v?/<`^?'>lv?")
337	grid(".*5.*")
338	doc("3[56][58][45][25][56]9")
339}
340
341# L shape
342Key l = {
343	dir("vl?>")
344	doc("1478[89]")
345}
346
347# M shape or lowercase m with optional initial down-stroke
348Key m = {
349	dir("v?`?^?'>?v?lv?^?'>?lv?")
350	doc("7[12]8[23]9:straight")
351	doc("74[12]5[58]8[58]5[23]69")
352	doc("14[47]7[47]4[12]5[58]8[58]5[23]69")
353}
354
355# N shape starting at lower-left
356Key n = {
357	dir("^l>?'?^")
358	doc("7193:straight")
359}
360
361# lowercase n
362Key n = {
363	dir("v^'>lv")
364	grid("[^789]*[789].*[123].*")
365	doc("14[47]7[47]4269")
366}
367
368# O as counter-clockwise circle starting at top
369Key o = {
370	dir("<?/vl>'^?`<?/?")
371	doc("248622")
372}
373
374# custom P with just the curved part, drawn backwards, (like backwards D)
375Key p = {
376	dir("l?>'^`</?")
377	grid("[^5]*")
378	doc("7821")
379}
380
381# lowercase P with up-stroke or down-up stroke vertical bar
382Key p = {
383	dir("v?`?^'?>lv/<`?")
384	grid(".*[123][^789]*")
385	doc("741254")
386	doc("14[47]7[47]41254")
387}
388
389# Q as counter-clockwise circle starting at bottom
390Key q = {
391	dir("l?>?'^`</vl>?")
392	doc("862488")
393}
394
395# lowercase q with tail to the right
396Key q = dir("`?</vl>'^vl?>")
397
398# Also, it's not defined until no_capitals_in_lowercase_mode, but I'll
399# display it here:
400Key q = { doc("24862123") }
401
402# lowercase r
403Key r = {
404	dir("v/?<?`?^'?>l?")
405	doc("14[47]7[47]423")
406}
407
408# R shape
409Key r = {
410	dir("v?/?<?`?^'?>lv/<`?^?'?>lv?")
411	doc("74125[45]4[45]5[89]")
412	doc("14[47]7[47]4125[45]4[45]5[89]")
413}
414
415# your basic S shape
416Key s = {
417	dir("`?</vl>?l?v/<`?")
418	doc("325698")
419}
420
421# stylized T as right->down
422Key t = {
423	dir(">l?v")
424	doc("[12]2369")
425}
426
427# u shape
428Key u = {
429	dir("vl>'^v?")
430	doc("148633")
431	doc("1486[36]3[36]69")
432}
433
434# V shape
435Key v = {
436	dir("lv?l?^?'")
437	doc("183:straight")
438}
439
440# V as backwards U
441Key v = {
442	dir("v?/<?(`^?|`?^)")
443	doc("381:straight")
444	doc("368411")
445}
446
447# w or W shape
448Key w = {
449	dir("(v?l|vl?)>?'^?(v?l|vl?)>?'^?")
450	doc("14[78]5[25]2[25]5[89]63")
451}
452
453# loopy sort of x-like shape
454Key x = {
455	dir("v?l>'^?`</v?")
456	grid(".*5.*")
457	doc("1[45][58][56][25][45]7")
458}
459
460# y shape
461Key y = {
462	dir("vl>?'^v/?<?`?^?'?>?")
463	doc("2[25][36]3[36]69")
464	doc("2[25][36]3[36]69[89][56]6")
465}
466
467# basic z shape
468Key z = {
469	dir(">l?v?/v?l?>")
470	doc("1379:straight")
471}
472
473### NEWPAGE
474}
475
476Mode "Abc":"abc"
477{
478    ModeLock "ABC", Key Caps_Lock, OrientationCorrection -90 = dir("^")
479}
480
481Mode "ABC":"abc"
482{
483    ModeLock "abc", OrientationCorrection -90 = dir("^")
484}
485
486#
487#Mode "123":"!@#"
488#{
489#### Number mode [123]
490#
491## Need to override Return so it has precedence over ',' from [!@#]
492#Key Return = grid("3[26]?5[48]?7?")
493#
494#ModeShift "!@#" = {
495#	grid("1[24]?5[68]?9")
496#	doc("159")
497#}
498#ModeLock "*123*" = grid("9[68]?5[24]?1?")
499#
500## In number mode we get to use the standard number shapes.
501## standard 0
502#Key 0 = {
503#	grid("3?2?1?[54][45]?7?89?6[32]+1?4?")
504#	doc("248622")
505#}
506#Key 0 = {
507#	grid("1?2?3?[56][56]?9?87?41?2?3?6?")
508#	doc("268422")
509#}
510## standard 1
511#Key 1= {
512#	grid("258")
513#	doc("258")
514#}
515## 7 needs precedence over 2 for 123658
516## standard 7 as T
517#Key 7 = grid("1?23?([26]?5[48]?7?|65?[98]8?9?)")
518## standard 2
519#Key 2 = {
520#	grid("1?23?[26]?5[48]?([47]*?[58]+|47?[58]*)[69]*")
521#	doc("12578[89]")
522#}
523#Key 2 = grid("1?23?6[59]8[47]*[58]+[69]*")
524## standard 3
525#Key 3 = {
526#	grid("4?(1?[2][369]+|1[25][369]*)([369]+[25]+[147]?[258]*[369]+|[25]*[147]+[258]+[369]*)([369]*[58][74]+|[369]+[58][74]*)")
527#	doc("125[45]4[45]587")
528#}
529## standard 4 (as L)
530#Key 4 = {
531#	grid("1?47?89?6?")
532#	doc("14789")
533#}
534## standard 4 (like the y stroke)
535#Key 4 = {
536#	grid("12?[45]+1?6?[23]*[56]*[89]+")
537#	doc("2[25][36]3[36]69")
538#}
539## standard 5
540#Key 5 = {
541#	grid("6?3?[25]?5?[14]*[25]*[69]*+[58]*87?4?")
542#	doc("325698")
543#	doc("255698")
544#}
545## standard 6
546#Key 6 = {
547#	grid("3?[26]?[15]?[45][57]?8[59]?6?9?[58]+[47]*1?")
548#	doc("24854")
549#}
550## 7 is defined above (before 2)
551#Key 7 = {
552#	doc("12357:straight")
553#	doc("[12]2369")
554#}
555## a figure-eight
556#Key 8= {
557#	grid("3?2[14]?4?[25]+[69]?9?87?[4598]+[12356]*")
558#	doc("325698563")
559#}
560## basic 9-shape
561#Key 9 = {
562#	grid("3?21?2?[45]*[789]*1?[256]+[32]+[56]+[89]*7?")
563#	doc("32[25][36]3[36]69")
564#}
565#
566#### NEWPAGE
567#}
568#
569#Mode "*123*":"123"
570#{
571#    ModeLock "abc" = grid("9[68]?5[24]?1?")
572#}
573#
574#Mode "!@#":"punctuation_in_letter_mode"
575#{
576#### Punctuation mode [!@\#]
577#
578#ModeLock "abc" = {
579#	grid("1[24]?5[68]?9")
580#	doc("159")
581#}
582#
583#Key period = {
584#	grid("5")
585#	doc("5")
586#}
587#
588#Key comma  = {
589#	grid("3[26]?5[48]?7?")
590#	doc("357")
591#}
592#
593#Key quoteright,	OrientationCorrection 90 = {
594#	grid("258")
595#	doc("258")
596#}
597#
598#Key quotedbl = {
599#	grid("([87]*[45]5?[12]+|[87]+[45]5?[12]*)([456]*[789]+|[12][45]5?[789]*)[56]6?3?2?")
600#	doc("7415963:straight")
601#}
602#
603#Key less = {
604#	grid("9?8[75]?4[15]?23?")
605#	doc("842:straight")
606#}
607#
608#Key greater = {
609#	grid("7?8[59]?6[35]?21?4?")
610#	doc("862:straight")
611#}
612#
613#Key bracketleft = {
614#	grid("(9?[8][147]+|9[58][147]*)([147]+[58]+[69]?[258]*[147]+|[58]*[69]+[258]+[147]*)([147]*[25][36]+|[147]+[25][36]*)")
615#	doc("985[56]6[56]523")
616#	doc("[89]8741")
617#}
618#
619#Key bracketright= {
620#	grid("(7?[8][369]+|7[58][369]*)([369]+[58]+[47]?[258]*[369]+|[58]*[47]+[258]+[369]*)([369]*[25][14]+|[369]+[25][14]*)")
621#	doc("[78]8963")
622#	doc("785[45]4[45]521")
623#}
624#
625#Key minus, OrientationCorrection 0 = {
626#	grid("456")
627#	doc("456")
628#}
629#
630#Key slash = {
631#	grid("7[48]?5[26]?3")
632#	doc("753")
633#}
634#
635## XXX: this stroke doesn't work very well yet
636#Key question = {
637#	grid("4?1?23?[26]?54?7?")
638#	doc("12547")
639#}
640#
641#Key exclam, OrientationCorrection -90 = {
642#	grid("852")
643#	doc("852")
644#}
645#
646#Key braceleft = {
647#	grid("6?([36]?[25][147]+|[36][215][147]*)([147]+[258]+([36]?[258]*|9[658]+)[147]+|[258]*([36]+[25]+|9[658]+)[147]*)([147]*[58]9?6?|[147]+[58][96]*)")
648#	doc("325[56]6[56]589")
649#	doc("9874[14]1[14]47")
650#}
651#
652#Key braceright = {
653#	grid("4?([14]?[25][369]+|[14][235][369]*)([369]+[258]+([14]?[258]*|7[458]+)[369]+|[259]*([14]+[25]+|7[458]+)[369]*)([369]*[58]7?4?|[369]+[58][74]*)")
654#	doc("7896[36]3[36]69")
655#	doc("125[45]4[45]587")
656#}
657#Key braceright = grid("1?23?[26]?5[48]?7?89?[58]+[47]*8?")
658#
659#Key numbersign = {
660#	grid("147[48]?5[26]?369")
661#	doc("1475369:straight")
662#}
663#
664#Key parenleft = {
665#	grid("6?3?2[15]?47?[58]8?9?6?")
666#	doc("248")
667#}
668#
669#Key parenright = {
670#	grid("1?2[35]?6[59]?87?4?")
671#	doc("268")
672#}
673#
674#Key dollar = {
675#	grid("6?3?25?([369]+(58)?8?7?4?|[14]+[25]*(5[25]*[369]*5?87?4?|[369]*874?))")
676#	doc("325698")
677#}
678#
679#Key dollar = grid("6?3?25?15?4(7?[58]8?9?6?|[78]+9?6?9?)87?")
680#
681#Key backslash = {
682#	grid("9[68]?5[24]?1?")
683#	doc("951")
684#}
685#
686#Key plus = {
687#	grid("(3[26]?|3?[26])([58]8?)([48][57])?[47](1[24])?[57]?[68]?9")
688#	doc("3[56][58][45][25][56]9")
689#}
690#
691#Key equal = {
692#	grid("1?2(3[26]?5[48]?7?|3?[26]?5[48]?7)89?")
693#	doc("1235789:straight")
694#}
695#
696#Key equal = grid("(123?|23)((56?5?)?8[47]|5?6?9[58]8?)7?4?[58]+[69]*")
697#
698#Key underscore = {
699#	grid("4?5654?")
700#	doc("45[56]6[56]54")
701#}
702#
703#Key asterisk = {
704#	grid("1?([24]?5|[24]7)([68][59])?6(3[256]1?)?[59]?[48]?7")
705#	doc("1[45][58][56][25][45]7")
706#}
707#
708#Key bar = {
709#	grid("8?5258?")
710#	doc("85[25]2[25]58")
711#}
712#
713#Key semicolon = {
714#	grid("3?[26]?5[48]?7?[48]?5[26]?3")
715#	doc("35[57]7[57]53")
716#}
717#
718#Key colon = {
719#	grid("2?5852?")
720#	doc("25[58]8[58]52")
721#}
722#
723#Key Tab	 = {
724#	grid("741?23")
725#	doc("7412[23]")
726#}
727#
728#Key Escape = {
729#	grid("369?[68]?[58][24]?1")
730#	doc("36951:straight")
731#}
732#Key Escape = grid("3?6?[56](8|987)[745]*41?")
733#
734## These five come last to avoid some precedence problems
735#Key asciitilde = {
736#	grid("3?69?[68]?[35]?[24]?147?")
737#	doc("3695147:straight")
738#}
739#Key asciitilde = grid("3?6?[56](8|98)[7845]*41?2?[456]+[789]*")
740#
741#Key at	 = {
742#	grid("3?(21?[54][45]?7?89?63?2?|2?1?[54]4?7?89?63?2)1?4?")
743#	doc("248622")
744#}
745#
746#Key at	 = {
747#	grid("1?(23?[56][56]?9?87?41?2?|2?3?[56]6?9?87?41?2)3?6?")
748#	doc("268422")
749#}
750#
751#Key percent = {
752#	grid("([12]*[45]+[789]+|[12][745]+[789]*)([78]*[45]*[123]*[456]*[789]+|[45]*[12]+[456]+[789]*)([789]*[56]+[32]+|[789]+[56]+[32]*)")
753#	doc("1[45][78][47]5[69][89][56]3")
754#	doc("183:straight")
755#}
756#
757#Key ampersand = {
758#	grid("3?2[14]?4?[25]+[69]?9?87?[4598]+[12356]*")
759#	doc("325698563")
760#}
761#
762#Key asciicircum = {
763#	grid("[78]?[45]5?1?(23?[56]6?|4?5)8?9?8?")
764#	doc("729:straight")
765#}
766#
767#Key quoteleft = {
768#	grid("9?[68]?5[24]?1?[24]?5[68]?9?")
769#	doc("95[15]1[15]59")
770#}
771#
772#}
773#### NEWPAGE
774#
775Mode "no_capitals_in_lowercase_mode"
776{
777## n instead of A
778#Key n = grid("[78]?[45]5?1?(23?(56?[89]+[856]*[124]*|6[89]+[856]*[1234]*)|4?58?9?[856]*4?[12]+)")
779## s instead of C
780#Key s = grid("6?3?25?15?4(7?[58]8?9?6?|[78]+9?6?9?)87?")
781## z instead of D
782#Key z = grid("(123?|23)((56?5?)?8[47]|5?6?9[58]8?)7?4?[58]+[69]*")
783## r instead of D
784#Key r = grid("[12]?([45][78]*4|[459]*[78]+[45]*)(123?|23)5?6?5?(8[47]|9[58]8?)7?4?[58]+[69]*")
785## g instead of G
786#Key g = grid("3?21?2?[45]?1?[256]*[32]*[56]+(98?7?|87)4?[58]*2?[369]*")
787## w instead of H
788#Key w = grid("[12]1?47[47]*8?[56]6?[89][56]*[23]*")
789## d instead of J
790#Key d = grid("2?(3?69?8[74]4?|(3?6|2)59?8[74]4?)7?8[69]*")
791## b instead of L
792#Key b = grid("1?47?89[58]*[47]*")
793## m instead of N
794#Key m = grid("([87]*[45]5?[12]+|[87]+[45]5?[12]*)([456]*[789]+|[45]5?6?[789]*)[56]6?3?2?[56]+[89]*")
795## w instead of N
796#Key w = grid("[12]*[45]+(7[45]+)(1?23?6|1[24][35]?6?|1[45]+8)9?[56]+[23]+")
797## q instead of O
798Key q = {
799	dir("`?</vl>'^`?</?v?l?>'?")
800	doc("24862123")
801}
802## p instead of R
803#Key p = grid("([12]*[45]|[12][45]*)?[78]*4?5?1?23?[25]+[14]*")
804## e instead of S
805#Key e = grid("6?3?25?([369]+(58)?8?7?4?|[14]+[25]*(5[25]*[369]*5?87?4?|[369]*874?))[58]+[69]*")
806## w instead of U
807#Key w = grid("1?47?8[59]?[26]3?2?6(9[56]+)?[23]*")
808## y instead of X
809#Key y = grid("1?([24]?5|[24]7)([68][59])?6(3[256]1?)?3?5?[48]?78?9?[456]+[1236]*")
810## b instead of Z
811#Key b = grid("1?2(3[26]?5[48]?7?|3?[26]?5[48]?7)89?[58]+[47]*8?")
812}
813#
814#Mode "capitals_in_lowercase_mode"
815#{
816## stylized A shape
817#Key A = grid("[78]?[45]5?1?(23?(56?[89]+[856]*[124]*|6[89]+[856]*[1234]*)|4?58?9?[856]*4?[12]+)")
818## a shape
819#Key A = grid("6?(3?25?|32?5?)1?4([748]+56?|7?4?8[96]6?)[23]*(3[56][89]?8?|3?(6[89]|598?))[56]*[23]*")
820#
821## B with optional bar
822#Key B = grid("([12]*[45]+[78]|[12][45]+[78])?[78]*[45]*(1?[2][369]+|1[25][369]*)([369]+[25]+[147]?[258]*[369]+|[25]*[147]+[258]+[369]*)([369]*[58][74]+|[369]+[58][74]*)[58]+[69]*8?")
823## lowercase b shape
824#Key B = grid("[21][21]?[54]4?[78]+4?8?58?[69]9?87?4?[58]*[69]*")
825#
826## the letter c
827#Key C = grid("6?3?25?15?4(7?[58]8?9?6?|[78]+9?6?9?)87?")
828#
829## D shape with optional bar
830#Key D = grid("(123?|23)((56?5?)?8[47]|5?6?9[58]8?)7?4?[58]+[69]*")
831#Key D = grid("[12]?([45][78]*4|[459]*[78]+[45]*)(123?|23)5?6?5?(8[47]|9[58]8?)7?4?[58]+[69]*")
832## lowercase d starting with bar
833#Key D = grid("(3?6(56)?|26?5(6[89]+)?|23?6?9)[89]*[658]*[32]*[15]?([47]+|[58]+)89?[69]+[58]+[47]+")
834## lowercase d starting with circle
835#Key D = grid("9?6?[258]+[47]7?[258]+9?[256]?[23]+[56]*9?[89]*[56]+[23]*")
836#
837## stylized E shape like a mirror-image of a 3
838## This is simply the the mirror-image of the B stroke
839#Key E = grid("([36]?[25][147]+|[36][215][147]*)([147]+[258]+([36]?[25]*|9[658]+)[147]+|[258]*([36]+[25]+|9[658]+)[147]*)([147]*8[96]6?|[147]+8[96]*)[58]+[47]*8?")
840## e shape
841#Key E = grid("1?[47]?2?[58]?2?6?3?[25]+1?4[57]?89?6?[58]+[47]*")
842#
843## stylized F shape with optional initial curl
844#Key F = grid("6?3?21?478?7?[45]*[12]*")
845#
846## i and I need precedence over g and G
847## I as vertical downward stroke
848#Key I = grid("2?58?52")
849#
850## G shape (in-and-out-and-in at end)
851#Key G = grid("3?21?5?45?7?89?((6?5|68)|85)([47]+[258]+([369]+[258]+)?|[47]*[258]+([369]+[258]+))[147]*")
852## lowercase g shape with tail to left
853#Key G = grid("3?21?2?[45]1?[256]+[32]+[56]+(98?7?|87)4?[58]*[69]*")
854#
855## typical lowercase h
856#Key H = grid("[12]1?47[47]*8?[56]6?[89][56]*[23]*")
857#
858## i is defined above (before G)
859#
860## stylized J shape as backwards L
861#Key J = grid("2?(3?69?8[74]4?|(3?6|2)59?8[74]4?)7?8[69]*")
862#
863## loopy sort of k-like shape
864#Key K = grid("(3[26]?|3?[26])([58]8?)([48][57])?[47]+(1[24]3?)?1?[57]?[68]?9[568]+([12347]|5)[1245]*")
865#
866## L shape
867#Key L = grid("1?47?89[58]*[47]*")
868#
869## M shape or lowercase m with optional initial down-stroke
870#Key M = grid("([12]*[45]|[12][45]*)?([78]*[45]+[123]+|[78][145]+[123]*)(([123]+[456]+[789]*|[456]+[789]+)[456]*[123]+|[456]*[789]+[456]+[123]*)([123]*[56]+[98]+|[123]+[56]+[98]*)[56]+[23]*")
871#
872## N shape starting at lower-left
873#Key N = grid("([87]*[45]5?[12]+|[87]+[45]5?[12]*)([456]*[789]+|[45]5?6?[789]*)[56]6?3?2?[56]+[89]*")
874## n shape
875#Key N = grid("[12]*[45]+(7[45]+)(1?23?6|1[24][35]?6?|1[45]+8)9?[56]+[23]+")
876#
877## O as counter-clockwise circle starting at top
878#Key O = grid("3?([26][15]?[54]4?7?8[59]?[65]5?3?2?|[26]?[15]?[54]4?7?8[59]?[65]5?3?2)1?4?[25]+[36]*")
879#
880## custom P with just the curved part, drawn backwards, (like backwards D)
881#Key P = grid("7?8[59]?63?[52]2?([14]4?[25]+3?|[25]+3)")
882## P with up-stroke or down-up stroke vertical bar
883#Key P = grid("([12]*[456]+|[12][456]*)?([789]*4|[789]+[45]+)1?2[36]?(6|(6?(2?5|25?)2?8?[147]*|[25]*8?1?41?7?))[25]+[36]*")
884#
885## Q as counter-clockwise circle starting at bottom
886#Key Q = grid("4?[57]?([48][59]?63?2[15]?[45][57]?|[48]?[59]?63?2[15]?[45][57]?)(87|8?9?6?9[58]+[47]*[58]*)")
887#
888## lowercase r
889#Key R = grid("([12]*[45]|[12][45]*)[78]*4?5?1?23?[25]+[14]*")
890## R shape
891#Key R = grid("([12]*4)?[78]*[45]+[12]2?([369]*[25]+[14]|[369]+[258]+)([147]*[258]*[68]?9|[147]+[258]+[68]?9?)[68]?[57][24]?1?4?")
892#
893## your basic S shape
894#Key S = grid("6?3?25?([369]+(58)?8?7?4?|[14]+[25]*(5[25]*[369]*5?87?4?|[369]*874?))[58]+[69]*")
895#
896## stylized T as right->down
897#Key T = grid("1?23?65?([23]+|[98]8?9?)[56]+[23]*")
898#
899## u shape (down-up tail)
900#Key U = grid("1?47?8[59]?[26]3?2?6(9[56]+)?[23]*")
901#
902## V shape
903#Key V = grid("1?[245]5?[78]8?[49]?[256]+3[56]*9?8")
904#Key V = grid("1?[245]5?8[49]?[256]+3[56]*9?8?")
905#Key V = grid("1?[245]5?78?[49]?[56]*[23]+[56]*9?87?")
906## V as backwards U
907#Key V = grid("3?6?[56](8|987)[7845]*41?2?[456]+[789]*")
908#Key V = grid("3?6?[56](8|98)[745]*41?2?[456]+[89]*")
909#
910## w or W shape
911#Key W = grid("([12]*[45][789]+|[12][745][789]*)(([78]+[456]+[123]*|[45]+[12]+)4?5?6?[789]+|[45]*[12]+[456]+[789]*)([789]*[569]+[32]+|[789]+[569]+[32]*)[56]*[89]*")
912#
913## loopy sort of x-like shape
914#Key X = grid("1?([24]?5|[24]7)([68][59])?6(3[256]1?)?3?5?[48]?78?9?[456]+[1236]*")
915#
916## y shape (down-up-down tail)
917#Key Y = grid("1?2?[45]+1?([789]+[45]*)?6?[23]+[56]*[89]+7?8?[456]+([23]+[56]+)?[89]*9[89]*")
918#
919## basic z shape
920#Key Z = grid("1?2(3[26]?5[48]?7?|3?[26]?5[48]?7)89?[58]+[47]*8?")
921#}
922#
923#Mode "numbers_in_letter_mode"
924#{
925#### Numbers in letter mode [abc]
926## 0 as clockwise circle
927#Key 0 = {
928#	grid("1?2?3?69?87?41?2?3?")
929#	doc("268422")
930#}
931#
932## 1 is defined way up above A
933#Key 1 = {
934#	dir ("^v")
935#	doc("85[25]2[25]58")
936#}
937#
938## 2 drawn backwards (starting at bottom)
939#Key 2 = {
940#	grid("9?8([74][48]?[58]9?[26]?3?|7?[48]?[58]9?[26]?[63]3?)21?4?")
941#	doc("[89]87521")
942#}
943#
944## 3 drawn backwards (starting at bottom)
945#Key 3 = {
946#	grid("(7?[8][369]+|7[58][369]*)([369]+[58]+[47]?[258]*[369]+|[58]*[47]+[258]+[369]*)([369]*[25][14]+|[369]+[25][14]*)")
947#	doc("785[45]4[45]521")
948#}
949#
950## 4 as y drawn backwards, (starting at bottom)
951#Key 4 = {
952#	grid("[89]9?5?65?36?9?(87?4|54?)1?2?")
953#	doc("96[36]3[36][25]2")
954#}
955#
956## 6 needs precedence over 5
957## 6 drawn backwards (starting at circle)
958#Key 6 = grid("7?4?[58][69]*87?4[15]?2?3?")
959#
960## 5 drawn backwards (starting at bottom)
961#Key 5 = {
962#	grid("([47]*[58]5?[69]+|[47]+[58]5?[69]*)([58]*[147]+(25)?|[58]+[147]*5?2)23?6?")
963#	doc("896523")
964#}
965#
966#Key 6 = doc("[47][58]842")
967#
968## 7 drawn backwards (starting at bottom)
969#Key 7 = {
970#	grid("963?21")
971#	doc("9632[12]")
972#}
973#
974## standard 8
975#Key 8 = {
976#	grid("3?2[14]?4?[25]+[69]9?87?[4598]+[12356]*")
977#	doc("325698563")
978#}
979## 8 drawn backwards
980#Key 8 = {
981#	grid("1?2[36]?6?[25]+[47]7?89?[5678]+[12345]*")
982#	doc("236589652")
983#}
984#
985## 9 drawn backwards (starting with circle)
986#Key 9 = {
987#	grid("3?6?(5[41]*|2[41]*4[41]*)23?69?8?9?")
988#	doc("[36][25]2369")
989#}
990#
991## 9 drawn backwards (starting with tail)
992#Key 9 = {
993#	grid("[789]*[56]+3?2[14]4?(2?52?[36]*|[25]*63?)")
994#	doc("9632[25][36]")
995#}
996#
997#}
998#
999#Mode "punctuation_in_letter_mode"
1000#{
1001#### Punctuation in letter mode [abc]
1002#
1003#Key Escape = {
1004#	grid("369?[68]?[58][24]?1")
1005#	doc("36951:straight")
1006#}
1007#
1008#
1009#Key Tab	 = {
1010#	grid("741?2(32)?1?")
1011#	doc("7412[23]21")
1012#}
1013#
1014#Key period = {
1015#	grid("65456")
1016#	doc("65[45]4[45]6")
1017#}
1018#
1019#Key comma = {
1020#	grid("3?2123?[26]?5[48]?7?")
1021#	doc("32[12]1[12]357")
1022#}
1023#
1024#Key colon = {
1025#	grid("3?2(12)?3?6[89]+")
1026#	doc("32[12]1[12]369")
1027#}
1028#
1029#Key exclam = {
1030#	grid("2?5(85?)?2?58?5?")
1031#	doc("25[58]8[58]5258")
1032#}
1033#
1034#Key minus = {
1035#	grid("45654")
1036#	doc("45[56]6[56]54")
1037#}
1038#
1039## XXX: I replaced this with 'e'. Need a new stroke here...
1040#Key equal = {
1041#	grid("1?2(32)?1?47?89?")
1042#	doc("12[23]3[23]289")
1043#}
1044#
1045#Key question = {
1046#	grid("1?23?21?[45][78]+")
1047#	doc("12[23]3[23]2147")
1048#}
1049#
1050#Key underscore = {
1051#	grid("4?5(65)?456?")
1052#	doc("45[56]6[56]5456")
1053#}
1054#
1055## XXX: need to combine
1056#Key plus = grid("2587456")
1057#Key plus = grid("1458?[74]4?56")
1058#Key plus = grid("1?258?[74]4?56")
1059#Key plus = grid("2?3[56]9?87?456?")
1060#
1061## bar is defined way up above A for precedence
1062#Key bar = {
1063#	dir("^v^")
1064#	doc("85[25]2[25]5852")
1065#}
1066#Key bar	 = grid("7?4147?89")
1067#Key bar	 = grid("9?6369?87")
1068#
1069#Key bracketleft = {
1070#	grid("987?41")
1071#	doc("98741")
1072#}
1073#
1074#Key bracketright = {
1075#	grid("789?63")
1076#	doc("78963")
1077#}
1078#
1079#Key braceleft = {
1080#	grid("(654?|987?4)14[78]?")
1081#	doc("9874[14]1[14]47")
1082#}
1083#
1084#Key braceright = {
1085#	grid("(456?|789?6)36[89]?")
1086#	doc("7896[36]3[36]69")
1087#}
1088#
1089#Key less = {
1090#	grid("987[48]?5[26]?3?")
1091#	doc("-98753")
1092#}
1093#
1094#Key greater = {
1095#	grid("789[68]?5[24]?1?")
1096#	doc("-78951")
1097#}
1098#
1099#Key parenleft = {
1100#	grid("9?[68]?5([24]?1|[24]1?)2[36]*")
1101#	doc("95123:straight")
1102#}
1103#
1104#Key parenright = {
1105#	grid("7?[48]?5([26]?3|[36]3?)2[14]*")
1106#	doc("75321:straight")
1107#}
1108#
1109#Key quoteright = {
1110#	grid("7[48]?5[26]?3?[26]?5[48]?7?")
1111#	doc("75[35]3[35]57")
1112#}
1113#Key quoteright = grid("7?[48]?5[26]?3?[26]?5[48]?7")
1114#
1115#Key quoteleft = {
1116#	grid("1[24]?5[68]?9?([68]?5[24]?|84)1?")
1117#	doc("15[59]9[59]51")
1118#}
1119#Key quoteleft = grid("1?[24]?5[68]?9?([68]?5[24]?|84)1")
1120#
1121#Key quotedbl = {
1122#	grid("147[48]?54?5?[26]?32?3?69")
1123#	doc("1475369:straight")
1124#}
1125#
1126#Key semicolon = {
1127#	grid("3?[26]?5[48]?7?[48]?5[26]?3")
1128#	doc("35[57]7[57]53")
1129#}
1130#
1131#Key slash = {
1132#	grid("7[48]?5[26]?3")
1133#	doc("753")
1134#}
1135#
1136## XXX: need something else for backslash if this will be puncshift
1137##Key backslash = grid("1[24]?5[68]?9")
1138#
1139#Key percent = {
1140#	grid("([32]*[56]+[789]+|[32][569]+[789]*)([89]*[56]*[123]*[456]*[789]+|[56]*[23]+[456]+[789]*)([789]*[45]+[12]+|[789]+[45]+[12]*)")
1141#	doc("3[56][89][69]5[47][78][45]1")
1142#}
1143#
1144#Key asciicircum = {
1145#	grid("8?9[68]?5?[34]?(2?1?[54]4?|6?5)[78]*")
1146#	doc("927:straight")
1147#}
1148#
1149#Key numbersign = {
1150#	grid("9?63?[26]?56?5?[48]?741?")
1151#	doc("9635741:straight")
1152#}
1153#
1154#Key asciitilde = {
1155#	grid("3?69?[68]?5?[24]?147?")
1156#	doc("3695147")
1157#}
1158#
1159## XXX: what stroke do we want for asterisk?
1160#Key asterisk    = grid("7[48]?[15]([26][53])?6(9[568]7?)?[53]?[24]?1")
1161#
1162#Key ampersand = {
1163#	grid("9[68]?5?[24]?1?47?89?")
1164#	doc("9514789")
1165#}
1166#
1167#Key at	 = {
1168#	grid("2?589?63?21?47?8?9?[89]?")
1169#	doc("55862488")
1170#}
1171#
1172## XXX: right now, dollar conflicts with 8
1173#Key dollar = grid("3?2[14]?4?[58]+[69]?9?874[12][12]?")
1174#
1175#### NEWPAGE
1176#}
1177#