1 rizwank 1.1 /*
2 * States definitions file for GNU Enscript.
3 * Copyright (c) 1997-2001 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 rizwank 1.1 * 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, 59 Temple Place - Suite 330,
27 * Boston, MA 02111-1307, USA.
28 */
29
30 /*
31 * $Id: enscript.st,v 1.17 2001/04/10 17:12:46 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 rizwank 1.1 * * ...
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 rizwank 1.1 * - 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
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 rizwank 1.1
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 rizwank 1.1 * 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 rizwank 1.1 * 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 rizwank 1.1 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 rizwank 1.1
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 rizwank 1.1 }
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 rizwank 1.1 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 rizwank 1.1 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 rizwank 1.1 {
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 rizwank 1.1
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
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 rizwank 1.1 * 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 rizwank 1.1 {
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 rizwank 1.1 }
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 rizwank 1.1 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 rizwank 1.1 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
396 /*
397 * Initializations.
398 */
399
400 rizwank 1.1 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 rizwank 1.1 /* 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 rizwank 1.1 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 rizwank 1.1 /* 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 rizwank 1.1 /\.(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 /\.js$/ javascript;
495 /\.java$/ java;
496 /\.([Pp][Aa][Ss]|[Pp][Pp]|[Pp])$/ pascal;
497 /\.[fF]$/ fortran;
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 rizwank 1.1 /\.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 rizwank 1.1 /-\*- [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 rizwank 1.1 */
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 rizwank 1.1 /* 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 rizwank 1.1
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 rizwank 1.1 }
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 rizwank 1.1 mode: c
632 End:
633 */
|