Gema is a non-procedural, rule-based language for text manipulation. I find it an extremely useful tool for maintaining Web pages, massaging databases, transforming documents - all the things I used to do in Awk, Nawk, Perl, Sed, and the like. Here are some short examples of Gema programming. I have explained what I see as Gema's strengths in Why I Love Gema. I also have some exercises to help beginning Gema students.
Take a tab-delimited text file and make an HTML table out of it
\n\n*\n\n=<table border>\n$1</table> \L<U>=\t<tr>\n@makerow{$0}\t</tr> makerow:<P>=\t\t<td>$1</td>\n;?=
Generate a simple KWIC index
<G>\P <G> <G> <G> <G> = @fill-right{@repeat{40;\ };$1 $2} $3 $4 $5\n
Add SBML markup, including family
\L<p>\t<p>\t<p>\t<p>\t<p>\t<p>\t<p>=@filter{$7}<Latin>$5 $6<English>$3 $4 filter:<u> \/ <u>=<Family>$2\n@define{filter:@quote{$0}=}
Create a dictionary from a word list
\<Word\><G>\<=@tokenize{$1} tokenize:<A>=@filter{$1}@define{filter:$1=} tokenize:?= filter:<u>=@int-char{@length{$1}}$1 \Z=@int-char{0}
Report duplicates in CyberDewey
@set{l1;} @set{n1;} \L\N\<li\><U>a href\=\"<U>\"\><U>\<\/a=@set{l2;$2}@set{n2;$3}@duplicate{}@set{l1;@var{l2}}@set{n1;@var{n2}} duplicate:\A=@cmps{@var{l1};@var{l2};;@position{@var{l1}};} duplicate:\A=@cmps{@var{n1};@var{n2};;@position{@var{n1}};} position:<U>=File @file{}\;Line @line{}\# $1\n
Compute seconds from a starting time
ARGV:\N-date\n*\n=@set{indate;$1} !\A=@datime2secs{1998-10-24 10:10:10}\n datime2secs:<D>-<D>-<D> <D>\:<D>\:<D>=\ @add{@date2secs{$1 $2 $3};@time2secs{$4 $5 $6}} date2secs:<D> <D> <D>=@add{@leap{$1 $2};@add{@month2secs{@sub{$2;1}};@mul{86400;@sub{$3;1}}}} time2secs:<D> <D> <D>=@add{@mul{3600;$1};@add{@mul{60;$2};$3}} month2secs:<D>=@mul{86400;@daysinmonth{$1}} daysinmonth:00=0 daysinmonth:01=31 daysinmonth:02=59 daysinmonth:03=90 daysinmonth:04=120 daysinmonth:05=151 daysinmonth:06=181 daysinmonth:07=212 daysinmonth:08=243 daysinmonth:09=273 daysinmonth:10=304 daysinmonth:11=334 leap:<D> 01=0 leap:<D> 02=0 leap:<D> <D>=@cmpi{@mod{$1;4};0;0;86400;0} \A=Input date @var{indate} \= @datime2secs{@var{indate}}\n@end{}
Capitalize text, taking into account articles, etc.
! Capitalize the first letter in the file \B/[a-zA-Z]//[a-zA-Z]*/=@upper{$1}@lower{$2} ! Capitalize the first letter after a period \.<S><-S1><-s>=.$1@upper{$2}@lower{$3} ! Me, I'm always upper \C\Ii\I=I ! Other one- and-two-character words are lower \I<A1>\I=@lower{$1} \I<A2>\I=@lower{$1} ! A few special words are lower \Iand\I=and;\Iaux\I=aux;\Ialla\I=alla;\Ialle\I=alle \Ides\I=des;\Idell\I=dell;\Idella\I=della;\Idelle\I=delle \Ifor\I=for;\Ithe\I=the;\Iles\I=les;\Iwith\I=with \Icon\I=con;\Icol\I=col ! Everything else is capitalized /[a-zA-Z]//[a-zA-Z]*/=@upper{$1}@lower{$2} upper:/[a-z]/=@upcase{$1} ! Rules for system-dependent upcasing go here lower:/[A-Z]/=@downcase{$1} ! Rules for system-dependent downcasing go here
Mundie, David A. Gema Gems / David A. Mundie Pittsburgh, PA : Polymath Systems 1995 005.13 dc-20 [MARC]