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 * 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)
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.
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.
31 * $Id: enscript.st,v 1.3 2003/03/05 08:31:31 mtr Exp $
35 * Guildelines for writing new highlighting rules for the GNU Enscript.
37 * - all highlighting states should have a document comment like this:
41 * * Description: C programming language.
42 * * Author: Author Name <author@email.address>
45 * It is used by enscript's --help-pretty-print option to print
46 * description about supported highlighting modes.
48 * - the main entry state (for example, for the C, the state `c') must
49 * be inherited from state `HighlightEntry':
51 * state c extends HighlightEntry
55 * - all help-states smust be inherited from state `Highlight':
57 * state c_string extends Highlight
61 * - all printing should be done with the language_print() procedure
62 * instead of the print() primitive.
64 * - using enscript.el to build regular expressions:
66 * M-x load-file RET enscript.el RET
68 * Move in the buffer to the point where the (build-re '()) ends,
69 * that is, after the last closing parenthesis ')'. Then, type:
73 * Magic should happen.
75 * These rules ensures that enscript's --help-pretty-print option and
76 * the different output languages (HTML, RTF, etc.) work.
79 /* This script needs at least this version of the States program. */
83 * Constants, fonts, etc.
92 font_spec = "Courier@10";
94 /* These components are resolved from <font_spec>. */
99 * Generatel table of contents? This is not supported by all output
105 * The Highlight style. The default style is `emacs' to imitate
106 * Emacs' font lock mode.
111 * Create color outputs?
116 * Use verbose highlighting rules?
118 verbose_highlighting = false;
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
130 language = "enscript";
133 * How many input files we have.
135 num_input_files = "1";
136 current_input_file = 0;
141 document_title = "Enscript Output";
144 * Global variables for nested highlighting `nested.st'.
146 nested_start = "^-+(([ \t]*)([a-zA-Z_0-9]*)([ \t]*))-+$";
149 nested_end_re_cached = 0;
151 nested_default = "passthrough";
158 rgb_values = list ();
160 sub define_color (name, r, g, b)
162 rgb_values[cindex] = list (name, r, g, b);
166 sub color_index (name)
170 for (i = 0; i < length (rgb_values); i = i + 1)
171 if (strcmp (rgb_values[i][0], name) == 0)
177 sub language_color (name)
181 idx = color_index (name);
183 panic ("unknown color `", name, "'");
186 * The map_color() subroutine is language specific and defined in
187 * *_faces() subroutine.
189 map_color (rgb_values[idx][1], rgb_values[idx][2], rgb_values[idx][3]);
192 /* RGB definitions for colors. These are borrowed from X's rgb.txt file. */
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);
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);
233 print ("DEBUG: ", msg, "\n");
236 sub is_prefix (prefix, string)
238 return strncmp (prefix, string, length (prefix)) == 0;
241 sub strchr (string, ch)
243 local len = length (string), i;
245 for (i = 0; i < len; i = i + 1)
252 sub need_version (major, minor, beta)
256 regmatch (version, (/([0-9]+)\.([0-9]+)\.([0-9]+)/));
257 v = list (int ($1), int ($2), int ($3));
258 r = list (major, minor, beta);
260 for (i = 0; i < 3; i = i + 1)
263 else if (v[i] < r[i])
270 /* Highlight types which match expression <re> from string <data>. */
271 sub highlight_types (data, re)
275 while (regmatch (data, re))
282 match_len = length ($B, $0);
284 data = substring (data, match_len, length (data));
287 language_print (data);
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.
304 face_off (face_bold);
310 face_on (face_italic);
312 face_off (face_italic);
318 face_on (face_bold_italic);
320 face_off (face_bold_italic);
323 sub comment_face (on)
326 face_on (face_comment);
328 face_off (face_comment);
331 sub function_name_face (on)
334 face_on (face_function_name);
336 face_off (face_function_name);
339 sub variable_name_face (on)
342 face_on (face_variable_name);
344 face_off (face_variable_name);
347 sub keyword_face (on)
350 face_on (face_keyword);
352 face_off (face_keyword);
355 sub reference_face (on)
358 face_on (face_reference);
360 face_off (face_reference);
366 face_on (face_string);
368 face_off (face_string);
371 sub builtin_face (on)
374 face_on (face_builtin);
376 face_off (face_builtin);
384 face_off (face_type);
387 sub highlight_face (on)
390 face_on (face_highlight);
392 face_off (face_highlight);
402 /* Set debug level. */
403 debug_level = int (debug);
408 /* Increment input file count. */
409 current_input_file = current_input_file + 1;
412 idx = strchr (font_spec, '@');
414 panic ("malformed font spec: `", font_spec, "'");
416 font = substring (font_spec, 0, idx);
417 ptsize = substring (font_spec, idx + 1, length (font_spec));
419 debug (concat ("start: ", font, "@", ptsize));
421 /* Construct bold, italic, etc. fonts for our current body font. */
422 if (is_prefix ("AvantGarde", font))
424 bold_font = "AvantGarde-Demi";
425 italic_font = "AvantGarde-BookOblique";
426 bold_italic_font = "AvantGarde-DemiOblique";
428 else if (regmatch (font, /^Bookman|Souvenir/))
430 bold_font = concat ($0, "-Demi");
431 italic_font = concat ($0, "-LightItalic");
432 bold_italic_font = concat ($0, "-DemiItalic");
434 else if (regmatch (font, /^Lucida(Sans-)?Typewriter/))
436 bold_font = concat ($0, "Bold");
437 italic_font = concat ($0, "Oblique");
438 bold_italic_font = concat ($0, "BoldOblique");
440 else if (regmatch (font, /^(.*)-Roman$/))
442 bold_font = concat ($1, "-Bold");
443 italic_font = concat ($1, "-Italic");
444 bold_italic_font = concat ($1, "-BoldItalic");
448 bold_font = concat (font, "-Bold");
449 italic_font = concat (font, "-Oblique");
450 bold_italic_font = concat (font, "-BoldOblique");
453 /* Create regular expressions for nested highlighting. */
454 nested_start_re = regexp (nested_start);
455 nested_end_re_cached = regexp (nested_end);
457 /* Define output faces. */
458 calln (concat ("lang_", language));
460 /* Define our highlight style. */
461 calln (concat ("style_", style));
463 /* Resolve start state. */
464 if (check_startrules ())
465 debug ("startstate from startrules");
466 if (check_namerules ())
467 debug ("startstate from namerules");
473 /\.(c++|C|H|cpp|cc|cxx)$/ cpp;
475 /\.(mpl|mp|maple)$/ maple;
476 /\.(scm|scheme)$/ scheme;
477 /\b\.emacs$|\.el$/ elisp;
481 /(M|m)akefile.*/ makefile;
482 /\.(MOD|DEF|mi|md)$/ modula_2;
486 /\bChangeLog$/ changelog;
487 /\.(vhd|vhdl)$/ vhdl;
488 /\.(scr|.syn|.synth)$/ synopsys;
490 /\.(hs|lhs|gs|lgs)$/ haskell;
492 /\.(eps|EPS|ps|PS)$/ postscript;
497 /\.([Pp][Aa][Ss]|[Pp][Pp]|[Pp])$/ pascal;
502 /\.(cshrc|login|logout|history|csh)$/ csh;
504 /\.(zshenv|zprofile|zshrc|zlogin|zlogout)$/ zsh;
505 /\.(bash_profile|bashrc|inputrc)$/ bash;
509 /\b(rfc.*\.txt|draft-.*\.txt)$/ rfc;
512 /\.wmlscript$/ wmlscript;
519 /.\010.\010.\010./ nroff;
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;
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;
542 /^\04?%!/ postscript;
547 * The global super states.
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.
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. */
569 /* Skip output language's special characters. */
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;
579 state HighlightEntry extends Highlight
582 if (highlight_entry_nesting++ == 0)
586 if (--highlight_entry_nesting == 0)
594 * Helper subroutines and states.
597 state match_balanced_block extends Highlight
599 match_balanced_block_start {
601 match_balanced_block_count = match_balanced_block_count + 1;
604 match_balanced_block_end {
605 match_balanced_block_count = match_balanced_block_count - 1;
606 if (match_balanced_block_count == 0)
613 sub match_balanced_block (starter, ender)
615 match_balanced_block_count = 1;
616 match_balanced_block_start = starter;
617 match_balanced_block_end = ender;
618 return call (match_balanced_block);