configure.ac: Add AM_GNU_GETTEXT_VERSION([0.17]). Remove ALL_LINGUAS.
[enscript.git] / states / hl / enscript.st
1 /*
2  * States definitions file for GNU Enscript.
3  * Copyright (c) 1997-2003 Markku Rossi.
4  * Author: Markku Rossi <mtr@iki.fi>
5  *
6  * The latest version of this file can be downloaded from URL:
7  *
8  *     http://www.iki.fi/~mtr/genscript/enscript.st
9  */
10
11 /*
12  * This file is part of GNU enscript.
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2, or (at your option)
17  * any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; see the file COPYING.  If not, write to
26  * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
27  * Boston, MA 02110-1301, USA.
28  */
29
30 /*
31  * $Id: enscript.st,v 1.3 2003/03/05 08:31:31 mtr Exp $
32  */
33
34 /*
35  * Guildelines for writing new highlighting rules for the GNU Enscript.
36  *
37  * - all highlighting states should have a document comment like this:
38  *
39  *   /**
40  *    * Name: c
41  *    * Description: C programming language.
42  *    * Author: Author Name <author@email.address>
43  *    * ...
44  *
45  *   It is used by enscript's --help-pretty-print option to print
46  *   description about supported highlighting modes.
47  *
48  * - the main entry state (for example, for the C, the state `c') must
49  *   be inherited from state `HighlightEntry':
50  *
51  *   state c extends HighlightEntry
52  *   {
53  *     ...
54  *
55  * - all help-states smust be inherited from state `Highlight':
56  *
57  *   state c_string extends Highlight
58  *   {
59  *     ...
60  *
61  * - all printing should be done with the language_print() procedure
62  *   instead of the print() primitive.
63  *
64  * - using enscript.el to build regular expressions:
65  *
66  *      M-x load-file RET enscript.el RET
67  *
68  *   Move in the buffer to the point where the (build-re '()) ends,
69  *   that is, after the last closing parenthesis ')'.  Then, type:
70  *
71  *      C-x C-e
72  *
73  *   Magic should happen.
74  *
75  * These rules ensures that enscript's --help-pretty-print option and
76  * the different output languages (HTML, RTF, etc.) work.
77  */
78 \f
79 /* This script needs at least this version of the States program. */
80 prereq ("1.6.2");
81
82 /*
83  * Constants, fonts, etc.
84  */
85
86 debug = "0";
87
88 /* Boolean values. */
89 true = 1;
90 false = 0;
91
92 font_spec = "Courier@10";
93
94 /* These components are resolved from <font_spec>. */
95 font = "";
96 ptsize = "";
97
98 /*
99  * Generatel table of contents?  This is not supported by all output
100  * languages.
101  */
102 toc = "0";
103
104 /*
105  * The Highlight style.  The default style is `emacs' to imitate
106  * Emacs' font lock mode.
107  */
108 style = "emacs";
109
110 /*
111  * Create color outputs?
112  */
113 color = "1";
114
115 /*
116  * Use verbose highlighting rules?
117  */
118 verbose_highlighting = false;
119
120 /*
121  * Target language.  Possible values are:
122  * - enscript           generate enscript special escapes
123  * - html               generate HTML
124  * - overstrike         generate overstrike (line printers, less)
125  * - texinfo            generate Texinfo
126  * - rtf                generate Rich Text Format (rtf - MS Word, WordPerfect)
127  *                      This code can be souched into MS Word or PowerPoint
128  *                      for a pretty version of the code
129  */
130 language = "enscript";
131
132 /*
133  * How many input files we have.
134  */
135 num_input_files = "1";
136 current_input_file = 0;
137
138 /*
139  * Document title.
140  */
141 document_title = "Enscript Output";
142
143 /*
144  * Global variables for nested highlighting `nested.st'.
145  */
146 nested_start = "^-+(([ \t]*)([a-zA-Z_0-9]*)([ \t]*))-+$";
147 nested_start_re = 0;
148 nested_end = "^-+$";
149 nested_end_re_cached = 0;
150 nested_end_re = 0;
151 nested_default = "passthrough";
152
153 /*
154  * Color definitions.
155  */
156
157 cindex = 0;
158 rgb_values = list ();
159
160 sub define_color (name, r, g, b)
161 {
162   rgb_values[cindex] = list (name, r, g, b);
163   cindex = cindex + 1;
164 }
165
166 sub color_index (name)
167 {
168   local i;
169
170   for (i = 0; i < length (rgb_values); i = i + 1)
171     if (strcmp (rgb_values[i][0], name) == 0)
172       return i;
173
174   return -1;
175 }
176
177 sub language_color (name)
178 {
179   local idx;
180
181   idx = color_index (name);
182   if (idx < 0)
183     panic ("unknown color `", name, "'");
184
185   /*
186    * The map_color() subroutine is language specific and defined in
187    * *_faces() subroutine.
188    */
189   map_color (rgb_values[idx][1], rgb_values[idx][2], rgb_values[idx][3]);
190 }
191
192 /* RGB definitions for colors.  These are borrowed from X's rgb.txt file. */
193
194 define_color ("black",                  0, 0, 0);
195 define_color ("gray25",                 64, 64, 64);
196 define_color ("gray50",                 127, 127, 127);
197 define_color ("gray75",                 191, 191, 191);
198 define_color ("gray85",                 217, 217, 217);
199 define_color ("gray90",                 229, 229, 229);
200 define_color ("gray95",                 242, 242, 242);
201 define_color ("blue",                   0, 0, 255);
202 define_color ("cadet blue",             95, 158, 160);
203 define_color ("dark goldenrod",         184, 134, 11);
204 define_color ("dark olive green",       85, 107, 47);
205 define_color ("firebrick",              178, 34, 34);
206 define_color ("forest green",           34, 139, 34);
207 define_color ("green",                  0, 255, 0);
208 define_color ("orchid",                 218, 112, 214);
209 define_color ("purple",                 160, 32, 240);
210 define_color ("red",                    255, 0, 0);
211 define_color ("rosy brown",             188, 143, 143);
212
213 define_color ("DarkSeaGreen",           143, 188, 143);
214 define_color ("DarkSeaGreen1",          193, 255, 193);
215 define_color ("DarkSeaGreen2",          180, 238, 180);
216 define_color ("DarkSeaGreen3",          155, 205, 155);
217 define_color ("DarkSeaGreen4",          105, 139, 105);
218 define_color ("Goldenrod",              237, 218, 116);
219 define_color ("Aquamarine",             67, 183, 186);
220 define_color ("SeaGreen2",              100, 233, 134);
221 define_color ("Coral",                  247, 101,  65);
222 define_color ("DarkSlateGray1",         154, 254, 255);
223 define_color ("LightGrey",              211, 211, 211);
224
225
226 /*
227  * General helpers.
228  */
229
230 sub debug (msg)
231 {
232   if (debug_level)
233     print ("DEBUG: ", msg, "\n");
234 }
235
236 sub is_prefix (prefix, string)
237 {
238   return strncmp (prefix, string, length (prefix)) == 0;
239 }
240
241 sub strchr (string, ch)
242 {
243   local len = length (string), i;
244
245   for (i = 0; i < len; i = i + 1)
246     if (string[i] == ch)
247       return i;
248
249   return -1;
250 }
251
252 sub need_version (major, minor, beta)
253 {
254   local r, v, i;
255
256   regmatch (version, (/([0-9]+)\.([0-9]+)\.([0-9]+)/));
257   v = list (int ($1), int ($2), int ($3));
258   r = list (major, minor, beta);
259
260   for (i = 0; i < 3; i = i + 1)
261     if (v[i] > r[i])
262       return 1;
263     else if (v[i] < r[i])
264       return 0;
265
266   /* Exact match. */
267   return 1;
268 }
269
270 /* Highlight types which match expression <re> from string <data>. */
271 sub highlight_types (data, re)
272 {
273   local match_len;
274
275   while (regmatch (data, re))
276     {
277       language_print ($B);
278       type_face (true);
279       language_print ($0);
280       type_face (false);
281
282       match_len = length ($B, $0);
283
284       data = substring (data, match_len, length (data));
285     }
286
287   language_print (data);
288 }
289
290 \f
291 /*
292  * The supported faces.  These functions are used in the highlighting
293  * rules to mark different logical elements of the code.  The
294  * different faces and their properties (face_*) are defined in the
295  * style definition files.  The face_on() and face_off() functions are
296  * defined in the output language definition files.
297  */
298
299 sub bold (on)
300 {
301   if (on)
302     face_on (face_bold);
303   else
304     face_off (face_bold);
305 }
306
307 sub italic (on)
308 {
309   if (on)
310     face_on (face_italic);
311   else
312     face_off (face_italic);
313 }
314
315 sub bold_italic (on)
316 {
317   if (on)
318     face_on (face_bold_italic);
319   else
320     face_off (face_bold_italic);
321 }
322
323 sub comment_face (on)
324 {
325   if (on)
326     face_on (face_comment);
327   else
328     face_off (face_comment);
329 }
330
331 sub function_name_face (on)
332 {
333   if (on)
334     face_on (face_function_name);
335   else
336     face_off (face_function_name);
337 }
338
339 sub variable_name_face (on)
340 {
341   if (on)
342     face_on (face_variable_name);
343   else
344     face_off (face_variable_name);
345 }
346
347 sub keyword_face (on)
348 {
349   if (on)
350     face_on (face_keyword);
351   else
352     face_off (face_keyword);
353 }
354
355 sub reference_face (on)
356 {
357   if (on)
358     face_on (face_reference);
359   else
360     face_off (face_reference);
361 }
362
363 sub string_face (on)
364 {
365   if (on)
366     face_on (face_string);
367   else
368     face_off (face_string);
369 }
370
371 sub builtin_face (on)
372 {
373   if (on)
374     face_on (face_builtin);
375   else
376     face_off (face_builtin);
377 }
378
379 sub type_face (on)
380 {
381   if (on)
382     face_on (face_type);
383   else
384     face_off (face_type);
385 }
386
387 sub highlight_face (on)
388 {
389   if (on)
390     face_on (face_highlight);
391   else
392     face_off (face_highlight);
393 }
394
395 \f
396 /*
397  * Initializations.
398  */
399
400 start
401 {
402   /* Set debug level. */
403   debug_level = int (debug);
404
405   /* Use colors? */
406   color = int (color);
407
408   /* Increment input file count. */
409   current_input_file = current_input_file + 1;
410
411   /* Resolve fonts. */
412   idx = strchr (font_spec, '@');
413   if (idx < 0)
414     panic ("malformed font spec: `", font_spec, "'");
415
416   font = substring (font_spec, 0, idx);
417   ptsize = substring (font_spec, idx + 1, length (font_spec));
418
419   debug (concat ("start: ", font, "@", ptsize));
420
421   /* Construct bold, italic, etc. fonts for our current body font. */
422   if (is_prefix ("AvantGarde", font))
423     {
424       bold_font = "AvantGarde-Demi";
425       italic_font = "AvantGarde-BookOblique";
426       bold_italic_font = "AvantGarde-DemiOblique";
427     }
428   else if (regmatch (font, /^Bookman|Souvenir/))
429     {
430       bold_font = concat ($0, "-Demi");
431       italic_font = concat ($0, "-LightItalic");
432       bold_italic_font = concat ($0, "-DemiItalic");
433     }
434   else if (regmatch (font, /^Lucida(Sans-)?Typewriter/))
435     {
436       bold_font = concat ($0, "Bold");
437       italic_font = concat ($0, "Oblique");
438       bold_italic_font = concat ($0, "BoldOblique");
439     }
440   else if (regmatch (font, /^(.*)-Roman$/))
441     {
442       bold_font = concat ($1, "-Bold");
443       italic_font = concat ($1, "-Italic");
444       bold_italic_font = concat ($1, "-BoldItalic");
445     }
446   else
447     {
448       bold_font = concat (font, "-Bold");
449       italic_font = concat (font, "-Oblique");
450       bold_italic_font = concat (font, "-BoldOblique");
451     }
452
453   /* Create regular expressions for nested highlighting. */
454   nested_start_re = regexp (nested_start);
455   nested_end_re_cached = regexp (nested_end);
456
457   /* Define output faces. */
458   calln (concat ("lang_", language));
459
460   /* Define our highlight style. */
461   calln (concat ("style_", style));
462
463   /* Resolve start state. */
464   if (check_startrules ())
465     debug ("startstate from startrules");
466   if (check_namerules ())
467     debug ("startstate from namerules");
468 }
469
470 namerules
471 {
472   /\.(c|h)$/                                    c;
473   /\.(c++|C|H|cpp|cc|cxx)$/                     cpp;
474   /\.m$/                                        matlab;
475   /\.(mpl|mp|maple)$/                           maple;
476   /\.(scm|scheme)$/                             scheme;
477   /\b\.emacs$|\.el$/                            elisp;
478   /\.ad(s|b|a)$/                                ada;
479   /\.[Ss]$/                                     asm;
480   /\.st$/                                       states;
481   /(M|m)akefile.*/                              makefile;
482   /\.(MOD|DEF|mi|md)$/                          modula_2;
483   /\.tcl$/                                      tcl;
484   /\.(v|vh)$/                                   verilog;
485   /\.html?$/                                    html;
486   /\bChangeLog$/                                changelog;
487   /\.(vhd|vhdl)$/                               vhdl;
488   /\.(scr|.syn|.synth)$/                        synopsys;
489   /\.idl$/                                      idl;
490   /\.(hs|lhs|gs|lgs)$/                          haskell;
491   /\.(pm|pl)$/                                  perl;
492   /\.(eps|EPS|ps|PS)$/                          postscript;
493   /\.py$/                                       python;
494   /\.pyx$/                                      pyrex;
495   /\.js$/                                       javascript;
496   /\.java$/                                     java;
497   /\.([Pp][Aa][Ss]|[Pp][Pp]|[Pp])$/             pascal;
498   /\.[fF]$/                                     fortran;
499   /\.awk$/                                      awk;
500   /\.sh$/                                       sh;
501   /\.vba$/                                      vba;
502   /\.(cshrc|login|logout|history|csh)$/         csh;
503   /\.tcshrc$/                                   tcsh;
504   /\.(zshenv|zprofile|zshrc|zlogin|zlogout)$/   zsh;
505   /\.(bash_profile|bashrc|inputrc)$/            bash;
506   /\.m4$/                                       m4;
507   /\.il$/                                       skill;
508   /\.wrl$/                                      vrml;
509   /\b(rfc.*\.txt|draft-.*\.txt)$/               rfc;
510   /\.inf$/i                                     inf;
511   /\.tex$/                                      tex;
512   /\.wmlscript$/                                wmlscript;
513   /\.wmls$/                                     wmlscript;
514   /^.*$/                                        passthrough;
515 }
516
517 startrules
518 {
519   /.\010.\010.\010./                                    nroff;
520   /-\*- [Cc] -\*-/                                      c;
521   /-\*- [Cc]\+\+ -\*-/                                  cpp;
522   /-\*- [Aa][Dd][Aa] -\*-/                              ada;
523   /-\*- [Aa][Ss][Mm] -\*-/                              asm;
524   /-\*- [Oo][Bb][Jj][Cc] -\*-/                          objc;
525   /-\*- [Ss][Cc][Hh][Ee][Mm][Ee] -\*-/                  scheme;
526   /-\*- [Ee][Mm][Aa][Cc][Ss] [Ll][Ii][Ss][Pp] -\*-/     elisp;
527   /-\*- [Tt][Cc][Ll] -\*-/                              tcl;
528   /-\*- [Vv][Hh][Dd][Ll] -\*-/                          vhdl;
529   /-\*- [Hh][Aa][Ss][Kk][Ee][Ll][Ll] -\*-/              haskell;
530   /-\*- [Ii][Dd][Ll] -\*-/                              idl;
531   /-\*- [Pp][Ee][Rr][Ll] -\*-/                          perl;
532   /^#![ \t]*\/.*\/perl/                                 perl;
533   /^From:/                                              mail;
534   /^#![ \t]*(\/usr)?\/bin\/[ngmt]?awk/                  awk;
535   /^#![ \t]*(\/usr)?\/bin\/sh/                          sh;
536   /^#![ \t]*(\/usr)?\/bin\/csh/                         csh;
537   /^#![ \t]*(\/usr)?(\/local)?\/bin\/tcsh/              tcsh;
538   /^#![ \t]*(\/usr)?(\/local)?\/bin\/zsh/               zsh;
539   /^#![ \t]*(\/usr)?(\/local)?\/bin\/bash/              bash;
540   /^#![ \t]*(\/usr)?(\/ccs)?\/bin\/m4/                  m4;
541   /^#VRML/                                              vrml;
542   /^\04?%!/                                             postscript;
543 }
544
545 \f
546 /*
547  * The global super states.
548  */
549
550 state Highlight
551 {
552   /* If you want to preserve enscript's escape sequences in the state
553      highlighting, uncomment the following rule.  It passes all
554      enscript's escape sequences to the output.
555
556        /^\0[^{]+{[^}]+}/ {
557         language_print ($0);
558        }
559   */
560
561   /* If we are doing nested highlighting (same document can contain
562      multiple highlighting styles), the variable `nested_end_re'
563      specifies the end of the nesting highlight state. */
564   nested_end_re {
565     language_print($0);
566     return;
567   }
568
569   /* Skip output language's special characters. */
570   LANGUAGE_SPECIALS {
571     language_print ($0);
572   }
573 }
574
575 /* How many nesting HighlightEntry states are currently active.  The
576    header and trailer will be printed at the nesting level 0. */
577 highlight_entry_nesting = 0;
578
579 state HighlightEntry extends Highlight
580 {
581   BEGIN {
582     if (highlight_entry_nesting++ == 0)
583       header();
584   }
585   END {
586     if (--highlight_entry_nesting == 0)
587       trailer();
588   }
589 }
590
591
592 \f
593 /*
594  * Helper subroutines and states.
595  */
596
597 state match_balanced_block extends Highlight
598 {
599   match_balanced_block_start {
600     language_print ($0);
601     match_balanced_block_count = match_balanced_block_count + 1;
602   }
603
604   match_balanced_block_end {
605     match_balanced_block_count = match_balanced_block_count - 1;
606     if (match_balanced_block_count == 0)
607       return $0;
608
609     language_print ($0);
610   }
611 }
612
613 sub match_balanced_block (starter, ender)
614 {
615   match_balanced_block_count = 1;
616   match_balanced_block_start = starter;
617   match_balanced_block_end = ender;
618   return call (match_balanced_block);
619 }
620
621 state eat_one_line
622 {
623   /.*\n/ {
624     language_print ($0);
625     return;
626   }
627 }
628
629 \f
630 /*
631 Local variables:
632 mode: c
633 End:
634 */