home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1519 < prev    next >
Encoding:
Internet Message Format  |  1990-12-28  |  13.2 KB

  1. From: aas@boeygen.nr.no (Gisle Aas)
  2. Newsgroups: alt.sources
  3. Subject: Yet another text to postscript filter
  4. Message-ID: <AAS.90Jun28144434@boeygen.nr.no>
  5. Date: 28 Jun 90 12:44:34 GMT
  6.  
  7. The unusual thing about this one, is that it is written in perl.
  8. Comments and bug fixes are welcome.
  9.  
  10. # This is a shell archive.
  11. # Remove everything above and including the cut line.
  12. # Then run the rest of the file through /bin/sh (not csh).
  13. #--cut here-----cut here-----cut here-----cut here-----cut here-----cut here--#
  14. #!/bin/sh
  15. # shar: Shell Archiver
  16. # Execute the following text with /bin/sh to create the file(s):
  17. #    a2ps.1
  18. #    a2ps
  19. # This archive created: Thu Jun 28 14:40:28 1990
  20. # Wrapped by: Gisle Aas (Norwegain Computing Centre, Oslo, Norway)
  21. sed 's/^X//' << \SHAR_EOF > a2ps.1
  22. X.TH A2PS 1 "June 1990"
  23. X.SH NAME
  24. Xa2ps \- convert ISO Latin1 text to PostScript
  25. X.SH SYNOPSIS
  26. X.B a2ps
  27. X[
  28. X.B \-nlrth23
  29. X] [
  30. X.B \-b
  31. X.I "text"
  32. X] [
  33. X.B \-s
  34. X.I size
  35. X] [
  36. X.I filename
  37. X\&.\|.\|.
  38. X]
  39. X.SH DESCRIPTION
  40. XThe
  41. X.B a2ps
  42. Xprogram is used to print simple
  43. Xtext files (e.g. program listings) on a PostScript\*R device. 
  44. XThe name
  45. X.B a2ps
  46. Xused to stand for ascii-to-postscript, but the program
  47. Xis designed to handle the whole
  48. XISO Latin1 character set.
  49. XEfforts have been made to ensure that 
  50. X.B a2ps
  51. Xproduces good looking and effective PostScript code.
  52. XThe output conforms to Adobe's
  53. Xdocument structuring conventions (version 2.1). The 
  54. X.B a2ps 
  55. Xprogram
  56. Xassumes that the page format on the output device is A4.
  57. XThe meaning of form feed (^L) characters in the input stream is understood.
  58. X.PP
  59. XThe
  60. X.B a2ps
  61. Xprogram is written in
  62. X.I perl.
  63. XSo if there is something you don't like about how
  64. X.B a2ps
  65. Xworks, you can easily fix it youself.
  66. X.SH OPTIONS
  67. X.TP 5
  68. X.B \-n
  69. Xuse the norwegian version of ISO 646 (7-bit ascii) to encode the text.
  70. XNorwegian letters will replace the left/right braces, left/right
  71. Xbrackets, backslash and horisontal bar characters.
  72. X.TP 5
  73. X.B \-l
  74. Xproduces linenumbers on each 5'th line. Nice for program listings.
  75. X.TP 5
  76. X.B \-t
  77. Xtruncate lines that are to long. The default is to wrap
  78. Xlong lines so that they continue on the next line on the printed output.
  79. X.TP 5
  80. X.B \-r
  81. Xrotate the output page 90 degrees. This is also called
  82. X.I landscape
  83. Xmode.
  84. X.TP 5
  85. X.B \-h
  86. Xsuppress generation of page headers.
  87. X.TP 5
  88. X.B \-2
  89. Xuse two column format.
  90. X.TP 5
  91. X.B \-3
  92. Xuse three column format (not supported).
  93. X.TP 5
  94. X.BI \-b " text"
  95. Xthe 
  96. X.I text
  97. Xparameter replaces the default text in the header of the pages.
  98. XThe default text is the filename of the file to be printed. There is no
  99. Xdefault if the filtered text comes from standard input.
  100. X.TP 5
  101. X.BI \-s " size"
  102. Xspecifies a new font size for the body text. The default is 10 point.
  103. X.SH EXAMPLES
  104. XTo print files on a PostScript printer:
  105. X.nf
  106. X    a2ps -l *.[ch] | lpr
  107. X.fi
  108. X.PP
  109. XTo find out how many pages a2ps will produce for a given file:
  110. X.nf
  111. X    a2ps file.txt | tail -1
  112. X.fi
  113. X.PP
  114. XOur printer stacks the pages the wrong way. To fix it try:
  115. X.nf
  116. X    cat file.txt | a2ps -b "some text" | psrev | lpr
  117. X.fi
  118. X.SH SEE ALSO
  119. X.BR perl (1),
  120. X.BR enscript (1),
  121. X.BR psrev (1),
  122. X.BR ISO8859 (7),
  123. X.BR PostScript (7)
  124. X.SH BUGS
  125. XIf some of the specified
  126. X.I files
  127. Xdoes not exist,
  128. X.B a2ps
  129. Xget confused about what to put in the header.
  130. XThere is no easy way to change the margins or the fonts that
  131. X.B a2ps
  132. Xinsist on using.
  133. XThe
  134. X.B a2ps
  135. Xfilter ought to understand the meaning of the backspace character. It is used
  136. Xto produce boldfaced and underlined text by programs like 
  137. X.BR nroff (1).
  138. XPerhaps
  139. X.B a2ps
  140. Xshould be made to reject input which looks like garbage (binary files).
  141. X.SH AUTHOR
  142. XGisle Aas, Norwegain Computing Centre (NR), Oslo, Norway.
  143. X<Gisle.Aas@nr.no>
  144. SHAR_EOF
  145. if test 2839 -ne "`wc -c a2ps.1`"
  146. then
  147. echo shar: error transmitting a2ps.1 '(should have been 2839 characters)'
  148. fi
  149. sed 's/^X//' << \SHAR_EOF > a2ps
  150. X#!/local/boeygen/bin/perl
  151. X# "a2ps" text to PostScript filter written in perl by Gisle Aas, NCC 1990
  152. X# version 1.1
  153. X#
  154. X# Efforts have been made to produce nice and effective PostScript. The
  155. X# output conforms to Adobe's document structuring conventions version-2.1.
  156. X# 
  157. X# Whish list:  (this may become a feature some time)
  158. X#     Line number on the last line (in addition to each 5th line)
  159. X#     Marking (by some funny char) truncation and wrapping of lines
  160. X#     Faster execution (rewrite the hole thing in C?)
  161. X#     Parsing of backspace to produce bold and underlined fonts.
  162. X
  163. X# Some configuration constants, meassured in points (1/72 inch)
  164. Xsub a4_top        { 841; }
  165. Xsub a4_right_edge { 595; }
  166. X
  167. X# The next few entries are from the AFM file for Adobe's font Courier
  168. Xsub cour_char_width     { 600; }   # The width of each char in 1000x1000 square
  169. X#sub underline_position  { -82; }   # Where underline goes relative to baseline
  170. X#sub underline_thickness {  40; }   # and it's thickness
  171. X
  172. X# Parse command line for options and flags
  173. Xdo 'getopts.pl';
  174. Xunless (&Getopts('nrth12s:b:l')) {
  175. X   print STDERR "Usage: a2ps [-<options>] [file]...\n";
  176. X   print STDERR "Options: -n       norwegian 7bit-ascii encoding\n";
  177. X   print STDERR "         -l       print with line numbers\n";
  178. X   print STDERR "         -r       rotated, landscape orientation\n";
  179. X   print STDERR "         -t       truncate long lines, " . 
  180. X                                  "default is to wrap lines\n";
  181. X   print STDERR "         -b\"text\" replaces the text in the page header\n";
  182. X   print STDERR "         -h       no page headers\n";
  183. X   print STDERR "         -2       set text in two columns\n";
  184. X   print STDERR "         -s<size> select new text fontsize, default 10pt\n";
  185. X   exit(1);
  186. X}
  187. X
  188. X# Set default values, some based on command line options
  189. X$left_margin  = 80;
  190. X$right_margin = 40;
  191. X$tb_margin    = 45;
  192. X$font         = "Courier";
  193. X$font_size    = 10;        $font_size = $opt_s if ($opt_s > 0);
  194. X$header_font  = "Helvetica-Bold";
  195. X$header_font_size = 12;
  196. X$line_number_font = "Helvetica";
  197. X$line_number_size = 5;
  198. X
  199. X$line_height = $font_size * 1.08;
  200. X$no_columns = defined($opt_2) ? 2 : 1;
  201. X$col_separation = 30;
  202. X$sep_bars = '';                 # false
  203. X$landscape = defined($opt_r);
  204. X$header_height = 30;
  205. X$show_header = !defined($opt_h);
  206. X$wrap_lines = !defined($opt_t);
  207. X$truncate_lines = !$wrap_lines; # don't change this
  208. X$norsk_ascii = defined($opt_n);
  209. X
  210. X# Some initial values
  211. X$opt_b = &ps_string($opt_b) if ($opt_b);
  212. X$form_feed = ''; # false;
  213. X$page_no  = 0;
  214. X$line_no = 0;
  215. Xif ($landscape) {
  216. X    $top = &a4_right_edge;
  217. X    $right_edge = &a4_top;
  218. X    $left_margin = $right_margin; # this is a dirty one
  219. X} else {
  220. X    $top = &a4_top;
  221. X    $right_edge = &a4_right_edge;
  222. X}
  223. X$home_pos = $top - $tb_margin - ($show_header ? $header_height : 0);
  224. X$col_width = ($right_edge - $left_margin - $right_margin
  225. X              - ($no_columns - 1) * $col_separation) / $no_columns;
  226. X$char_width = &cour_char_width * $font_size / 1000;
  227. X$chars_per_line = int ($col_width / $char_width + 1);
  228. X
  229. X&prolog;
  230. X
  231. X$cur_pos = -1;
  232. X$cur_col = 100;
  233. X$file_name = &ps_string($ARGV[0]);
  234. XLINES:
  235. Xwhile (<>) {
  236. X   chop;
  237. X   $line_no++;
  238. X   if (ord == 014) {        # form feed
  239. X       s/.//;    # chop off first char
  240. X       $cur_pos = -1; 
  241. X       next LINES if (length == 0);
  242. X   }
  243. X   while (s/\t/' ' x (8 - length($`) % 8)/e) {}   # expand tabs
  244. X   do {
  245. X      if ($cur_pos < $tb_margin) {
  246. X          $cur_pos = $home_pos;
  247. X          if ($cur_col < $no_columns) {
  248. X              $cur_col++;
  249. X          } else {
  250. X              $cur_col = 1;
  251. X              &new_page;
  252. X          }
  253. X      }
  254. X      $text = substr($_,0,$chars_per_line);
  255. X      $_ = $truncate_lines ? '' : substr($_,$chars_per_line,10000);
  256. X      if ($text =~ s/^ +//) {            # suppress leading blanks
  257. X          $indent = $char_width * length($&);
  258. X      } else {
  259. X          $indent = 0;
  260. X      }
  261. X      # Make suitable as a postscript string
  262. X      $text =~ s/[\\\(\)]/\\$&/g;
  263. X      $text =~ s/[\000-\037\177-\377]/sprintf("\\%03o",ord($&))/ge;
  264. X      # Calculate position
  265. X      $x = $left_margin + ($cur_col - 1) * ($col_width + $col_separation);
  266. X      $cur_pos -= $line_height;
  267. X      printf "(%s)%.1f %.1f S\n", $text, $x + $indent, $cur_pos 
  268. X             if (length($text));
  269. X      if ($opt_l && ($line_no % 5) == 0) { # print line numbers
  270. X          print "F2 SF ";
  271. X          printf "($line_no) dup stringwidth pop neg %.1f add %.1f M show ",
  272. X                  $x - 10, $cur_pos;
  273. X          print "F1 SF\n";
  274. X      }
  275. X      if (eof) {
  276. X         $file_name = &ps_string($ARGV[0]);
  277. X         $cur_pos = -1;  # will force a new column next time
  278. X         $cur_col = 100; # will force a new page next time
  279. X         $line_no = 0;
  280. X      }
  281. X   } while (length($_));
  282. X}
  283. X&end_page;
  284. Xprint "%%Trailer\n";
  285. Xprint "%%Pages: $page_no\n";
  286. X
  287. X#--end of main-------------------------------------------------------
  288. X
  289. X
  290. Xsub prolog {
  291. X   local($user) = getlogin || "(unknown)";
  292. X   local($sec,$min,$hour,$mday,$mon,$year) = localtime;
  293. X   $date = sprintf("(%d. %s %d) (%2d:%02d)",$mday,
  294. X                    ('Januar','Februar','Mars','April','Mai','Juni',
  295. X                     'Juli','August','Oktober','November','Desember')[$mon],
  296. X                     $year+1900, $hour,$min);
  297. X#   open(LOG,">>/home/boeygen/aas/.a2ps-log");
  298. X#   print LOG "$user, $date\n";
  299. X#   close(LOG);
  300. X
  301. X   print "%!PS-Adobe-2.0\n";
  302. X   print "%%Title: @ARGV\n" if (@ARGV);
  303. X   print <<"EOT";
  304. X%%Creator: a2ps, Text to PostScript filter in perl, (C) 1990 Gisle Aas, NCC
  305. X%%CreationDate: $date
  306. X%%For: $user
  307. X%%Pages: (atend)
  308. X%%DocumentFonts: $font
  309. XEOT
  310. X   print "%%+ $line_number_font\n" if ($opt_l);
  311. X   print "%%+ $header_font\n" if ($show_header);
  312. X   print <<"EOT";
  313. X%%EndComments
  314. X/S{moveto show}bind def
  315. X/M{moveto}bind def
  316. X/L{lineto}bind def
  317. X/SF{setfont}bind def
  318. X%%BeginProcSet: reencode 1.0 0
  319. X/RE { %def
  320. X   findfont begin
  321. X   currentdict dup length dict begin
  322. X        { %forall
  323. X             1 index/FID ne {def} {pop pop} ifelse
  324. X         } forall
  325. X         /FontName exch def dup length 0 ne { %if
  326. X            /Encoding Encoding 256 array copy def
  327. X            0 exch { %forall
  328. X                dup type /nametype eq { %ifelse
  329. X                    Encoding 2 index 2 index put
  330. X                    pop 1 add
  331. X                 }{%else
  332. X                    exch pop
  333. X                 } ifelse
  334. X          } forall
  335. X       } if pop
  336. X    currentdict dup end end
  337. X    /FontName get exch definefont pop
  338. X} bind def
  339. X%%EndProcSet: reencode 1.0 0
  340. X%%EndProlog
  341. X%%BeginSetup
  342. X0.15 setlinewidth
  343. XEOT
  344. X   if ($norsk_ascii) {
  345. X      print "[8#133 /AE/Oslash/Aring 8#173 /ae/oslash/aring] dup\n";
  346. X      print "/Body-Font/$font RE\n";
  347. X      print "/Header-Font/$header_font RE\n" if ($show_header);
  348. X   } else {
  349. X      print "ISOLatin1Encoding /Body-Font/$font RE\n";
  350. X      print "ISOLatin1Encoding /Header-Font/$header_font RE\n"
  351. X         if ($show_header);
  352. X   }
  353. X   print "/F1/Body-Font findfont $font_size scalefont def\n";
  354. X   print "/F2/$line_number_font findfont $line_number_size scalefont def\n"
  355. X        if ($opt_l);
  356. X   print "/F3/Header-Font findfont $header_font_size scalefont def\n"
  357. X        if ($show_header);
  358. X   print "F1 SF\n";
  359. X   if ($landscape) {
  360. X      printf "90 rotate 0 -%d translate %% landscape mode\n",&a4_right_edge;
  361. X   }
  362. X   print "%%EndSetup\n";
  363. X}
  364. X
  365. X
  366. X
  367. Xsub new_page {
  368. X   &end_page unless ($page_no == 0);
  369. X   $page_no++;
  370. X   print "%%Page: $page_no $page_no\n";
  371. X   print "/my_save save def\n";
  372. X   if ($show_header) {
  373. X      # First print a box
  374. X      local($llx,$lly,$urx,$ury) = ($left_margin - 10,
  375. X            $top - $tb_margin - $header_font_size * 1.3,
  376. X            $right_edge - $right_margin + 10, $top - $tb_margin);
  377. X      printf "%.1f %.1f M %.1f %.1f L %.1f %.1f L ",
  378. X             $llx,$lly, $urx,$lly, $urx, $ury;
  379. X      printf "%.1f %.1f L closepath \n",$llx,$ury;
  380. X      print  "gsave .95 setgray fill grestore stroke\n";
  381. X      # Then the banner or the filename
  382. X      print "F3 SF\n";
  383. X      if ($opt_b) {
  384. X         printf "($opt_b)%.1f %.1f S\n",
  385. X                $left_margin,$top - $tb_margin - $header_font_size;
  386. X      }
  387. X      elsif ($file_name) {
  388. X         printf "(%s)%.1f %.1f S\n", $file_name, 
  389. X                      $left_margin,
  390. X                      $top - $tb_margin - $header_font_size;
  391. X      }
  392. X      # Then print page number
  393. X      printf "%.1f %.1f M($page_no)dup stringwidth pop neg 0 rmoveto show\n",
  394. X                 $right_edge - $right_margin, 
  395. X                 $top - $tb_margin - $header_font_size;
  396. X      print  "F1 SF\n";
  397. X   }
  398. X   if ($sep_bars) {
  399. X      print "% Some postscript code to draw horizontal bars.\n";
  400. X      print "% Not implemented yet\n";
  401. X   }
  402. X}
  403. X
  404. Xsub end_page {
  405. X   unless ($page_no == 0) {
  406. X      print "showpage\n";
  407. X      print "my_save restore\n";
  408. X   }
  409. X}
  410. X
  411. Xsub ps_string
  412. X{
  413. X   # Prepare text for printing
  414. X   local($_) = shift;
  415. X   s/[\\\(\)]/\\$&/g;
  416. X   s/[\001-\037\177-\377]/sprintf("\\%03o",ord($&))/ge;
  417. X   $_;    # return string
  418. X}
  419. X
  420. X
  421. X
  422. X
  423. X# This is interpreted by the GnuEmacs text editor.
  424. X# Local Variables:
  425. X# mode: C
  426. X# eval: (message "Text to PostScript filter written in perl by Gisle Aas")
  427. X# End:
  428. SHAR_EOF
  429. if test 8974 -ne "`wc -c a2ps`"
  430. then
  431. echo shar: error transmitting a2ps '(should have been 8974 characters)'
  432. fi
  433. #    End of shell archive
  434. exit 0
  435. --
  436. Gisle Aas               |  snail: Boks 114 Blindern, N-0314 Oslo, Norway
  437. Norsk Regnesentral      |  X.400: G=Gisle;S=Aas;O=nr;P=uninett;C=no
  438. voice: +47-2-453561     |  inet:  Gisle.Aas@nr.no
  439.