home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 3 / CDPDIII.bin / pd / programming / gnusmalltalk / fileout-ps.st < prev    next >
Text File  |  1992-02-16  |  8KB  |  327 lines

  1. "======================================================================
  2. |
  3. |   File out method definitions as PostScript.
  4. |
  5.  ======================================================================"
  6.  
  7. "======================================================================
  8. |
  9. | Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc.
  10. | Written by Steve Byrne.
  11. |
  12. | This file is part of GNU Smalltalk.
  13. |
  14. | GNU Smalltalk is free software; you can redistribute it and/or modify it
  15. | under the terms of the GNU General Public License as published by the Free
  16. | Software Foundation; either version 1, or (at your option) any later version.
  17. | GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT
  18. | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  19. | FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
  20. | details.
  21. | You should have received a copy of the GNU General Public License along with
  22. | GNU Smalltalk; see the file COPYING.  If not, write to the Free Software
  23. | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  
  24. |
  25.  ======================================================================"
  26.  
  27. "
  28. |     Change Log
  29. | ============================================================================
  30. | Author       Date       Change 
  31. | sbb         16 Feb 92      created Feb 92.
  32. |
  33. "
  34.  
  35. !String methodsFor: 'useful functionality'!
  36.  
  37. linesDo: aBlock
  38.     "Send 'aBlock' a substring of the receiver for each newline delimited
  39.      line in the receiver"
  40.     | start substr |
  41.     start _ 1.
  42.     1 to: self size do:
  43.     [ :i | (self at: i) == Character nl
  44.            ifTrue: [ substr _ self copyFrom: start to: i - 1.
  45.                  aBlock value: substr.
  46.                  start _ i + 1. ]
  47.           ].
  48.     "start - 1 <= self size   this includes the blank line at the end"
  49.     start <= self size
  50.     ifTrue: [ aBlock value: (self copyFrom: start to: self size) ]
  51. !
  52.  
  53. tabExpand
  54.     "Replace tabs in self with appropriate number of spaces"
  55.     | hpos dest |
  56.     hpos _ 1.
  57.     dest _ String new: (self size * 8).
  58.     self do:
  59.     [ :ch | ch == Character tab
  60.             ifTrue: [ [ dest at: hpos put: Character space.
  61.                 hpos _ hpos + 1.
  62.                 (hpos \\ 8) ~= 1 ] whileTrue.
  63.                   ]
  64.             ifFalse: [ (ch == $( ) | (ch == $) )
  65.                    ifTrue: [ dest at: hpos put: $\.
  66.                          hpos _ hpos + 1 ].
  67.                    dest at: hpos put: ch.
  68.                    hpos _ hpos + 1 ]
  69.             ].
  70.     ^dest copyFrom: 1 to: hpos - 1
  71. ! !
  72.  
  73. "Execute to test:
  74. ----------------------------------------------------------------------
  75. 'foo
  76. bar
  77. baz
  78. ' linesDo: [ :aLine | aLine printNl ]!
  79. ----------------------------------------------------------------------
  80. "
  81.  
  82.  
  83.  
  84. !ClassDescription methodsFor: 'filing'!
  85.  
  86. filePostscriptOutOn: aFileStream
  87.     | categories now |
  88.     categories _ Set new.
  89.     methodDictionary isNil ifTrue: [ ^self ].
  90.     methodDictionary do:
  91.     [ :method | categories add: (method methodCategory) ].
  92.  
  93.     self emitPostscriptHeader: aFileStream.
  94.  
  95.     aFileStream nextPutAll: 'normal'; nl;
  96.     nextPutAll: '(''Filed out from ';
  97.     nextPutAll: Version;
  98.     nextPutAll: ' on '.
  99.     now _ Date dateAndTimeNow.
  100.     aFileStream print: (now at: 1);
  101.     nextPutAll:  '  ';
  102.     print: (now at: 2);
  103.     nextPutAll: ' GMT''!)'; 
  104.     nextPutAll: ' show newline newline'; nl; nl.
  105.  
  106.     categories asSortedCollection do:
  107.         [ :category | self emitPostscriptCategory: category toStream: aFileStream ].
  108.  
  109.     aFileStream nextPutAll: 'finish'; nl.
  110. ! !
  111.  
  112.  
  113. !ClassDescription methodsFor: 'private'!
  114.  
  115. emitPostscriptCategory: category toStream: aFileStream
  116.     "I write Postscript for legal Smalltalk load syntax definitions of all of my methods
  117.      are in the 'category' category to the aFileStream"
  118.  
  119.     aFileStream nextPutAll: 'italic'; nl;
  120.     nextPutAll: '(!';
  121.     print: self;
  122.     nextPutAll: ' methodsFor: ''';
  123.     nextPutAll: category;
  124.     nextPutAll: '''!)';
  125.     nextPutAll: ' show '; nl.
  126.     methodDictionary notNil
  127.       ifTrue: [ methodDictionary do:
  128.               [ :method | (method methodCategory) = category
  129.                       ifTrue: [ self emitPostscriptMethod: method
  130.                          toStream: aFileStream ]
  131.                       ] ].
  132.     aFileStream nextPutAll: '(!) show newline
  133. newline newline
  134. '
  135. !
  136.  
  137. emitPostscriptMethod: method toStream: aFileStream
  138.     self splitOffSelector: method methodSourceString
  139.      to: [ :sel :body | aFileStream nextPutAll: 'newline newline'; nl;
  140.                 nextPutAll: 'bold'; nl.
  141.                 self emitLines: sel toStream: aFileStream.
  142.                 aFileStream nextPutAll: 'normal'; nl.
  143.                 self emitLines: body toStream: aFileStream.
  144.                 aFileStream nextPutAll: '(! ) show '; nl.
  145.                 ] 
  146. !
  147.  
  148.  
  149. splitOffSelector: methodString to: aBlock
  150.     | sel body ch split pos |
  151.     ch _ methodString at: 1.    "could skip whitespace"
  152.     ch isAlphaNumeric
  153.     ifTrue: [ split _ self parseUnaryOrKeyword: methodString ]
  154.     ifFalse: [ pos _ self skipToWhite: 1 on: methodString.
  155.            pos _ self skipWhite: pos on: methodString.
  156.            pos _ self skipIdentifier: pos on: methodString.
  157.            split _ self skipPastNewline: pos on: methodString ].
  158.     sel _ methodString copyFrom: 1 to: split - 1.
  159.     body _ methodString copyFrom: split to: methodString size.
  160.     aBlock value: sel value: body
  161. !
  162.  
  163. skipToWhite: start on: string
  164.     | pos |
  165.     pos _ start.
  166.     [ (string at: pos) isSeparator ]
  167.     whileFalse: [ pos _ pos + 1].
  168.     ^pos
  169. !
  170.  
  171. skipWhite: start on: string
  172.     | pos |
  173.     pos _ start.
  174.     [ (string at: pos) isSeparator ]
  175.     whileTrue: [ pos _ pos + 1].
  176.     ^pos
  177. !
  178.  
  179. skipIdentifier: start on: string
  180.     | pos |
  181.     pos _ start.
  182.     [ (string at: pos) isAlphaNumeric ]
  183.     whileTrue: [ pos _ pos + 1].
  184.     ^pos
  185. !    
  186.  
  187. skipPastNewline: start on: string
  188.     | pos ch |
  189.     pos _ start.
  190.     [ ch _ string at: pos.
  191.       (ch isSeparator) and: [ ch ~~ Character nl] ]
  192.     whileTrue: [ pos _ pos + 1].
  193.     ch == Character nl
  194.     ifTrue: [ pos _ pos + 1 ].
  195.     ^pos
  196. !    
  197.  
  198. parseUnaryOrKeyword: string
  199.     | pos ch tempPos |
  200.     pos _ self skipIdentifier: 1 on: string.
  201.     ch _ string at: pos.
  202.     ch ~~ $:
  203.     ifTrue: [ "Got a unary selector"
  204.           pos _ self skipPastNewline: pos on: string.
  205.           ^pos ].
  206.     pos _ 1.
  207.     [ tempPos _ self skipWhite: pos on: string.
  208.       ch _ string at: tempPos.
  209.      "make sure we have a valid keyword identifier to start"
  210.       ch isLetter 
  211.       ifFalse: [ ^self skipPastNewline: pos on: string ].
  212.       tempPos _ self skipIdentifier: tempPos on: string.
  213.       ch _ string at: tempPos.
  214.       ch ~~ $:
  215.       ifTrue: [ ^self skipPastNewline: pos on: string ].
  216.      "parsed a keyword, expect an identifier next"
  217.       tempPos _ self skipWhite: tempPos + 1 on: string.
  218.       ch _ string at: tempPos.
  219.       ch isLetter 
  220.       ifFalse: [ ^self skipPastNewline: pos on: string ].
  221.       pos _ self skipIdentifier: tempPos on: string.
  222.       true ] whileTrue
  223. !
  224.  
  225. emitLines: string toStream: aStream
  226.     string linesDo: [ :line | aStream nextPut: $(;
  227.                   nextPutAll: line tabExpand;
  228.                   nextPutAll: ') show newline'; nl ]
  229. !
  230.  
  231.  
  232. emitPostscriptHeader: aFileStream
  233.     aFileStream nextPutAll: 
  234. '%!
  235.  
  236. %%%
  237. %%% User settable parameters
  238. %%%
  239.  
  240. /fontSize 10 def
  241. /leading 2 def
  242. /indent 0 def
  243.  
  244.  
  245. %%% 
  246. %%% End of user settable parameters
  247. %%%
  248.  
  249. clippath pathbbox 
  250.   /uy exch def
  251.   /ux exch def
  252.   /ly exch def
  253.   /lx exch def
  254.  
  255.  
  256. /lineHeight fontSize leading add def
  257.  
  258. /ystart uy lineHeight sub def
  259. /ypos ystart def
  260.  
  261. /linecounter 0 def
  262. /maxline
  263.     uy ly sub                % height
  264.     lineHeight              % line_height height
  265.     div floor            % max_whole_lines_per_page
  266. def
  267.  
  268. /Helvetica findfont fontSize scalefont /hel exch def
  269. /Helvetica-Bold findfont fontSize scalefont /helb exch def
  270. /Helvetica-Oblique findfont fontSize scalefont /heli exch def
  271.  
  272. /normal {
  273.     hel setfont
  274. } def
  275.  
  276. /bold {
  277.     helb setfont
  278. } def
  279.  
  280. /italic {
  281.     heli setfont
  282. } def
  283.  
  284. /newline { % - => -
  285.     /ypos ypos lineHeight sub def
  286.     /linecounter linecounter 1 add def
  287.     linecounter maxline 1 sub ge
  288.     {
  289.     showpage
  290.         /ypos ystart def
  291.     /linecounter 0 def
  292.     } if
  293.     indent ypos moveto
  294. } def
  295.  
  296. /finish { % - => -
  297.     linecounter 0 gt
  298.     { showpage }
  299.     if
  300. } def 
  301.  
  302. indent ypos moveto
  303.  
  304.  
  305.  
  306. '
  307.  
  308. ! !
  309.  
  310. "Some test code.  Eval the region in comments after you've filed it in."
  311.  
  312. "SymLink filePostscriptOutOn: stdout!"
  313.  
  314. "
  315. | pipe |
  316.     pipe _ FileStream popen: 'lpr' dir: 'w'.
  317.     Association filePostscriptOutOn: pipe.
  318.     pipe close
  319. !
  320. "
  321.  
  322. "
  323. Object filePostscriptOutOn: stdout!
  324. "
  325.