miker@cord.UUCP (Mike Roberson) (07/21/86)
i caught the: \(br\|line-eater\|\(br\l'|0\(rn'\l'|0\(ul'! abstract: how can items be sorted in troff(nroff)? explanation: given the definition of the list-begin, list-item, and list-end macros, how can i generate a sorted list of the first arguments to the list-item macros? e.g., given the following pseudo-troff input: list-begin list-item arg1 list-item arg1 list-item arg1 list-end list-sort \" i.e. produce a sorted list of all arg1s what should list-item and list-sort do? my problem is best stated as a troff example. the following can be run unchanged with troff(nroff): .\" ---------- begin troff source ---------- .de lH \" list header \&\\$1 .. .de lB \" list begin .in +2i .. .de lI \" list item .br .\" the next line causes $1 to be a hanging mark \h'|-1i'\&\\$1\h'|0'\c .. .de lE \" list end .br .in -2i .. .de lS \" output sorted list .\" what goes here? .. .lH "this is the header for the following list" .lB \" list start .lI ".ti" this is some text that i don't care about. this is even more text that doesn't matter. .lI ".in" this is some text that i don't care about. this is even more text that doesn't matter. .lI ".br" this is some text that i don't care about. this is even more text that doesn't matter. .lI ".bp" this is some text that i don't care about. this is even more text that doesn't matter. .lE \" list end this is some text (after the list) that i don't care about. this is even more (after the list) text that doesn't matter. .lS .\" ---------- end of troff source ---------- finally: I can't (read: i don't want to) call a sub-shell. I also can't (read: i really can't) call a pre- processor, unfortunately. any help, pointers to documentation, people etc. would be greatly appreciated. ADVthanksANCE, -- "Stoneware - prehistoric computers" Mike "Trust Me" Roberson UUCP: {ihnp4,cbosgd,akgua}!cord!miker
liam@cs.qmc.ac.uk (William Roberts) (07/24/86)
Summary: Expires: Sender: Followup-To: Distribution: Xpath: ukc eagle In article <320@cord.UUCP> miker@cord.UUCP writes: >abstract: how can items be sorted in troff(nroff)? > >explanation: given the definition of the list-begin, list-item, > and list-end macros, how can i generate a sorted list of > the first arguments to the list-item macros? > > e.g., given the following pseudo-troff input: > >list-begin >list-item arg1 >list-item arg1 >list-item arg1 >list-end >list-sort \" i.e. produce a sorted list of all arg1s > > what should list-item and list-sort do? (You are joking, aren't you?) Ignoring the fact that troff doesn't have string comparisons, just numeric ones, what you need is a way of imitating arrays in troff so you can do quicksort/bubblesort or whatever. The way to imitate arrays is to use dynamically constructed register/string names. To mimic an array Q with 10 elements and access Q[i] where i is a suitable numeric register, do things like .nr \n(Q\ni 7 \" Q[i] := 7 .nr \n(Q\ni \n(Q\n(j \" Q[i] := Q[j] .nr \n(Q2 3 \" Q[2] := 3 or have a string array if you can find some way of comparing the arguments. To get arrays with more than 0 elements, you have to encode the subscript into a single character - help is at hand in the unlikely form of the .af primitive .af i a will give you a 27 element array with index letters 0,a-z and tricky use of .ie conditionals will give you A-Z as well by changing the format to a or A as appropriate. Note that .af doesn't change the way you assign numbers into the register. Control structures - I can't offhand think of a way to do iteration directly (Exercise for the readers?) but recursion is just macro calling and the \$n arguments really are call-by-value local variables! Your only problem will be avoiding macro nesting depth limits, but you have to tackle the sorting of strings first. For the paper in which I first saw these crazy ideas used (to do proper floating keeps, no -ms rubbish here!), look in Software- Practice & Experience sometime in the past 4 years (?) for a paper entitled "* On the Power of Traps and Diversions*" Note the use of pattern matching to compensate for failing memory. When you have written your sort program, you might care to tackle the aesthetically valid idea of re-writing troff in troff...... -- William Roberts ARPA: liam@cs.qmc.ac.uk (gw: cs.ucl.edu) Queen Mary College UUCP: liam@qmc-cs.UUCP LONDON, UK Tel: 01-980 4811 ext 3900
john@basser.oz (John Mackin) (07/28/86)
In article <320@cord.UUCP> miker@cord.UUCP (Mike Roberson) writes: > how can items be sorted in troff(nroff)? This got a friend and I to thinking. Once we worked out a way to compare strings (for other than (in)equality) an insertion sort was easy, but we were dissatisfied with its performance, so we wrote a merge-based sort that is n log n. Both versions follow. The insertion sort took 55 minutes of user-time on our 780 to sort a 300 element list; the merge sort does the same list in 17 minutes (and a 1000 element list in 72 minutes). Bear in mind, people, troff isn't sort! The insertion sort is far simpler and is perfectly adequate (and considerably faster) for small lists (say up to 20 or so elements on a 780). Each sort has the same interface: .LS \" list start .LI "key" "data" \" list item - will be sorted on the key, \" and the data goes with it. they key must \" not contain spaces or backslashes. if \" you want a space in the key, put in a \" control-E at that point. ... .LE \" list end - sort the list and invoke \" .lo "key" "data" \" list output \" for every item, in order. the user can \" redefine lo to get whatever format is \" desired; a basic one is provided. We make no apology for this code; we wrote it to establish that it could be done. It is unfortunate that we did not adopt a more consistent naming convention; adapting this for use with any existing macro package is up to you. If you have spaces in the key, replace them with control-E characters; they will be output as spaces. The only other macro in these sources (it is the same in both) that you are likely to want to call is .sc, the string comparison macro. .sc "string1" "string2" sets the number register R to 1, 0, or -1, depending on whether string1 is lexically less than, equal to, or greater than string2. Extract the following shell archive using sh. Then, BEFORE TRYING TO USE THE MACROS, edit "insert" and "merge" with an editor capable of handling control characters. Globally change the string CTRL-E into a control-E, and the string CTRL-F into a control-F. To test the macros, try "nroff insert demo | sed 10q | cmp - demo.out". (The sed is needed because I stripped the traling newlines from demo.out for posting.) Have fun! John Mackin, Basser Department of Computer Science, University of Sydney, Sydney, Australia john%basser.oz@SEISMO.CSS.GOV {seismo,hplabs,mcvax,ukc,nttlab}!munnari!basser.oz!john The following code is the product of a collaboration between Mark Shand and John Mackin. You can do what you like with it, as long as you don't mail us and ask how it works! # To unbundle, sh this file echo insert 1>&2 sed 's/.//' >insert <<'//GO.SYSIN DD insert' -.ds @CTRL-E "0 " -.ds @! "1 " -.ds @" "2 " -.ds @# "3 " -.ds @$ "4 " -.ds @% "5 " -.ds @& "6 " -.ds @' "7 " -.ds @( "8 " -.ds @) "9 " -.ds @* "10 " -.ds @+ "11 " -.ds @, "12 " -.ds @- "13 " -.ds @. "14 " -.ds @/ "15 " -.ds @0 "16 " -.ds @1 "17 " -.ds @2 "18 " -.ds @3 "19 " -.ds @4 "20 " -.ds @5 "21 " -.ds @6 "22 " -.ds @7 "23 " -.ds @8 "24 " -.ds @9 "25 " -.ds @: "26 " -.ds @; "27 " -.ds @< "28 " -.ds @= "29 " -.ds @> "30 " -.ds @? "31 " -.ds @@ "32 " -.ds @A "33 " -.ds @B "34 " -.ds @C "35 " -.ds @D "36 " -.ds @E "37 " -.ds @F "38 " -.ds @G "39 " -.ds @H "40 " -.ds @I "41 " -.ds @J "42 " -.ds @K "43 " -.ds @L "44 " -.ds @M "45 " -.ds @N "46 " -.ds @O "47 " -.ds @P "48 " -.ds @Q "49 " -.ds @R "50 " -.ds @S "51 " -.ds @T "52 " -.ds @U "53 " -.ds @V "54 " -.ds @W "55 " -.ds @X "56 " -.ds @Y "57 " -.ds @Z "58 " -.ds @[ "59 " -.\" this is a bit buggered ds @\e "60 " -.ds @] "61 " -.ds @^ "62 " -.ds @_ "63 " -.ds @` "64 " -.ds @a "65 " -.ds @b "66 " -.ds @c "67 " -.ds @d "68 " -.ds @e "69 " -.ds @f "70 " -.ds @g "71 " -.ds @h "72 " -.ds @i "73 " -.ds @j "74 " -.ds @k "75 " -.ds @l "76 " -.ds @m "77 " -.ds @n "78 " -.ds @o "79 " -.ds @p "80 " -.ds @q "81 " -.ds @r "82 " -.ds @s "83 " -.ds @t "84 " -.ds @u "85 " -.ds @v "86 " -.ds @w "87 " -.ds @x "88 " -.ds @y "89 " -.ds @z "90 " -.ds @{ "91 " -.ds @| "92 " -.ds @} "93 " -.ds @~ "94 " -.\" -.de sc -.nr S 0 -.if '\\$1\\$2'' .nr R 0 -.if !'\\$1\\$2'' \{\ -.if '\\$1'' .nr R 0-1 -.if !'\\$1'' \{\ -.if '\\$2'' .nr R 1 -.if !'\\$2'' \{\ -.Sc a \\*(@\\$1 -.Sc b \\*(@\\$2 -.if \\*(Ha=\\*(Hb .sc "\\*(Ta" "\\*(Tb" -.if !\\nS \{\ -.ie \\*(Ha>\\*(Hb .nr R 1 -.el .nr R 0-1 -'br\} -'br\} -'br\} -'br\} -.nr S 1 -.. -.de Sc -.ds H\\$1 "\\$2 -.ds T\\$1 "\\$3 -.. -.de lo -\\$1 --> \\$2 -.. -.de li -.if \\n(is=0 \{\ -.sc "\\$1" "\\*(ik" -.if \\nR=1 \{ .nr is 1 -\!.li "\\*(ik" "\\*(it" -'br\} -'br\} -\!.li "\\$1" "\\$2" -.. -.de LS -.rm L -.. -.de LI -.nr is 0 -.di M -.ds ik "\\$1 -.ds it "\\$2 -.L -.di -.rn M L -.if \\n(is=0 \{\ -.da L -\!.li "\\$1" "\\$2" -.di -'br\} -.. -.de LE -.rn li lt -.rn lo li -.nr F \\n(.u -.nf -.tr CTRL-E -.L -.tr -.if \\nF .fi -.rn li lo -.rn lt li -.. //GO.SYSIN DD insert echo merge 1>&2 sed 's/.//' >merge <<'//GO.SYSIN DD merge' -.af ml a -.af sl a -.af rl a -.af tl a -.ds @CTRL-E "0 " -.ds @! "1 " -.ds @" "2 " -.ds @# "3 " -.ds @$ "4 " -.ds @% "5 " -.ds @& "6 " -.ds @' "7 " -.ds @( "8 " -.ds @) "9 " -.ds @* "10 " -.ds @+ "11 " -.ds @, "12 " -.ds @- "13 " -.ds @. "14 " -.ds @/ "15 " -.ds @0 "16 " -.ds @1 "17 " -.ds @2 "18 " -.ds @3 "19 " -.ds @4 "20 " -.ds @5 "21 " -.ds @6 "22 " -.ds @7 "23 " -.ds @8 "24 " -.ds @9 "25 " -.ds @: "26 " -.ds @; "27 " -.ds @< "28 " -.ds @= "29 " -.ds @> "30 " -.ds @? "31 " -.ds @@ "32 " -.ds @A "33 " -.ds @B "34 " -.ds @C "35 " -.ds @D "36 " -.ds @E "37 " -.ds @F "38 " -.ds @G "39 " -.ds @H "40 " -.ds @I "41 " -.ds @J "42 " -.ds @K "43 " -.ds @L "44 " -.ds @M "45 " -.ds @N "46 " -.ds @O "47 " -.ds @P "48 " -.ds @Q "49 " -.ds @R "50 " -.ds @S "51 " -.ds @T "52 " -.ds @U "53 " -.ds @V "54 " -.ds @W "55 " -.ds @X "56 " -.ds @Y "57 " -.ds @Z "58 " -.ds @[ "59 " -.\" this is a bit buggered ds @\e "60 " -.ds @] "61 " -.ds @^ "62 " -.ds @_ "63 " -.ds @` "64 " -.ds @a "65 " -.ds @b "66 " -.ds @c "67 " -.ds @d "68 " -.ds @e "69 " -.ds @f "70 " -.ds @g "71 " -.ds @h "72 " -.ds @i "73 " -.ds @j "74 " -.ds @k "75 " -.ds @l "76 " -.ds @m "77 " -.ds @n "78 " -.ds @o "79 " -.ds @p "80 " -.ds @q "81 " -.ds @r "82 " -.ds @s "83 " -.ds @t "84 " -.ds @u "85 " -.ds @v "86 " -.ds @w "87 " -.ds @x "88 " -.ds @y "89 " -.ds @z "90 " -.ds @{ "91 " -.ds @| "92 " -.ds @} "93 " -.ds @~ "94 " -.ds @CTRL-F "95 " -.\" -.de sc -.nr S 0 -.if '\\$1\\$2'' .nr R 0 -.if !'\\$1\\$2'' \{\ -.if '\\$1'' .nr R 0-1 -.if !'\\$1'' \{\ -.if '\\$2'' .nr R 1 -.if !'\\$2'' \{\ -.Sc a \\*(@\\$1 -.Sc b \\*(@\\$2 -.if \\*(Ha=\\*(Hb .sc "\\*(Ta" "\\*(Tb" -.if !\\nS \{\ -.ie \\*(Ha>\\*(Hb .nr R 1 -.el .nr R 0-1 -'br\} -'br\} -'br\} -'br\} -.nr S 1 -.. -.de Sc -.ds H\\$1 "\\$2 -.ds T\\$1 "\\$3 -.. -.de lo -\\$1 --> \\$2 -.. -.de li -.ds ik "<none> -.lr "\\$1" -.if !'\\$1'CTRL-F' \!.l0 "\\$1" "\\$2" -.\"if !'\\$1'CTRL-F' .tm li: "\\$1" into \\n(.z -.. -.\" lr ensures that %0 contains something (which it does by calling lS, -.\" the logarithmic split macro); then it extracts the keyword -.\" out of %0. if the keyword precedes $1 then it outputs the entry, and -.\" recurs. -.de lr -.if \\n(%0=0 .lS -.rn l% l0 -.%0 -.rn l0 l% -.sc "\\$1" "\\*(ik" -.if \\nR=1 \{\ -\!.l0 "\\*(ik" "\\*(it" -.\"tm lr: "\\*(ik" into \\n(.z -.nr %0 0 -.lr "\\$1" -'br\} -.. -.de l% -.ds ik "\\$1 -.ds it "\\$2 -.. -.de lS -.nr sl 0 -.fs -.rn re l0 -.nr rl 0 -.nr rc 0 -.nr op 0 -.di %0 -.%\\n(sl -.di -.rn l0 re -.rm %\\n(sl -.nr %\\n(sl 0 -.. -.de re -\!.l0 "\\$1" "\\$2" -.nr rc +1 -.if \\n(rc>=\\n(op \{\ -.di -.nr %\\n(rl 1 -.nr rl +1 -.di %\\n(rl -.ie \\n(op=0 .nr op 1 -.el .nr op \\n(op*2 -.nr rc 0 -'br\} -.. -.de fs -.nr sl +1 -.if \\n(%\\n(sl=0 .fs -.. -.de LS -.nr #a 0 -.nr #b 0 -.nr #c 0 -.nr #d 0 -.nr #e 0 -.nr #f 0 -.nr #g 0 -.nr #h 0 -.nr #i 0 -.nr #j 0 -.nr #k 0 -.nr #l 0 -.nr #m 0 -.nr #n 0 -.nr #o 0 -.nr #p 0 -.nr #q 0 -.nr #r 0 -.nr #s 0 -.nr #t 0 -.nr #u 0 -.nr #v 0 -.nr #w 0 -.nr #x 0 -.nr #y 0 -.nr #z 0 -.rm #a -.rm #b -.rm #c -.rm #d -.rm #e -.rm #f -.rm #g -.rm #h -.rm #i -.rm #j -.rm #k -.rm #l -.rm #m -.rm #n -.rm #o -.rm #p -.rm #q -.rm #r -.rm #s -.rm #t -.rm #u -.rm #v -.rm #w -.rm #x -.rm #y -.rm #z -.. -.de LI -.di #0 -\!.l0 "\\$1" "\\$2" -.di -.nr ml 1 -.MG -.. -.de LE -.nr ml 1 -.rm #0 -.nr tl 27 -.Ft -.nr tl +1 -.FM -.rn lo l0 -.nr F \\n(.u -.nf -.tr CTRL-E -.#0 -.tr -.if \\nF .fi -.rn l0 lo -.. -.\" this macro has one parameter: a single letter giving the name of the -.\" diversion to merge with #0 producing #1, which is then moved to #0. -.de Mg -.nr %0 0 -.nr %a 0 -.nr %b 0 -.nr %c 0 -.nr %d 0 -.nr %e 0 -.nr %f 0 -.nr %g 0 -.nr %h 0 -.nr %i 0 -.nr %j 0 -.nr %k 0 -.nr %l 0 -.nr %m 0 -.nr %n 0 -.nr %o 0 -.nr %p 0 -.nr %q 0 -.nr %r 0 -.nr %s 0 -.nr %t 0 -.nr %u 0 -.nr %v 0 -.nr %w 0 -.nr %x 0 -.nr %y 0 -.nr %z 0 -.rm %a -.rm %b -.rm %c -.rm %d -.rm %e -.rm %f -.rm %g -.rm %h -.rm %i -.rm %j -.rm %k -.rm %l -.rm %m -.rm %n -.rm %o -.rm %p -.rm %q -.rm %r -.rm %s -.rm %t -.rm %u -.rm %v -.rm %w -.rm %x -.rm %y -.rm %z -.da #0 -\!.l0 "CTRL-FCTRL-F" "foobaz" -.da -.da #\\$1 -\!.li "CTRL-F" "foobaz" -.da -.#% -.di #1 -.#\\$1 -.di -.rn #1 #0 -.. -.de MG -.nr M \\n(#\\n(ml -.if !\\nM \{\ -. RN \\n(ml -. nr #\\n(ml 1 -'br\} -.if \\nM \{\ -. Mg \\n(ml -. nr #\\n(ml 0 -. nr ml +1 -. MG -'br\} -.. -.de FM -.if \\n(#\\n(ml .Mg \\n(ml -.nr ml +1 -.if !'\\n(ml'\\n(tl' .FM -.. -.de RN -.rn lR l0 -.di #\\$1 -.#0 -.di -.rn l0 lR -.. -.de lR -\!.li "\\$1" "\\$2" -.. -.de #% -.nr lC 0 -.rn lC l0 -.#0 -.rn l0 lC -.nr sl 0 -.nr ol 0 -.nr op 0 -.rn ol l0 -.di %% -.#0 -.di -.rm %% -.rn l0 ol -.. -.de lC -.nr lC +1 -.. -.de ol -.if \\n(ol=\\n(op \{\ -.OL -.di -.di %\\n(sl -.nr %\\n(sl 1 -'br\} -\!.l0 "\\$1" "\\$2" -.nr ol +1 -.. -.de OL -.nr sl +1 -.nr ol 0 -.ie \\n(op=0 .nr op 1 -.el .nr op \\n(op*2 -.nr Lc \\n(lC%2 -.nr lC \\n(lC/2 -.if \\n(Lc=0&\\n(lC>0 .OL -.. -.de Ft -.nr tl -1 -.if \\n(#\\n(tl=0 .Ft -.. //GO.SYSIN DD merge # To unbundle, sh this file echo demo 1>&2 sed 's/.//' >demo <<'//GO.SYSIN DD demo' -.LS -.LI root "Deus ex Machina" -.LI daemon "System Daemon" -.LI bin "System Owner" -.LI sys "System Source" -.LI s "System Source" -.LI backup "Backup Spooler" -.LI man "Unix Manual" -.LI adm "System Administration" -.LI usr "User Administration" -.LI pascal "Pascal Source" -.LE //GO.SYSIN DD demo echo demo.out 1>&2 sed 's/.//' >demo.out <<'//GO.SYSIN DD demo.out' -adm --> System Administration -backup --> Backup Spooler -bin --> System Owner -daemon --> System Daemon -man --> Unix Manual -pascal --> Pascal Source -root --> Deus ex Machina -s --> System Source -sys --> System Source -usr --> User Administration //GO.SYSIN DD demo.out exit 0
roland@moncskermit.oz (Roland Yap) (07/29/86)
In article <719@basser.oz>, john@basser.oz (John Mackin) writes: > In article <320@cord.UUCP> miker@cord.UUCP (Mike Roberson) writes: > > > how can items be sorted in troff(nroff)? > > ... > > The insertion sort took 55 minutes of user-time on our 780 to sort > a 300 element list; the merge sort does the same list in 17 minutes > (and a 1000 element list in 72 minutes). Bear in mind, people, troff > isn't sort! The insertion sort is far simpler and is perfectly adequate > (and considerably faster) for small lists (say up to 20 or so elements > on a 780). > My feeling that this job would be much better done by a preprocessor to [nt]roff. While one can write amazing (and convoluted) macros to do almost anything, it is not really suitable for algorithms with interation, arrays etc. Anyway as evidenced above it is rather slow! It is probably quite easy to write a quick and dirty awk filter as a preprocessor which may optionally call sort to do the dirty work. Any volunteers? Roland. ----------------------------------------------------------------------------- Roland Yap ACSNET,CSNET:roland@moncskermit.oz Dept. of Computer Science ARPA:roland%moncskermit.oz@seismo.arpa Monash University UUCP: ..!seismo!munnari!moncskermit.oz!roland Clayton ...!{decvax,pesnta,vax135}!mulga!moncskermit.oz!roland Australia 3168 moncsbruce can also be substituted for moncskermit
rcd@nbires.UUCP (Dick Dunn) (07/30/86)
> >abstract: how can items be sorted in troff(nroff)? > > > >explanation: given the definition of the list-begin, list-item, > > and list-end macros, how can i generate a sorted list of > > the first arguments to the list-item macros? > > (You are joking, aren't you?) The original posting MIGHT have been a joke, but I don't think so. It's a good question. Generating indices is very hard to do with troff, since you can't feed a piece of text out through a pipe to a program and catch the result. (At least, I can't find a way to do it.) You can try to make multiple passes somehow, but you end up with a messy makefile for your document that's peculiar to the document structure. If you try to piece the document together from files troff'ed separately, it's a mess to get the page numbering right and entering the index/indices in the TOC is even worse. So--if you're not making a humongous index, it would be worth trying to do it with troff. > Ignoring the fact that troff doesn't have string comparisons,... But OUCH! That, as far as I can see, is the crux of the problem. Once you get the comparison, you've obviously got the power you need; the rest is just a matter of finding the best way to do it. > ...what you need is a way of imitating arrays > in troff so you can do quicksort/bubblesort or whatever. Arrays aren't really necessary. You could keep the text in a diversion and use something as simple as an insertion sort: List-start initializes the diversion (probably with a dummy entry) and sets up macros to be used to enter the text. Each list-item shuffles text from one diversion to a second, inserting its argument at the appropriate point. The key here is that the diversion contains macro calls for each item entered so far. The macro that is called compares its argument (the already-entered string) with the new candidate. If the new candidate sorts ahead, the macro tosses it into the diversion being created (and might reset some macro definitions to speed up the rest of the copy). In any case, it then tosses its argument into the diversion (appropriately protected and as a macro call). The diversion needs to have a tail entry to force insertion at the end of the list. List-end redefines the macro used in the diversion to be something that outputs text appropriately and cleans up the mess. The insertion sort is, of course, quadratic in the number of items--and the unit of work is pretty large. But anything you could come up with at this level would be expensive for a list of any substantial size (say, more than a couple dozen items). At least it doesn't stop working when you run out of number registers; the limit on diversions is not too bad. And anyway, it's all just an entertaining exercise unless somebody knows how to do the string comparison... -- Dick Dunn {hao,ucbvax,allegra}!nbires!rcd (303)444-5710 x3086 ...Never attribute to malice what can be adequately explained by stupidity.
henry@utzoo.UUCP (Henry Spencer) (07/31/86)
> ... When you have written your sort program, you might > care to tackle the aesthetically valid idea of re-writing troff > in troff...... This isn't quite the same thing, but may be amusing. I actually wrote (in awk) a "text preprocessor" for troff at one point. It did the same sort of thing for ordinary text that eqn does for equations: emit it as detailed instructions for troff, checking to see whether a line was full or not, doing line breaks, etc. Worked all right. Not useful, but fun. -- EDEC: Stupidly non-standard brain-damaged incompatible Henry Spencer @ U of Toronto Zoology proprietary protocol used. {allegra,ihnp4,decvax,pyramid}!utzoo!henry
liam@cs.qmc.ac.uk (William Roberts) (08/04/86)
In article <7005@utzoo.UUCP> henry@utzoo.UUCP writes: >I actually wrote >(in awk) a "text preprocessor" for troff at one point. It did the same >sort of thing for ordinary text that eqn does for equations: emit it as >detailed instructions for troff, checking to see whether a line was full >or not, doing line breaks, etc. Worked all right. Not useful, but fun. In a recent paper about his version of Knuth's WEB system, adapted for use with C and troff, Harold Thimbleby observes that "The code which did the formatting for a draft printer was about the same size as the code which prepared the same file to be formatted by troff. Telling troff what to do is as hard as actually doing it." He also mentioned having once written a troff program to produce Pascal7s triangle - at least the formatting of the result was easier than in Pascal! -- William Roberts ARPA: liam@cs.qmc.ac.uk (gw: cs.ucl.edu) Queen Mary College UUCP: liam@qmc-cs.UUCP LONDON, UK Tel: 01-980 4811 ext 3900