enscript.st - enscript - GNU Enscript
(HTM) git clone git://thinkerwim.org/enscript.git
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
enscript.st (14227B)
---
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 * 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.
18 *
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.
23 *
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/>.
26 */
27
28 /*
29 * $Id: enscript.st,v 1.3 2003/03/05 08:31:31 mtr Exp $
30 */
31
32 /*
33 * Guildelines for writing new highlighting rules for the GNU Enscript.
34 *
35 * - all highlighting states should have a document comment like this:
36 *
37 * /**
38 * * Name: c
39 * * Description: C programming language.
40 * * Author: Author Name <author@email.address>
41 * * ...
42 *
43 * It is used by enscript's --help-pretty-print option to print
44 * description about supported highlighting modes.
45 *
46 * - the main entry state (for example, for the C, the state `c') must
47 * be inherited from state `HighlightEntry':
48 *
49 * state c extends HighlightEntry
50 * {
51 * ...
52 *
53 * - all help-states smust be inherited from state `Highlight':
54 *
55 * state c_string extends Highlight
56 * {
57 * ...
58 *
59 * - all printing should be done with the language_print() procedure
60 * instead of the print() primitive.
61 *
62 * - using enscript.el to build regular expressions:
63 *
64 * M-x load-file RET enscript.el RET
65 *
66 * Move in the buffer to the point where the (build-re '()) ends,
67 * that is, after the last closing parenthesis ')'. Then, type:
68 *
69 * C-x C-e
70 *
71 * Magic should happen.
72 *
73 * These rules ensures that enscript's --help-pretty-print option and
74 * the different output languages (HTML, RTF, etc.) work.
75 */
76
77 /* This script needs at least this version of the States program. */
78 prereq ("1.6.2");
79
80 /*
81 * Constants, fonts, etc.
82 */
83
84 debug = "0";
85
86 /* Boolean values. */
87 true = 1;
88 false = 0;
89
90 font_spec = "Courier@10";
91
92 /* These components are resolved from <font_spec>. */
93 font = "";
94 ptsize = "";
95
96 /*
97 * Generatel table of contents? This is not supported by all output
98 * languages.
99 */
100 toc = "0";
101
102 /*
103 * The Highlight style. The default style is `emacs' to imitate
104 * Emacs' font lock mode.
105 */
106 style = "emacs";
107
108 /*
109 * Create color outputs?
110 */
111 color = "1";
112
113 /*
114 * Use verbose highlighting rules?
115 */
116 verbose_highlighting = false;
117
118 /*
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
127 */
128 language = "enscript";
129
130 /*
131 * How many input files we have.
132 */
133 num_input_files = "1";
134 current_input_file = 0;
135
136 /*
137 * Document title.
138 */
139 document_title = "Enscript Output";
140
141 /*
142 * Global variables for nested highlighting `nested.st'.
143 */
144 nested_start = "^-+(([ \t]*)([a-zA-Z_0-9]*)([ \t]*))-+$";
145 nested_start_re = 0;
146 nested_end = "^-+$";
147 nested_end_re_cached = 0;
148 nested_end_re = 0;
149 nested_default = "passthrough";
150
151 /*
152 * Color definitions.
153 */
154
155 cindex = 0;
156 rgb_values = list ();
157
158 sub define_color (name, r, g, b)
159 {
160 rgb_values[cindex] = list (name, r, g, b);
161 cindex = cindex + 1;
162 }
163
164 sub color_index (name)
165 {
166 local i;
167
168 for (i = 0; i < length (rgb_values); i = i + 1)
169 if (strcmp (rgb_values[i][0], name) == 0)
170 return i;
171
172 return -1;
173 }
174
175 sub language_color (name)
176 {
177 local idx;
178
179 idx = color_index (name);
180 if (idx < 0)
181 panic ("unknown color `", name, "'");
182
183 /*
184 * The map_color() subroutine is language specific and defined in
185 * *_faces() subroutine.
186 */
187 map_color (rgb_values[idx][1], rgb_values[idx][2], rgb_values[idx][3]);
188 }
189
190 /* RGB definitions for colors. These are borrowed from X's rgb.txt file. */
191
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);
210
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);
222
223
224 /*
225 * General helpers.
226 */
227
228 sub debug (msg)
229 {
230 if (debug_level)
231 print ("DEBUG: ", msg, "\n");
232 }
233
234 sub is_prefix (prefix, string)
235 {
236 return strncmp (prefix, string, length (prefix)) == 0;
237 }
238
239 sub strchr (string, ch)
240 {
241 local len = length (string), i;
242
243 for (i = 0; i < len; i = i + 1)
244 if (string[i] == ch)
245 return i;
246
247 return -1;
248 }
249
250 sub need_version (major, minor, beta)
251 {
252 local r, v, i;
253
254 regmatch (version, (/([0-9]+)\.([0-9]+)\.([0-9]+)/));
255 v = list (int ($1), int ($2), int ($3));
256 r = list (major, minor, beta);
257
258 for (i = 0; i < 3; i = i + 1)
259 if (v[i] > r[i])
260 return 1;
261 else if (v[i] < r[i])
262 return 0;
263
264 /* Exact match. */
265 return 1;
266 }
267
268 /* Highlight types which match expression <re> from string <data>. */
269 sub highlight_types (data, re)
270 {
271 local match_len;
272
273 while (regmatch (data, re))
274 {
275 language_print ($B);
276 type_face (true);
277 language_print ($0);
278 type_face (false);
279
280 match_len = length ($B, $0);
281
282 data = substring (data, match_len, length (data));
283 }
284
285 language_print (data);
286 }
287
288
289 /*
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.
295 */
296
297 sub bold (on)
298 {
299 if (on)
300 face_on (face_bold);
301 else
302 face_off (face_bold);
303 }
304
305 sub italic (on)
306 {
307 if (on)
308 face_on (face_italic);
309 else
310 face_off (face_italic);
311 }
312
313 sub bold_italic (on)
314 {
315 if (on)
316 face_on (face_bold_italic);
317 else
318 face_off (face_bold_italic);
319 }
320
321 sub comment_face (on)
322 {
323 if (on)
324 face_on (face_comment);
325 else
326 face_off (face_comment);
327 }
328
329 sub function_name_face (on)
330 {
331 if (on)
332 face_on (face_function_name);
333 else
334 face_off (face_function_name);
335 }
336
337 sub variable_name_face (on)
338 {
339 if (on)
340 face_on (face_variable_name);
341 else
342 face_off (face_variable_name);
343 }
344
345 sub keyword_face (on)
346 {
347 if (on)
348 face_on (face_keyword);
349 else
350 face_off (face_keyword);
351 }
352
353 sub reference_face (on)
354 {
355 if (on)
356 face_on (face_reference);
357 else
358 face_off (face_reference);
359 }
360
361 sub string_face (on)
362 {
363 if (on)
364 face_on (face_string);
365 else
366 face_off (face_string);
367 }
368
369 sub builtin_face (on)
370 {
371 if (on)
372 face_on (face_builtin);
373 else
374 face_off (face_builtin);
375 }
376
377 sub type_face (on)
378 {
379 if (on)
380 face_on (face_type);
381 else
382 face_off (face_type);
383 }
384
385 sub highlight_face (on)
386 {
387 if (on)
388 face_on (face_highlight);
389 else
390 face_off (face_highlight);
391 }
392
393
394 /*
395 * Initializations.
396 */
397
398 start
399 {
400 /* Set debug level. */
401 debug_level = int (debug);
402
403 /* Use colors? */
404 color = int (color);
405
406 /* Increment input file count. */
407 current_input_file = current_input_file + 1;
408
409 /* Resolve fonts. */
410 idx = strchr (font_spec, '@');
411 if (idx < 0)
412 panic ("malformed font spec: `", font_spec, "'");
413
414 font = substring (font_spec, 0, idx);
415 ptsize = substring (font_spec, idx + 1, length (font_spec));
416
417 debug (concat ("start: ", font, "@", ptsize));
418
419 /* Construct bold, italic, etc. fonts for our current body font. */
420 if (is_prefix ("AvantGarde", font))
421 {
422 bold_font = "AvantGarde-Demi";
423 italic_font = "AvantGarde-BookOblique";
424 bold_italic_font = "AvantGarde-DemiOblique";
425 }
426 else if (regmatch (font, /^Bookman|Souvenir/))
427 {
428 bold_font = concat ($0, "-Demi");
429 italic_font = concat ($0, "-LightItalic");
430 bold_italic_font = concat ($0, "-DemiItalic");
431 }
432 else if (regmatch (font, /^Lucida(Sans-)?Typewriter/))
433 {
434 bold_font = concat ($0, "Bold");
435 italic_font = concat ($0, "Oblique");
436 bold_italic_font = concat ($0, "BoldOblique");
437 }
438 else if (regmatch (font, /^(.*)-Roman$/))
439 {
440 bold_font = concat ($1, "-Bold");
441 italic_font = concat ($1, "-Italic");
442 bold_italic_font = concat ($1, "-BoldItalic");
443 }
444 else
445 {
446 bold_font = concat (font, "-Bold");
447 italic_font = concat (font, "-Oblique");
448 bold_italic_font = concat (font, "-BoldOblique");
449 }
450
451 /* Create regular expressions for nested highlighting. */
452 nested_start_re = regexp (nested_start);
453 nested_end_re_cached = regexp (nested_end);
454
455 /* Define output faces. */
456 calln (concat ("lang_", language));
457
458 /* Define our highlight style. */
459 calln (concat ("style_", style));
460
461 /* Resolve start state. */
462 if (check_startrules ())
463 debug ("startstate from startrules");
464 if (check_namerules ())
465 debug ("startstate from namerules");
466 }
467
468 namerules
469 {
470 /\.(c|h)$/ c;
471 /\.(c++|C|H|cpp|cc|cxx|hpp)$/ cpp;
472 /\.m$/ matlab;
473 /\.(mpl|mp|maple)$/ maple;
474 /\.(scm|scheme)$/ scheme;
475 /\b\.emacs$|\.el$/ elisp;
476 /\.ad(s|b|a)$/ ada;
477 /\.[Ss]$/ asm;
478 /\.st$/ states;
479 /(M|m)akefile.*/ makefile;
480 /\.(MOD|DEF|mi|md)$/ modula_2;
481 /\.tcl$/ tcl;
482 /\.(v|vh)$/ verilog;
483 /\.html?$/ html;
484 /\bChangeLog$/ changelog;
485 /\.(vhd|vhdl)$/ vhdl;
486 /\.(scr|.syn|.synth)$/ synopsys;
487 /\.idl$/ idl;
488 /\.(hs|lhs|gs|lgs)$/ haskell;
489 /\.(pm|pl)$/ perl;
490 /\.(eps|EPS|ps|PS)$/ postscript;
491 /\.py$/ python;
492 /\.pyx$/ pyrex;
493 /\.js$/ javascript;
494 /\.java$/ java;
495 /\.([Pp][Aa][Ss]|[Pp][Pp]|[Pp])$/ pascal;
496 /\.[fF]$/ fortran;
497 /\.f90$/ f90;
498 /\.awk$/ awk;
499 /\.sh$/ sh;
500 /\.vba$/ vba;
501 /\.(cshrc|login|logout|history|csh)$/ csh;
502 /\.tcshrc$/ tcsh;
503 /\.(zshenv|zprofile|zshrc|zlogin|zlogout)$/ zsh;
504 /\.(bash_profile|bashrc|inputrc)$/ bash;
505 /\.m4$/ m4;
506 /\.il$/ skill;
507 /\.wrl$/ vrml;
508 /\b(rfc.*\.txt|draft-.*\.txt)$/ rfc;
509 /\.inf$/i inf;
510 /\.tex$/ tex;
511 /\.wmlscript$/ wmlscript;
512 /\.wmls$/ wmlscript;
513 /^.*$/ passthrough;
514 }
515
516 startrules
517 {
518 /.\010.\010.\010./ nroff;
519 /-\*- [Cc] -\*-/ c;
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;
532 /^From:/ mail;
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;
540 /^#VRML/ vrml;
541 /^\04?%!/ postscript;
542 }
543
544
545 /*
546 * The global super states.
547 */
548
549 state Highlight
550 {
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.
554
555 /^\0[^{]+{[^}]+}/ {
556 language_print ($0);
557 }
558 */
559
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. */
563 nested_end_re {
564 language_print($0);
565 return;
566 }
567
568 /* Skip output language's special characters. */
569 LANGUAGE_SPECIALS {
570 language_print ($0);
571 }
572 }
573
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;
577
578 state HighlightEntry extends Highlight
579 {
580 BEGIN {
581 if (highlight_entry_nesting++ == 0)
582 header();
583 }
584 END {
585 if (--highlight_entry_nesting == 0)
586 trailer();
587 }
588 }
589
590
591
592 /*
593 * Helper subroutines and states.
594 */
595
596 state match_balanced_block extends Highlight
597 {
598 match_balanced_block_start {
599 language_print ($0);
600 match_balanced_block_count = match_balanced_block_count + 1;
601 }
602
603 match_balanced_block_end {
604 match_balanced_block_count = match_balanced_block_count - 1;
605 if (match_balanced_block_count == 0)
606 return $0;
607
608 language_print ($0);
609 }
610 }
611
612 sub match_balanced_block (starter, ender)
613 {
614 match_balanced_block_count = 1;
615 match_balanced_block_start = starter;
616 match_balanced_block_end = ender;
617 return call (match_balanced_block);
618 }
619
620 state eat_one_line
621 {
622 /.*\n/ {
623 language_print ($0);
624 return;
625 }
626 }
627
628
629 /*
630 Local variables:
631 mode: c
632 End:
633 */