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. */ 78prereq ("1.6.2"); 79 80/* 81 * Constants, fonts, etc. 82 */ 83 84debug = "0"; 85 86/* Boolean values. */ 87true = 1; 88false = 0; 89 90font_spec = "Courier@10"; 91 92/* These components are resolved from <font_spec>. */ 93font = ""; 94ptsize = ""; 95 96/* 97 * Generatel table of contents? This is not supported by all output 98 * languages. 99 */ 100toc = "0"; 101 102/* 103 * The Highlight style. The default style is `emacs' to imitate 104 * Emacs' font lock mode. 105 */ 106style = "emacs"; 107 108/* 109 * Create color outputs? 110 */ 111color = "1"; 112 113/* 114 * Use verbose highlighting rules? 115 */ 116verbose_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 */ 128language = "enscript"; 129 130/* 131 * How many input files we have. 132 */ 133num_input_files = "1"; 134current_input_file = 0; 135 136/* 137 * Document title. 138 */ 139document_title = "Enscript Output"; 140 141/* 142 * Global variables for nested highlighting `nested.st'. 143 */ 144nested_start = "^-+(([ \t]*)([a-zA-Z_0-9]*)([ \t]*))-+$"; 145nested_start_re = 0; 146nested_end = "^-+$"; 147nested_end_re_cached = 0; 148nested_end_re = 0; 149nested_default = "passthrough"; 150 151/* 152 * Color definitions. 153 */ 154 155cindex = 0; 156rgb_values = list (); 157 158sub define_color (name, r, g, b) 159{ 160 rgb_values[cindex] = list (name, r, g, b); 161 cindex = cindex + 1; 162} 163 164sub 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 175sub 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 192define_color ("black", 0, 0, 0); 193define_color ("gray25", 64, 64, 64); 194define_color ("gray50", 127, 127, 127); 195define_color ("gray75", 191, 191, 191); 196define_color ("gray85", 217, 217, 217); 197define_color ("gray90", 229, 229, 229); 198define_color ("gray95", 242, 242, 242); 199define_color ("blue", 0, 0, 255); 200define_color ("cadet blue", 95, 158, 160); 201define_color ("dark goldenrod", 184, 134, 11); 202define_color ("dark olive green", 85, 107, 47); 203define_color ("firebrick", 178, 34, 34); 204define_color ("forest green", 34, 139, 34); 205define_color ("green", 0, 255, 0); 206define_color ("orchid", 218, 112, 214); 207define_color ("purple", 160, 32, 240); 208define_color ("red", 255, 0, 0); 209define_color ("rosy brown", 188, 143, 143); 210 211define_color ("DarkSeaGreen", 143, 188, 143); 212define_color ("DarkSeaGreen1", 193, 255, 193); 213define_color ("DarkSeaGreen2", 180, 238, 180); 214define_color ("DarkSeaGreen3", 155, 205, 155); 215define_color ("DarkSeaGreen4", 105, 139, 105); 216define_color ("Goldenrod", 237, 218, 116); 217define_color ("Aquamarine", 67, 183, 186); 218define_color ("SeaGreen2", 100, 233, 134); 219define_color ("Coral", 247, 101, 65); 220define_color ("DarkSlateGray1", 154, 254, 255); 221define_color ("LightGrey", 211, 211, 211); 222 223 224/* 225 * General helpers. 226 */ 227 228sub debug (msg) 229{ 230 if (debug_level) 231 print ("DEBUG: ", msg, "\n"); 232} 233 234sub is_prefix (prefix, string) 235{ 236 return strncmp (prefix, string, length (prefix)) == 0; 237} 238 239sub 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 250sub 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>. */ 269sub 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 297sub bold (on) 298{ 299 if (on) 300 face_on (face_bold); 301 else 302 face_off (face_bold); 303} 304 305sub italic (on) 306{ 307 if (on) 308 face_on (face_italic); 309 else 310 face_off (face_italic); 311} 312 313sub bold_italic (on) 314{ 315 if (on) 316 face_on (face_bold_italic); 317 else 318 face_off (face_bold_italic); 319} 320 321sub comment_face (on) 322{ 323 if (on) 324 face_on (face_comment); 325 else 326 face_off (face_comment); 327} 328 329sub function_name_face (on) 330{ 331 if (on) 332 face_on (face_function_name); 333 else 334 face_off (face_function_name); 335} 336 337sub variable_name_face (on) 338{ 339 if (on) 340 face_on (face_variable_name); 341 else 342 face_off (face_variable_name); 343} 344 345sub keyword_face (on) 346{ 347 if (on) 348 face_on (face_keyword); 349 else 350 face_off (face_keyword); 351} 352 353sub reference_face (on) 354{ 355 if (on) 356 face_on (face_reference); 357 else 358 face_off (face_reference); 359} 360 361sub string_face (on) 362{ 363 if (on) 364 face_on (face_string); 365 else 366 face_off (face_string); 367} 368 369sub builtin_face (on) 370{ 371 if (on) 372 face_on (face_builtin); 373 else 374 face_off (face_builtin); 375} 376 377sub type_face (on) 378{ 379 if (on) 380 face_on (face_type); 381 else 382 face_off (face_type); 383} 384 385sub 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 398start 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 468namerules 469{ 470 /\.(c|h)$/ c; 471 /\.(c++|C|H|cpp|cc|cxx)$/ 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 516startrules 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 549state 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. */ 576highlight_entry_nesting = 0; 577 578state 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 596state 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 612sub 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 620state eat_one_line 621{ 622 /.*\n/ { 623 language_print ($0); 624 return; 625 } 626} 627 628 629/* 630Local variables: 631mode: c 632End: 633*/ 634