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]