1 /* This file is a slightly modified version of the file of the same name
2 * included with enscript. The primary change was recognizing a few more
3 * -*- filetype -*- patterns in startrules. */
6 * States definitions file for GNU Enscript.
7 * Copyright (c) 1997-2003 Markku Rossi.
8 * Author: Markku Rossi <mtr@iki.fi>
10 * The latest version of this file can be downloaded from URL:
12 * http://www.iki.fi/~mtr/genscript/enscript.st
16 * This file is part of GNU enscript.
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2, or (at your option)
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with this program; see the file COPYING. If not, write to
30 * the Free Software Foundation, 59 Temple Place - Suite 330,
31 * Boston, MA 02111-1307, USA.
39 * Guildelines for writing new highlighting rules for the GNU Enscript.
41 * - all highlighting states should have a document comment like this:
45 * * Description: C programming language.
46 * * Author: Author Name <author@email.address>
49 * It is used by enscript's --help-pretty-print option to print
50 * description about supported highlighting modes.
52 * - the main entry state (for example, for the C, the state `c') must
53 * be inherited from state `HighlightEntry':
55 * state c extends HighlightEntry
59 * - all help-states smust be inherited from state `Highlight':
61 * state c_string extends Highlight
65 * - all printing should be done with the language_print() procedure
66 * instead of the print() primitive.
68 * - using enscript.el to build regular expressions:
70 * M-x load-file RET enscript.el RET
72 * Move in the buffer to the point where the (build-re '()) ends,
73 * that is, after the last closing parenthesis ')'. Then, type:
77 * Magic should happen.
79 * These rules ensures that enscript's --help-pretty-print option and
80 * the different output languages (HTML, RTF, etc.) work.
83 /* This script needs at least this version of the States program. */
87 * Constants, fonts, etc.
96 font_spec = "Courier@10";
98 /* These components are resolved from <font_spec>. */
103 * Generatel table of contents? This is not supported by all output
109 * The Highlight style. The default style is `emacs' to imitate
110 * Emacs' font lock mode.
115 * Create color outputs?
120 * Use verbose highlighting rules?
122 verbose_highlighting = false;
125 * Target language. Possible values are:
126 * - enscript generate enscript special escapes
127 * - html generate HTML
128 * - overstrike generate overstrike (line printers, less)
129 * - texinfo generate Texinfo
130 * - rtf generate Rich Text Format (rtf - MS Word, WordPerfect)
131 * This code can be souched into MS Word or PowerPoint
132 * for a pretty version of the code
134 language = "enscript";
137 * How many input files we have.
139 num_input_files = "1";
140 current_input_file = 0;
145 document_title = "Enscript Output";
148 * Global variables for nested highlighting `nested.st'.
150 nested_start = "^-+(([ \t]*)([a-zA-Z_0-9]*)([ \t]*))-+$";
153 nested_end_re_cached = 0;
155 nested_default = "passthrough";
162 rgb_values = list ();
164 sub define_color (name, r, g, b)
166 rgb_values[cindex] = list (name, r, g, b);
170 sub color_index (name)
174 for (i = 0; i < length (rgb_values); i = i + 1)
175 if (strcmp (rgb_values[i][0], name) == 0)
181 sub language_color (name)
185 idx = color_index (name);
187 panic ("unknown color `", name, "'");
190 * The map_color() subroutine is language specific and defined in
191 * *_faces() subroutine.
193 map_color (rgb_values[idx][1], rgb_values[idx][2], rgb_values[idx][3]);
196 /* RGB definitions for colors. These are borrowed from X's rgb.txt file. */
198 define_color ("black", 0, 0, 0);
199 define_color ("gray25", 64, 64, 64);
200 define_color ("gray50", 127, 127, 127);
201 define_color ("gray75", 191, 191, 191);
202 define_color ("gray85", 217, 217, 217);
203 define_color ("gray90", 229, 229, 229);
204 define_color ("gray95", 242, 242, 242);
205 define_color ("blue", 0, 0, 255);
206 define_color ("cadet blue", 95, 158, 160);
207 define_color ("dark goldenrod", 184, 134, 11);
208 define_color ("dark olive green", 85, 107, 47);
209 define_color ("firebrick", 178, 34, 34);
210 define_color ("forest green", 34, 139, 34);
211 define_color ("green", 0, 255, 0);
212 define_color ("orchid", 218, 112, 214);
213 define_color ("purple", 160, 32, 240);
214 define_color ("red", 255, 0, 0);
215 define_color ("rosy brown", 188, 143, 143);
217 define_color ("DarkSeaGreen", 143, 188, 143);
218 define_color ("DarkSeaGreen1", 193, 255, 193);
219 define_color ("DarkSeaGreen2", 180, 238, 180);
220 define_color ("DarkSeaGreen3", 155, 205, 155);
221 define_color ("DarkSeaGreen4", 105, 139, 105);
222 define_color ("Goldenrod", 237, 218, 116);
223 define_color ("Aquamarine", 67, 183, 186);
224 define_color ("SeaGreen2", 100, 233, 134);
225 define_color ("Coral", 247, 101, 65);
226 define_color ("DarkSlateGray1", 154, 254, 255);
227 define_color ("LightGrey", 211, 211, 211);
237 print ("DEBUG: ", msg, "\n");
240 sub is_prefix (prefix, string)
242 return strncmp (prefix, string, length (prefix)) == 0;
245 sub strchr (string, ch)
247 local len = length (string), i;
249 for (i = 0; i < len; i = i + 1)
256 sub need_version (major, minor, beta)
260 regmatch (version, (/([0-9]+)\.([0-9]+)\.([0-9]+)/));
261 v = list (int ($1), int ($2), int ($3));
262 r = list (major, minor, beta);
264 for (i = 0; i < 3; i = i + 1)
267 else if (v[i] < r[i])
274 /* Highlight types which match expression <re> from string <data>. */
275 sub highlight_types (data, re)
279 while (regmatch (data, re))
286 match_len = length ($B, $0);
288 data = substring (data, match_len, length (data));
291 language_print (data);
296 * The supported faces. These functions are used in the highlighting
297 * rules to mark different logical elements of the code. The
298 * different faces and their properties (face_*) are defined in the
299 * style definition files. The face_on() and face_off() functions are
300 * defined in the output language definition files.
308 face_off (face_bold);
314 face_on (face_italic);
316 face_off (face_italic);
322 face_on (face_bold_italic);
324 face_off (face_bold_italic);
327 sub comment_face (on)
330 face_on (face_comment);
332 face_off (face_comment);
335 sub function_name_face (on)
338 face_on (face_function_name);
340 face_off (face_function_name);
343 sub variable_name_face (on)
346 face_on (face_variable_name);
348 face_off (face_variable_name);
351 sub keyword_face (on)
354 face_on (face_keyword);
356 face_off (face_keyword);
359 sub reference_face (on)
362 face_on (face_reference);
364 face_off (face_reference);
370 face_on (face_string);
372 face_off (face_string);
375 sub builtin_face (on)
378 face_on (face_builtin);
380 face_off (face_builtin);
388 face_off (face_type);
391 sub highlight_face (on)
394 face_on (face_highlight);
396 face_off (face_highlight);
406 /* Set debug level. */
407 debug_level = int (debug);
412 /* Increment input file count. */
413 current_input_file = current_input_file + 1;
416 idx = strchr (font_spec, '@');
418 panic ("malformed font spec: `", font_spec, "'");
420 font = substring (font_spec, 0, idx);
421 ptsize = substring (font_spec, idx + 1, length (font_spec));
423 debug (concat ("start: ", font, "@", ptsize));
425 /* Construct bold, italic, etc. fonts for our current body font. */
426 if (is_prefix ("AvantGarde", font))
428 bold_font = "AvantGarde-Demi";
429 italic_font = "AvantGarde-BookOblique";
430 bold_italic_font = "AvantGarde-DemiOblique";
432 else if (regmatch (font, /^Bookman|Souvenir/))
434 bold_font = concat ($0, "-Demi");
435 italic_font = concat ($0, "-LightItalic");
436 bold_italic_font = concat ($0, "-DemiItalic");
438 else if (regmatch (font, /^Lucida(Sans-)?Typewriter/))
440 bold_font = concat ($0, "Bold");
441 italic_font = concat ($0, "Oblique");
442 bold_italic_font = concat ($0, "BoldOblique");
444 else if (regmatch (font, /^(.*)-Roman$/))
446 bold_font = concat ($1, "-Bold");
447 italic_font = concat ($1, "-Italic");
448 bold_italic_font = concat ($1, "-BoldItalic");
452 bold_font = concat (font, "-Bold");
453 italic_font = concat (font, "-Oblique");
454 bold_italic_font = concat (font, "-BoldOblique");
457 /* Create regular expressions for nested highlighting. */
458 nested_start_re = regexp (nested_start);
459 nested_end_re_cached = regexp (nested_end);
461 /* Define output faces. */
462 calln (concat ("lang_", language));
464 /* Define our highlight style. */
465 calln (concat ("style_", style));
467 /* Resolve start state. */
468 if (check_startrules ())
469 debug ("startstate from startrules");
470 if (check_namerules ())
471 debug ("startstate from namerules");
477 /\.(c++|C|H|cpp|cc|cxx)$/ cpp;
479 /\.(mpl|mp|maple)$/ maple;
480 /\.(scm|scheme)$/ scheme;
481 /\b\.emacs$|\.el$/ elisp;
485 /(M|m)akefile.*/ makefile;
486 /\.(MOD|DEF|mi|md)$/ modula_2;
490 /\bChangeLog$/ changelog;
491 /\.(vhd|vhdl)$/ vhdl;
492 /\.(scr|.syn|.synth)$/ synopsys;
494 /\.(hs|lhs|gs|lgs)$/ haskell;
496 /\.(eps|EPS|ps|PS)$/ postscript;
501 /\.([Pp][Aa][Ss]|[Pp][Pp]|[Pp])$/ pascal;
506 /\.(cshrc|login|logout|history|csh)$/ csh;
508 /\.(zshenv|zprofile|zshrc|zlogin|zlogout)$/ zsh;
509 /\.(bash_profile|bashrc|inputrc)$/ bash;
513 /\b(rfc.*\.txt|draft-.*\.txt)$/ rfc;
516 /\.wmlscript$/ wmlscript;
523 /.\010.\010.\010./ nroff;
525 /-\*- [Cc]\+\+ -\*-/ cpp;
526 /-\*- [Aa][Dd][Aa] -\*-/ ada;
527 /-\*- [Aa][Ss][Mm] -\*-/ asm;
528 /-\*- [Oo][Bb][Jj][Cc] -\*-/ objc;
529 /-\*- [Ss][Cc][Hh][Ee][Mm][Ee] -\*-/ scheme;
530 /-\*- [Ee][Mm][Aa][Cc][Ss] [Ll][Ii][Ss][Pp] -\*-/ elisp;
531 /-\*- [Tt][Cc][Ll] -\*-/ tcl;
532 /-\*- [Vv][Hh][Dd][Ll] -\*-/ vhdl;
533 /-\*- [Hh][Aa][Ss][Kk][Ee][Ll][Ll] -\*-/ haskell;
534 /-\*- [Ii][Dd][Ll] -\*-/ idl;
535 /-\*- [Pp][Ee][Rr][Ll] -\*-/ perl;
536 /^#![ \t]*\/.*\/perl/ perl;
538 /^#![ \t]*(\/usr)?\/bin\/[ngmt]?awk/ awk;
539 /-\*- [Ss][Hh] -\*-/ sh;
540 /^#![ \t]*(\/usr)?\/bin\/sh/ sh;
541 /^#![ \t]*(\/usr)?\/bin\/csh/ csh;
542 /^#![ \t]*(\/usr)?(\/local)?\/bin\/tcsh/ tcsh;
543 /^#![ \t]*(\/usr)?(\/local)?\/bin\/zsh/ zsh;
544 /^#![ \t]*(\/usr)?(\/local)?\/bin\/bash/ bash;
545 /^#![ \t]*(\/usr)?(\/ccs)?\/bin\/m4/ m4;
547 /^\04?%!/ postscript;
552 * The global super states.
557 /* If you want to preserve enscript's escape sequences in the state
558 highlighting, uncomment the following rule. It passes all
559 enscript's escape sequences to the output.
566 /* If we are doing nested highlighting (same document can contain
567 multiple highlighting styles), the variable `nested_end_re'
568 specifies the end of the nesting highlight state. */
574 /* Skip output language's special characters. */
580 /* How many nesting HighlightEntry states are currently active. The
581 header and trailer will be printed at the nesting level 0. */
582 highlight_entry_nesting = 0;
584 state HighlightEntry extends Highlight
587 if (highlight_entry_nesting++ == 0)
591 if (--highlight_entry_nesting == 0)
599 * Helper subroutines and states.
602 state match_balanced_block extends Highlight
604 match_balanced_block_start {
606 match_balanced_block_count = match_balanced_block_count + 1;
609 match_balanced_block_end {
610 match_balanced_block_count = match_balanced_block_count - 1;
611 if (match_balanced_block_count == 0)
618 sub match_balanced_block (starter, ender)
620 match_balanced_block_count = 1;
621 match_balanced_block_start = starter;
622 match_balanced_block_end = ender;
623 return call (match_balanced_block);