2 * States definitions file for GNU Enscript.
3 * Copyright (c) 1997-2003 Markku Rossi.
4 * Author: Markku Rossi <mtr@iki.fi>
6 * The latest version of this file can be downloaded from URL:
8 * http://www.iki.fi/~mtr/genscript/enscript.st
12 * This file is part of GNU Enscript.
14 * Enscript 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 3 of the License, or
17 * (at your option) any later version.
19 * Enscript 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.
24 * You should have received a copy of the GNU General Public License
25 * along with Enscript. If not, see <http://www.gnu.org/licenses/>.
29 * $Id: enscript.st,v 1.3 2003/03/05 08:31:31 mtr Exp $
33 * Guildelines for writing new highlighting rules for the GNU Enscript.
35 * - all highlighting states should have a document comment like this:
39 * * Description: C programming language.
40 * * Author: Author Name <author@email.address>
43 * It is used by enscript's --help-pretty-print option to print
44 * description about supported highlighting modes.
46 * - the main entry state (for example, for the C, the state `c') must
47 * be inherited from state `HighlightEntry':
49 * state c extends HighlightEntry
53 * - all help-states smust be inherited from state `Highlight':
55 * state c_string extends Highlight
59 * - all printing should be done with the language_print() procedure
60 * instead of the print() primitive.
62 * - using enscript.el to build regular expressions:
64 * M-x load-file RET enscript.el RET
66 * Move in the buffer to the point where the (build-re '()) ends,
67 * that is, after the last closing parenthesis ')'. Then, type:
71 * Magic should happen.
73 * These rules ensures that enscript's --help-pretty-print option and
74 * the different output languages (HTML, RTF, etc.) work.
77 /* This script needs at least this version of the States program. */
81 * Constants, fonts, etc.
90 font_spec = "Courier@10";
92 /* These components are resolved from <font_spec>. */
97 * Generatel table of contents? This is not supported by all output
103 * The Highlight style. The default style is `emacs' to imitate
104 * Emacs' font lock mode.
109 * Create color outputs?
114 * Use verbose highlighting rules?
116 verbose_highlighting = false;
119 * Target language. Possible values are:
120 * - enscript generate enscript special escapes
121 * - html generate HTML
122 * - overstrike generate overstrike (line printers, less)
123 * - texinfo generate Texinfo
124 * - rtf generate Rich Text Format (rtf - MS Word, WordPerfect)
125 * This code can be souched into MS Word or PowerPoint
126 * for a pretty version of the code
128 language = "enscript";
131 * How many input files we have.
133 num_input_files = "1";
134 current_input_file = 0;
139 document_title = "Enscript Output";
142 * Global variables for nested highlighting `nested.st'.
144 nested_start = "^-+(([ \t]*)([a-zA-Z_0-9]*)([ \t]*))-+$";
147 nested_end_re_cached = 0;
149 nested_default = "passthrough";
156 rgb_values = list ();
158 sub define_color (name, r, g, b)
160 rgb_values[cindex] = list (name, r, g, b);
164 sub color_index (name)
168 for (i = 0; i < length (rgb_values); i = i + 1)
169 if (strcmp (rgb_values[i][0], name) == 0)
175 sub language_color (name)
179 idx = color_index (name);
181 panic ("unknown color `", name, "'");
184 * The map_color() subroutine is language specific and defined in
185 * *_faces() subroutine.
187 map_color (rgb_values[idx][1], rgb_values[idx][2], rgb_values[idx][3]);
190 /* RGB definitions for colors. These are borrowed from X's rgb.txt file. */
192 define_color ("black", 0, 0, 0);
193 define_color ("gray25", 64, 64, 64);
194 define_color ("gray50", 127, 127, 127);
195 define_color ("gray75", 191, 191, 191);
196 define_color ("gray85", 217, 217, 217);
197 define_color ("gray90", 229, 229, 229);
198 define_color ("gray95", 242, 242, 242);
199 define_color ("blue", 0, 0, 255);
200 define_color ("cadet blue", 95, 158, 160);
201 define_color ("dark goldenrod", 184, 134, 11);
202 define_color ("dark olive green", 85, 107, 47);
203 define_color ("firebrick", 178, 34, 34);
204 define_color ("forest green", 34, 139, 34);
205 define_color ("green", 0, 255, 0);
206 define_color ("orchid", 218, 112, 214);
207 define_color ("purple", 160, 32, 240);
208 define_color ("red", 255, 0, 0);
209 define_color ("rosy brown", 188, 143, 143);
211 define_color ("DarkSeaGreen", 143, 188, 143);
212 define_color ("DarkSeaGreen1", 193, 255, 193);
213 define_color ("DarkSeaGreen2", 180, 238, 180);
214 define_color ("DarkSeaGreen3", 155, 205, 155);
215 define_color ("DarkSeaGreen4", 105, 139, 105);
216 define_color ("Goldenrod", 237, 218, 116);
217 define_color ("Aquamarine", 67, 183, 186);
218 define_color ("SeaGreen2", 100, 233, 134);
219 define_color ("Coral", 247, 101, 65);
220 define_color ("DarkSlateGray1", 154, 254, 255);
221 define_color ("LightGrey", 211, 211, 211);
231 print ("DEBUG: ", msg, "\n");
234 sub is_prefix (prefix, string)
236 return strncmp (prefix, string, length (prefix)) == 0;
239 sub strchr (string, ch)
241 local len = length (string), i;
243 for (i = 0; i < len; i = i + 1)
250 sub need_version (major, minor, beta)
254 regmatch (version, (/([0-9]+)\.([0-9]+)\.([0-9]+)/));
255 v = list (int ($1), int ($2), int ($3));
256 r = list (major, minor, beta);
258 for (i = 0; i < 3; i = i + 1)
261 else if (v[i] < r[i])
268 /* Highlight types which match expression <re> from string <data>. */
269 sub highlight_types (data, re)
273 while (regmatch (data, re))
280 match_len = length ($B, $0);
282 data = substring (data, match_len, length (data));
285 language_print (data);
290 * The supported faces. These functions are used in the highlighting
291 * rules to mark different logical elements of the code. The
292 * different faces and their properties (face_*) are defined in the
293 * style definition files. The face_on() and face_off() functions are
294 * defined in the output language definition files.
302 face_off (face_bold);
308 face_on (face_italic);
310 face_off (face_italic);
316 face_on (face_bold_italic);
318 face_off (face_bold_italic);
321 sub comment_face (on)
324 face_on (face_comment);
326 face_off (face_comment);
329 sub function_name_face (on)
332 face_on (face_function_name);
334 face_off (face_function_name);
337 sub variable_name_face (on)
340 face_on (face_variable_name);
342 face_off (face_variable_name);
345 sub keyword_face (on)
348 face_on (face_keyword);
350 face_off (face_keyword);
353 sub reference_face (on)
356 face_on (face_reference);
358 face_off (face_reference);
364 face_on (face_string);
366 face_off (face_string);
369 sub builtin_face (on)
372 face_on (face_builtin);
374 face_off (face_builtin);
382 face_off (face_type);
385 sub highlight_face (on)
388 face_on (face_highlight);
390 face_off (face_highlight);
400 /* Set debug level. */
401 debug_level = int (debug);
406 /* Increment input file count. */
407 current_input_file = current_input_file + 1;
410 idx = strchr (font_spec, '@');
412 panic ("malformed font spec: `", font_spec, "'");
414 font = substring (font_spec, 0, idx);
415 ptsize = substring (font_spec, idx + 1, length (font_spec));
417 debug (concat ("start: ", font, "@", ptsize));
419 /* Construct bold, italic, etc. fonts for our current body font. */
420 if (is_prefix ("AvantGarde", font))
422 bold_font = "AvantGarde-Demi";
423 italic_font = "AvantGarde-BookOblique";
424 bold_italic_font = "AvantGarde-DemiOblique";
426 else if (regmatch (font, /^Bookman|Souvenir/))
428 bold_font = concat ($0, "-Demi");
429 italic_font = concat ($0, "-LightItalic");
430 bold_italic_font = concat ($0, "-DemiItalic");
432 else if (regmatch (font, /^Lucida(Sans-)?Typewriter/))
434 bold_font = concat ($0, "Bold");
435 italic_font = concat ($0, "Oblique");
436 bold_italic_font = concat ($0, "BoldOblique");
438 else if (regmatch (font, /^(.*)-Roman$/))
440 bold_font = concat ($1, "-Bold");
441 italic_font = concat ($1, "-Italic");
442 bold_italic_font = concat ($1, "-BoldItalic");
446 bold_font = concat (font, "-Bold");
447 italic_font = concat (font, "-Oblique");
448 bold_italic_font = concat (font, "-BoldOblique");
451 /* Create regular expressions for nested highlighting. */
452 nested_start_re = regexp (nested_start);
453 nested_end_re_cached = regexp (nested_end);
455 /* Define output faces. */
456 calln (concat ("lang_", language));
458 /* Define our highlight style. */
459 calln (concat ("style_", style));
461 /* Resolve start state. */
462 if (check_startrules ())
463 debug ("startstate from startrules");
464 if (check_namerules ())
465 debug ("startstate from namerules");
471 /\.(c++|C|H|cpp|cc|cxx)$/ cpp;
473 /\.(mpl|mp|maple)$/ maple;
474 /\.(scm|scheme)$/ scheme;
475 /\b\.emacs$|\.el$/ elisp;
479 /(M|m)akefile.*/ makefile;
480 /\.(MOD|DEF|mi|md)$/ modula_2;
484 /\bChangeLog$/ changelog;
485 /\.(vhd|vhdl)$/ vhdl;
486 /\.(scr|.syn|.synth)$/ synopsys;
488 /\.(hs|lhs|gs|lgs)$/ haskell;
490 /\.(eps|EPS|ps|PS)$/ postscript;
495 /\.([Pp][Aa][Ss]|[Pp][Pp]|[Pp])$/ pascal;
501 /\.(cshrc|login|logout|history|csh)$/ csh;
503 /\.(zshenv|zprofile|zshrc|zlogin|zlogout)$/ zsh;
504 /\.(bash_profile|bashrc|inputrc)$/ bash;
508 /\b(rfc.*\.txt|draft-.*\.txt)$/ rfc;
511 /\.wmlscript$/ wmlscript;
518 /.\010.\010.\010./ nroff;
520 /-\*- [Cc]\+\+ -\*-/ cpp;
521 /-\*- [Aa][Dd][Aa] -\*-/ ada;
522 /-\*- [Aa][Ss][Mm] -\*-/ asm;
523 /-\*- [Oo][Bb][Jj][Cc] -\*-/ objc;
524 /-\*- [Ss][Cc][Hh][Ee][Mm][Ee] -\*-/ scheme;
525 /-\*- [Ee][Mm][Aa][Cc][Ss] [Ll][Ii][Ss][Pp] -\*-/ elisp;
526 /-\*- [Tt][Cc][Ll] -\*-/ tcl;
527 /-\*- [Vv][Hh][Dd][Ll] -\*-/ vhdl;
528 /-\*- [Hh][Aa][Ss][Kk][Ee][Ll][Ll] -\*-/ haskell;
529 /-\*- [Ii][Dd][Ll] -\*-/ idl;
530 /-\*- [Pp][Ee][Rr][Ll] -\*-/ perl;
531 /^#![ \t]*\/.*\/perl/ perl;
533 /^#![ \t]*(\/usr)?\/bin\/[ngmt]?awk/ awk;
534 /^#![ \t]*(\/usr)?\/bin\/sh/ sh;
535 /^#![ \t]*(\/usr)?\/bin\/csh/ csh;
536 /^#![ \t]*(\/usr)?(\/local)?\/bin\/tcsh/ tcsh;
537 /^#![ \t]*(\/usr)?(\/local)?\/bin\/zsh/ zsh;
538 /^#![ \t]*(\/usr)?(\/local)?\/bin\/bash/ bash;
539 /^#![ \t]*(\/usr)?(\/ccs)?\/bin\/m4/ m4;
541 /^\04?%!/ postscript;
546 * The global super states.
551 /* If you want to preserve enscript's escape sequences in the state
552 highlighting, uncomment the following rule. It passes all
553 enscript's escape sequences to the output.
560 /* If we are doing nested highlighting (same document can contain
561 multiple highlighting styles), the variable `nested_end_re'
562 specifies the end of the nesting highlight state. */
568 /* Skip output language's special characters. */
574 /* How many nesting HighlightEntry states are currently active. The
575 header and trailer will be printed at the nesting level 0. */
576 highlight_entry_nesting = 0;
578 state HighlightEntry extends Highlight
581 if (highlight_entry_nesting++ == 0)
585 if (--highlight_entry_nesting == 0)
593 * Helper subroutines and states.
596 state match_balanced_block extends Highlight
598 match_balanced_block_start {
600 match_balanced_block_count = match_balanced_block_count + 1;
603 match_balanced_block_end {
604 match_balanced_block_count = match_balanced_block_count - 1;
605 if (match_balanced_block_count == 0)
612 sub match_balanced_block (starter, ender)
614 match_balanced_block_count = 1;
615 match_balanced_block_start = starter;
616 match_balanced_block_end = ender;
617 return call (match_balanced_block);