File: enscript-html

package info (click to toggle)
noweb 2.13-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 3,540 kB
  • sloc: sh: 2,580; ansic: 1,829; makefile: 903; perl: 781; lisp: 757; awk: 174; csh: 3
file content (150 lines) | stat: -rwxr-xr-x 3,932 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#!/usr/bin/perl -w

# Noweb filter which calls enscript to prettyprint according to
# @language directives (see guesslang and inheritlang filters to have
# those directive automatically generated).

# Copyright (c) 2003 by Yann Dirson <ydirson@altern.org>

# Distribute under the terms of the GNU General Public Licence,
# version 2.

# FIXME:
# - @use in code chunks is not supported for all @language's yet
#   => find a way to plug external data ?
# - when a perl chunk ends with comment lines, we get enscript
#   trailers in woven output

use strict;
use File::Temp qw(tempfile);

my $mangledID='__NOWEB__mangled__use__';
sub mangle_use {
  my ($usedchunk, $lang) = @_;

  if (grep { $lang eq $_ } ('perl', 'c', 'c++') ) {
    return "$mangledID (\"$usedchunk\")\n";
  } else {
    die "Don't know how to mangle \@use for language $lang";
  }
}

sub demangle_use {
  my ($mangled, $lang) = @_;

  if (grep { $lang eq $_ } ('perl', 'c', 'c++') ) {
    $mangled =~ m|^(.*)$mangledID \((?:<B>)?(?:<FONT.*>)?\&quot;(.*)\&quot;(?:</FONT>)?(?:</B>)?\)(.*)$|;
    return ($1, $2, $3);
  } else {
    die "Don't know how to demangle \@use for language $lang";
  }
}


# Find out languages supported by the available version of enscript

my @knownlangs;
open (LANGS, 'enscript --help-highlight | grep ^Name: |') or
  die "enscript --help-highlight failed: $!";
while (<LANGS>) {
  chomp;
  @_ = split /\s+/;
  push @knownlangs, $_[1];
}


while (<STDIN>) {
  if (m/^\@begin code/) {

    # we found a code chunk, now bufferize its contents until
    # @language, or until @end if no @language is there.  Store in
    # $event which of these 2 events just occured

    my (@buffer, $event);
    push @buffer, $_;
    while (defined($_ = <STDIN>) and
	     not ((m/^\@end code / and $event = [1]) or
		  (m/^\@language (.*)/ and $event = [2, $1])) ) {
      push @buffer, $_;
    }
    die "$0 hit EOF before seing \@end code or \@language" unless defined $event;

    if ($event->[0] == 1) {
      # we got @end first, everything read goes through unmodified

      push @buffer, $_;		# the @end line
      # no declared language: dump @buffer
      foreach (@buffer) { print; }
    } else {
      # we found @language...

      # check that language is supported
      my $lang = $event->[1];
      if (grep { $_ eq $lang } @knownlangs ) {
	# language is supported

	# (implicitely) drop @language from output, read remainder
	my $chunknum;
	while (defined($_ = <STDIN>) and not (m/^\@end code (.*)/ and $chunknum = $1)) {
	  push @buffer, $_;
	}
	# we don't want "@end code" in the buffer, delay its output
        my $endcode = $_;

        # transform the code chunk to be accepted by enscript, and
        # store it into an auto-unlinked temporary file

	my $tmp = new File::Temp();
	# demangle @-directives into something suitable for enscript
	foreach (@buffer) {
	  if (m/^\@text (.*)/ ) {
	    print $tmp $1;
	  } elsif (m/^\@nl$/) {
	    print $tmp "\n";
	  } elsif (m/^\@use (.*)/) {
	    print $tmp mangle_use ($1, $lang);
	  } else {
	    print;
	  }
	}

	# pipe, remangle
	open PRETTY, "enscript --highlight=$lang --language=html " .
	  join (' ', @ARGV) .
	  " --silent -o - $tmp |" or
	    die "enscript failed: $!";
	{
	  my $started = undef;
	  while (<PRETTY>) {
	    if (m|^<PRE>$|) {
	      $started = 1;
	      next;
	    }
	    if (m|^</PRE>$|) {
	      last;
	    }

	    if (m/$mangledID/) {
	      my ($prefix, $use, $suffix) = demangle_use ($_, $lang);
	      print "\@literal $prefix\n" if $prefix ne '';
	      print "\@use $use\n" ; 
	      print "\@literal $suffix\n" if $suffix ne '';
	      next;
	    }
	    print "\@literal $_\@nl\n" if defined $started;
	  }
	}
	close PRETTY;
	close $tmp;		# auto-unlinked

	print $endcode;
      } else {
        push @buffer, $_;	# the @language line
	# unsupported language: dump @buffer
	foreach (@buffer) { print; }
      }
    }
  } else {
    print $_;
  }
}