Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

Re^3: [OT] Code that writes code that writes code: Perl to Lisp to Postscript

by almut (Canon)
on Apr 29, 2008 at 07:33 UTC ( #683424=note: print w/replies, xml ) Need Help??

in reply to Re^2: Code that writes code that writes code: Perl to Lisp to Postscript
in thread Code that writes code that writes code: Perl to Lisp to Postscript

If you really want to do good justification by hand, you do need metrics.

Yes... All I wanted to point out was that all the same font metrics info is readily available on the PS side, so it's no big issue to center or otherwise justify short strings.

My initial understanding was that you maybe wanted to position individual chess pieces/glyphs across the board, or something like that... But upon closer inspection it seems you actually want to do block justification of a whole paragraph of figurine notation (similar to what's shown on the Alpine Fonts sample page). In that case - and as you're outputting individual lines to be justified separately on the PS side - you're of course right in that you need to know the font metrics to pre-compute the proper line breaks in your program.

An alternative approach would be (in theory - not trying to talk you into doing it) to pass the entire paragraph as a single string to the PS code to let it handle the line wrapping all by itself. In which case you wouldn't need to know the font metrics in your program.

For illustration purposes I digged out a sample PostScript block justification routine (see below) which I had written a couple of years ago. It computes the line wrapping depending on the font used, and adjusts the inter-word spacings to block justify the lines. Optionally, it can also slightly condense or stretch the distances between the glyphs (intra-word) to compensate for big gaps between words which might otherwise result. (As some people don't like the appearance produced by the latter approach, you can fine-tune it or disable it altogether — see the respective note in the code.) Otherwise, it uses a simple one-pass algorithm...  (I'm explicitly mentioning the latter, as you seem to be doing this at a level of sophistication that I'm not sure if my code is of any interest to you at all... Anyhow, FWIW, maybe someone else will find some use for it some day.)

The sample code uses standard text with standard fonts, but there's no reason that it couldn't equally work with figurine notation fonts...

And no, I haven't yet written the PS code that implements the more advanced algorithm (whole-paragraph optimised line breaks) that D. Knuth uses in TeX (though this might be a little fun project for some rainy weekend...;)

BTW, I'm so rusty writing Postscript, ...

Same here... Kind of a pity that I don't really find much use for it at work any longer. Actually, PostScript was - as Perl (!) - one of those few languages which was "love at first sight" with me (the only other one in this category being Lisp). Powerful, flexible, and fun to play around with. Unfortunately, these days people mostly want PDF (without having to go via Distiller or Ghostscript), which is not quite as much fun, as it lacks PostScript's programming language features...


%!PS /nextline { y linedist sub /y exch def % (page wrap handling could go here...) } bind def /block_justify { % expected args: x, y, string, width of block, line distance % e.g.: 20 100 (...) 400 15 block_justify 30 dict begin % configurable params % (set those values to zero if you want to adjust % nothing but inter-word spacings) /maxcondense 0.1 def % max condense per glyph /maxstretch 0.3 def % max stretch per glyph % args /linedist exch def /blockwidth exch def dup length /txtlen exch def /txt exch def /y exch def /x exch def /j 0 def /_i 0 def /_w 0 def /_len 0 def /nspaces 0 def 0 1 txtlen 1 sub { % for each char/index of strin +g /i exch def txt i get 32 eq { % word boundary? txt j i j sub getinterval % substring to evaluate dup length /len exch def % length of substring stringwidth pop /w exch def % width of substring w blockwidth ge { % would exceed box border? /dleft blockwidth _w sub def % distance to border from left + side /dright w blockwidth sub def % distance to border from righ +t side /maxcondense_tot maxcondense len mul def /maxstretch_tot maxstretch _len mul def dright maxcondense_tot le { /aw dright len div neg def % neg value to apply to 'ashow +' /cw 0 def txt j i j sub getinterval /j i 1 add def } { dleft maxstretch_tot le { /aw dleft _len div def % pos value to apply to 'ashow +' /cw 0 def } { /aw maxstretch def nspaces 1 gt { /cw dleft maxstretch_tot sub nspaces 1 sub div def % value to apply to 'widthshow +' } { /cw 0 def } ifelse } ifelse txt j _i j sub getinterval /j _i 1 add def } ifelse x y moveto cw 0 32 aw 0 6 -1 roll awidthshow nextline /_i j def /_w 0 def /nspaces 0 def } { % doesn't yet exceed... /_w w def /_i i def /_len len def } ifelse /nspaces nspaces 1 add def } if } for txtlen j sub 0 gt { % remainder / last line -- left-justified x y moveto txt j txtlen j sub getinterval show nextline } if end } bind def % ----- /text (Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed d +o \ eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad + \ minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliqui +p \ ex ea commodo consequat. Duis aute irure dolor in reprehenderit in \ voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur + \ sint occaecat cupidatat non proident, sunt in culpa qui officia \ deserunt mollit anim id est laborum. ) def /Helvetica findfont 15 scalefont setfont 50 700 text 500 20 block_justify /Helvetica-BoldOblique findfont 12 scalefont setfont 50 550 text 450 17 block_justify /Times-Roman findfont 15 scalefont setfont 50 400 text 450 18 block_justify /Times-Italic findfont 15 scalefont setfont 50 250 text 400 18 block_justify showpage

(View with gs -sDEVICE=x11alpha — (device "x11alpha" for nice anti-aliased display) )

Replies are listed 'Best First'.
Re^4: [OT] Code that writes code that writes code: Perl to Lisp to Postscript
by hsmyers (Canon) on Apr 29, 2008 at 16:42 UTC

    I bow to the excellence of you code!! Well I would if my back didn't hurt. This is such an advance over my effort that I will with your permission and with suitable credit steal this code for my Lisp package. Theft is the highest praise for someone else's work ;) This comes at a particularly opportune time— I've decided to forgo the use of the figurine fonts in favor of the ordinary fonts; i.e. LinaresFigurine ⇒ Linares. I'm doing this because this lets me mix normal text and figurine in one font. Your block_justify is just the thing to fold into the mix with this change. I'll update this node with the new result.

    Liking Postscript as you do, have you ever tried Forth? My only complaint about Postscript is that Warnock should have copied all of the Forth vocabulary not just some. Cool thing is that, that is easily fixable using the language itself


    "Never try to teach a pig to wastes your time and it annoys the pig."
      Theft is the highest praise for someone else's work ;)

      True words :)  Thanks! — feel free to use it in whatever way you like.

      BTW, under these new circumstances I should mention there is a little peculiarity. That is, you need a trailing space at the end of the text (noticed the space in "laborum. ) def"? - that's there on purpose). The space itself will not be visible, but without it, the last line might not wrap properly in some cases. (I've always wanted to fix this bug, but then again, making sure there is that space has always been easier... ;)

      As to Forth, yes I've tried it and generally liked it. Though, due to largely missing library functionality in the environment I used at the time, it has always been somewhat tedious to get any real world problem solved with it... That definitely is a plus of PS, its powerful builtin typesetting and graphics facilities.

Re^4: [OT] Code that writes code that writes code: Perl to Lisp to Postscript
by ambrus (Abbot) on Apr 29, 2008 at 08:16 UTC

    I always wondered whether we could translate TeX and Metafont to postscript, and embed these and all required source files to a large postscript so it does all typesetting work on the viewer's computer.

      I think it should be doable (though performance might still be an issue for huge documents) — whether there is a real need for it is another question ;)

      Anyhow, I'd probably try to leave out Metafont to begin with (IMHO, PostScript has rather superb font handling capabilities on its own). Also, I guess I wouldn't attempt a direct 1:1 reimplementation in PS (except for maybe the TeX parser), but rather a loose mapping of good ideas and features onto the specific functionality that PS has to offer, but with the net effect of generating comparable output. But that's all mere theory at the moment (and probably not even a good one :)

      (Actually, I did play with the idea on and off... But then, with life being so short and so many other things being more rewarding in the short run, I never got started (yeah, lame excuse, I know). Actually, I haven't even gotten as far as doing a thorough search on whether other people might already be working on it.  And now, I don't really have a personal need for it any longer — which might keep me focused beyond the fun playing around phase...)

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://683424]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (2)
As of 2021-01-27 03:38 GMT
Find Nodes?
    Voting Booth?