Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.postscript > #2158 > unrolled thread

anybody mind if I just ... already long have been

Started byluser- -droog <mijoryx@yahoo.com>
First post2015-01-28 21:40 -0800
Last post2015-02-18 00:02 -0800
Articles 18 — 6 participants

Back to article view | Back to comp.lang.postscript


Contents

  anybody mind if I just ... already long have been luser- -droog <mijoryx@yahoo.com> - 2015-01-28 21:40 -0800
    Re: anybody mind if I just ... already long have been jdaw1 <jdawiseman@gmail.com> - 2015-01-29 01:34 -0800
      Re: anybody mind if I just ... already long have been Mark Carroll <mtbc@bcs.org> - 2015-01-29 17:44 +0000
    Re: anybody mind if I just ... already long have been luser- -droog <mijoryx@yahoo.com> - 2015-01-29 22:38 -0800
      Re: anybody mind if I just ... already long have been luser- -droog <mijoryx@yahoo.com> - 2015-01-30 00:35 -0800
        Re: anybody mind if I just ... already long have been rodd@panix.com (Rod Dorman) - 2015-01-30 20:45 +0000
          Re: anybody mind if I just ... already long have been luser- -droog <mijoryx@yahoo.com> - 2015-01-31 00:18 -0800
            Re: anybody mind if I just ... already long have been Yves Cloutier <yves.cloutier@gmail.com> - 2015-02-01 18:42 -0800
              Re: anybody mind if I just ... already long have been luser- -droog <mijoryx@yahoo.com> - 2015-02-01 23:04 -0800
                Re: anybody mind if I just ... already long have been luser- -droog <mijoryx@yahoo.com> - 2015-02-03 03:27 -0800
              Re: anybody mind if I just ... already long have been jdaw1 <jdawiseman@gmail.com> - 2015-02-04 01:48 -0800
                Re: anybody mind if I just ... already long have been luser- -droog <mijoryx@yahoo.com> - 2015-02-07 02:11 -0800
                  Re: anybody mind if I just ... already long have been jdaw1 <jdawiseman@gmail.com> - 2015-02-07 02:39 -0800
                    Re: anybody mind if I just ... already long have been luser- -droog <mijoryx@yahoo.com> - 2015-02-07 15:15 -0800
                      Re: anybody mind if I just ... already long have been tlvp <mPiOsUcB.EtLlLvEp@att.net> - 2015-02-08 00:21 -0500
                        Re: anybody mind if I just ... already long have been luser- -droog <mijoryx@yahoo.com> - 2015-02-08 02:45 -0800
                          Re: anybody mind if I just ... already long have been tlvp <mPiOsUcB.EtLlLvEp@att.net> - 2015-02-09 22:46 -0500
                            ibis        (was: Re: anybody mind if I just ... already long have been luser- -droog <mijoryx@yahoo.com> - 2015-02-18 00:02 -0800

#2158 — anybody mind if I just ... already long have been

Fromluser- -droog <mijoryx@yahoo.com>
Date2015-01-28 21:40 -0800
Subjectanybody mind if I just ... already long have been
Message-ID<2f49979b-b7c8-4f01-b599-4db8668b9e90@googlegroups.com>
abusing this usenet forum s some kind of personal
postscript blog?? 

Assuming 'no',

I finally cleaned some this old program I call 'ibis'
last posted in 2011 in a bugridden form.
https://github.com/luser-dr00g/ibis.ps/blob/master/ibis.ps

So the first bit of drama was fixing the bug(s).
'Convenient!' I thought to myself, 'that I now have
a debugger to use on it.'
https://github.com/luser-dr00g/debug.ps/blob/master/db5.ps
Then I had to debugger the debug debugging the buggy ibis.
(...5xfast).

So back to 'ibis'. First it does some little convenience 
routine which I had conveniently commented % Utiliy
"Utility"?? Thanks, past self. See that? That's a stupid.
Wise up! ya baloney.

Next, it encapsulates the "device" info, and the "text-setting"
api, and this crazy function called 'find' which is mostly a
wrapper for `search`.

% find takes 3 procedures a string and search-string
% and executes on_a and on_b upon the returned substrings if found
% or the not procedure if not found
/find {               % {not} {on_b} {on_a} (aXb) (X)  find  -
    search {          % n b a (b) (X) (a) 
        4 1 roll pop  % n b (a) a (b) 
        4 1 roll      % n (b) b (a) a
        5 -1 roll pop % (b) b (a) a
        /exec cvx 5 3 roll % (a) a exec (b) b
        /exec cvx 6 array astore cvx exec
        %exec exec
    }{                   % n b a (a_b)
        4 1 roll pop pop % (a_b) n
        exec
    } ifelse
} def 
%{(n)= =}{(b)= =}{(a)= =} (pretextpost) (text) find
%(stack:)= pstack
%quit

The three lines at the top are new, based on my current
understanding. My past self had left the stack comments
(bravo, self) and the testing comments (again, good job,
past self). But had utterly failed to simply say what
the dang thing does.

Then it does some really crazy stuff to try to generalize
the behavior of built-in commands.

I should backtrack and preface this whole discussion by
saying that, in a way, this is the program that I truly
wanted to write when I first set out to learn the 
postscript language initially. And the main reason I 
got an "incomplete" in Physics 101. I tried to do all
my reports in pure postscript. I was also the editor
of the Honors College newsmagazine at the time, but
was wise enough not to convert the whole thing to 
postscript, because I knew I was not mature enough as
a programmer to accomplish anything in a timely manner.
Sloppy as it was, the Pagemaker template was already
created. But over the course of my editorship, I tweaked
every dang thing from front to back, eventually designing
new cover art for each issue. (with some hacked versions
of Photoshop and stuff supplied by a Malaysian kid in the
dorms)

So 'ibis' is very dear to my heart. Even though I abandoned
it for, um, 4 years. It's also very new because I just
picked it up again, having almost completely forgotten
about it.

The built-in commands like 'italics' and 'bold', attempt
to encapsulate an on/off behavior that can be applied
automatically to keep the state in sync with the expectations
of the markup language. I'm not sure how well I've 
succeeded so far. It saves the currentfont as its "undo" 
action, so effects can be undone in a stack-wise manner,
but not out-of-order as I'd really like it to do.

This is more-or-less the basic execution framework to which
I'd like to add things like line-fitting and justifying
and columns and tables and kerning and stuff.

Questions/Comments/Chit-chat?

$ cat ibis.ps
%!
%(debug.ps/db5.ps)run %currentfile cvx debug

%/show { dup print (\n) print show } bind def

% mark k1 v1 .. kN vN  dicttomark  dict(N)
/dicttomark { counttomark dup dict begin 2 idiv { def } repeat pop currentdict end } def

/-= { 1 index load exch sub store } def

% Composite Index  inc/dec  -
% (n.b. userdict is a composite object)
/inc { 2 copy get 1 add put } def
/dec { 2 copy get 1 sub put } def

% Stack type is an array where element 0 contains the index of the top of the stack
% n  stack  array{n+1}:[0]=0
/stack { 1 add array dup 0 0 put } def
/top { dup 0 get get } def % S  top  a
/spop { dup top exch 0 dec } def % S  spop  a  (S{n}->S'(n-1})
/spush { % S a  spush  -  (S{n}->S'{n+1})
    1 index 0 inc
    1 index 0 get exch put
} def

% output device
/dev mark
    /size [ clippath pathbbox ]
    /bounds null
dicttomark def
/savebounds { dev /bounds [ x y X Y ] put } def
/restorebounds { dev /bounds get aload pop setbounds } def
/setbounds { % x y X Y  setbounds  -
    /Y exch def /X exch def /y exch def /x exch def
} def
/setmargin { % pts  setmargin  -
    dev /size get aload pop
    4 index sub 4 1 roll 4 index sub 4 1 roll
    4 index add 4 1 roll 4 index add 4 1 roll
    setbounds pop savebounds
} def

/nextpage { showpage restorebounds } def

% text setting
/text mark
    /eol { /Y lead -=
        y Y lt { x Y moveto }
               { nextpage } ifelse }
    /heol { eol }
    /blank { eol }
    /settext { show }
dicttomark def

% processing
% find takes 3 procedures a string and search-string
% and executes on_a and on_b upon the returned substrings if found
% or the not procedure if not found
/find {               % {not} {on_b} {on_a} (aXb) (X)  find  -
    search {          % n b a (b) (X) (a)
        4 1 roll pop  % n b (a) a (b)
        4 1 roll      % n (b) b (a) a
        5 -1 roll pop % (b) b (a) a
        /exec cvx 5 3 roll % (a) a exec (b) b
        /exec cvx 6 array astore cvx exec
        %exec exec
    }{                   % n b a (a_b)
        4 1 roll pop pop % (a_b) n
        exec
    } ifelse
} def
%{(n)= =}{(b)= =}{(a)= =} (pretextpost) (text) find
%(stack:)= pstack
%quit

%shift a 1-char string off of a larger string
/first { % (abc)  first  (bc) (a)
    dup 1 1 index length 1 sub getinterval exch
    0 1 getinterval
} def

% delimiter pairs
/pairs mark
    ([)(]) (<)(>) (\()(\)) ({)(}) (`)(') (:)(;)
dicttomark def

% ([)  rhs  (])
% (q)  rhs  (q)
/rhs { pairs exch 2 copy known { get }{ exch pop } ifelse } def

/nest 10 stack def
% {on_a} (])  deferal  {[{on_a} (])] nest exch spush}
% create a save-it-for-later proc
% for the not-found clause of find
/deferal {
    2 array astore
    [ exch /nest cvx /exch cvx /spush cvx ] cvx
} def

% {on_a} ([a]b)  delim  (b)
/delim {
    exch /settext cvx exch /exec cvx 3 array astore cvx exch
    first rhs       % on_a (a]b) (])
    3 copy exch pop % on_a (a]b) (]) on_a (]) 
    deferal         % on_a (a]b) (]) not    %not-clause
    {}              % on_a (a]b) (]) not on_b  %on_b clause: leave string on stack
    5 2 roll        % not on_b on_a (a]b) (])
    %(delim)= pstack()=
    find
} def

% ([arg]rem) /name  short  (rem)
/short {
    alt exch get % s d
    dup /ini get exec % s d ?
    exch /fin get % s ? {}
    [ 3 1 roll /exec cvx ] cvx exch % undo s
    (short)= pstack()=
    delim
} def

% str  execute  -
/execute { token { exec process }{ BAD_COMMAND } ifelse } def

% the "at" sign indicates the start of an embedded command
/sigil <40> def

% scan string for embedded @commands
% and call settext for other text.
/process { % str  process  -
    %(process:)= pstack()=
    dup length 0 eq { pop blank }{
        {settext} {execute} {settext} 4 3 roll
        sigil find
    } ifelse
} def

% call process on each line
%
/src null def
/buf 200 string def
/exitflag false def
/ibis { % file|string  ibis  -
    dup type /stringtype eq { (r) file } if
    dup type /filetype ne { NOT_A_FILE } if
    /src exch def

    pstack()=
    {
        src buf readline {process}{process exit}ifelse
        heol
        exitflag { exit } if
    } loop

    showpage
} def

% @@ define the at-sign as a command to print itself
sigil { sigil settext } def


%alterations
/alt 20 dict def

% name dict  newalter  -
%
% dict should contain 2 procs
% -  ini  ?
% ?  fin  -
% where init returns an object that should be
% passed to final
/newalter {
    %install in alt dict
    2 copy alt 3 1 roll put
    %create short-form procedure
    pop [ 1 index /short cvx ] cvx def
    %create long-form
} def

%/i mark /ini {currentfont /Palatino-Italic 10 selectfont} /fin {setfont} dicttomark newalter

%/name /fontname fontsize  fontproc  - 
/fontproc {
    /currentfont cvx 3 1 roll /selectfont cvx 4 array astore cvx
    mark exch /ini exch /fin {setfont} dicttomark newalter
} def

/r /Palatino-Roman  10 fontproc
/b /Palatino-Bold   10 fontproc
/i /Palatino-Italic 10 fontproc

/default {
    text begin
    72 setmargin
    %/Palatino-Roman 10 selectfont
    alt /r get /ini get exec pop
    /lead 12 def
    %eol
} def

/bye {pstack()= /exitflag true def} def

%/i load == quit
%stepon
%traceon

default
%currentfile /ibis load debug
currentfile ibis
Text is passed to the output.
Only ragged-right, explicit linebreaks for now.

There are various ways of executing a command to change
a section of text. All commands are introduced by the @@  character,
known internally as the "sigil".

The simple command @@ i for italics, can use the short form 
with various sets of delimiters.

    @@ i[italics] @i[italics]
    @@ i(italics) @i(italics)
    @@ i<italics> @i<italics>
    @@ i{italics} @i{italics}
    @@ i `italics' @i `italics'
    @@ i :italics; @i :italics;

These last two require an extra space after the command name since
the backquote and colon are not postscript delimiters.

Incidentally, since the command name is scanned with 'token' and
executed with 'exec', it can even be a postscript procedure.
@{/oldfont currentfont def}
    @@ {/Courier 11 selectfont}text in Courier
    @{/Courier 11 selectfont}text in Courier
@{oldfont setfont}
Only "short-form" commands take a delimited argument. 
The @@ {arbitrary ps code} commands are not "short-form", 
and do not take an argument but apply directly to the current state.

Now with @b[bold].


@bye
(stack:)= pstack(---)= currentfile flushfile


[toc] | [next] | [standalone]


#2159

Fromjdaw1 <jdawiseman@gmail.com>
Date2015-01-29 01:34 -0800
Message-ID<fa2fab02-41dd-41eb-9839-9990c1dae0f5@googlegroups.com>
In reply to#2158
> some kind of personal postscript blog?? 

No objection. 

[toc] | [prev] | [next] | [standalone]


#2160

FromMark Carroll <mtbc@bcs.org>
Date2015-01-29 17:44 +0000
Message-ID<87lhkl32i1.fsf@ixod.org>
In reply to#2159
jdaw1 <jdawiseman@gmail.com> writes:

>> some kind of personal postscript blog?? 
>
> No objection. 

Indeed. You at least post relevant on-topic stuff!

-- Mark

[toc] | [prev] | [next] | [standalone]


#2161

Fromluser- -droog <mijoryx@yahoo.com>
Date2015-01-29 22:38 -0800
Message-ID<e13fb5a0-bece-4719-a8fd-b626d8e77537@googlegroups.com>
In reply to#2158
On Wednesday, January 28, 2015 at 11:40:34 PM UTC-6, luser- -droog wrote:
> https://github.com/luser-dr00g/ibis.ps/blob/master/ibis.ps
> https://github.com/luser-dr00g/debug.ps/blob/master/db5.ps
[snip]> 
> default
> %currentfile /ibis load debug
> currentfile ibis
> Text is passed to the output.
> Only ragged-right, explicit linebreaks for now.
> 
> There are various ways of executing a command to change
> a section of text. All commands are introduced by the @@  character,
> known internally as the "sigil".
> 
> The simple command @@ i for italics, can use the short form 
> with various sets of delimiters.
> 
>     @@ i[italics] @i[italics]
>     @@ i(italics) @i(italics)
>     @@ i<italics> @i<italics>
>     @@ i{italics} @i{italics}
>     @@ i `italics' @i `italics'
>     @@ i :italics; @i :italics;
> 
> These last two require an extra space after the command name since
> the backquote and colon are not postscript delimiters.
> 
> Incidentally, since the command name is scanned with 'token' and
> executed with 'exec', it can even be a postscript procedure.
> @{/oldfont currentfont def}
>     @@ {/Courier 11 selectfont}text in Courier
>     @{/Courier 11 selectfont}text in Courier
> @{oldfont setfont}
> Only "short-form" commands take a delimited argument. 
> The @@ {arbitrary ps code} commands are not "short-form", 
> and do not take an argument but apply directly to the current state.
> 
> Now with @b[bold].
> 
> 
> @bye
> (stack:)= pstack(---)= currentfile flushfile

The "long form", the existence of which might be deducible from the 
above looks like 

   @enter[i] ... @leave[i] 

and these should allow arbitrary interleaving like 

   @enter[i] it @enter[b] it-bold @leave[i] bold @leave[b]

So, it needs a very different view of fonts, I think.
I needs to deal with a family of faces as a unit with
roman, bold, italic, and bold-italic selected by 
flags (booleans). 

With an array of fonts

   /font-fam [ -roman- -italic- -bold- -bold+italic- ] def

Then using integers 0 and 1 for the flags, I can index
with 

   font-fam bold 2 mul italic add get

Then I can just maintain the variables, and set the font
in /settext so its always current when used.

I suppose lots of things might need simple controllable
representations like this.

[toc] | [prev] | [next] | [standalone]


#2162

Fromluser- -droog <mijoryx@yahoo.com>
Date2015-01-30 00:35 -0800
Message-ID<7988e366-4e43-44e4-9ee9-a514f0f5baa4@googlegroups.com>
In reply to#2161
On Friday, January 30, 2015 at 12:38:36 AM UTC-6, luser- -droog wrote:
> On Wednesday, January 28, 2015 at 11:40:34 PM UTC-6, luser- -droog wrote:
> > https://github.com/luser-dr00g/ibis.ps/blob/master/ibis.ps
> > https://github.com/luser-dr00g/debug.ps/blob/master/db5.ps
> [snip]> 
> With an array of fonts
> 
>    /font-fam [ -roman- -italic- -bold- -bold+italic- ] def
> 

Dammit! There's no /Palatino-Bold-Italic

[toc] | [prev] | [next] | [standalone]


#2163

Fromrodd@panix.com (Rod Dorman)
Date2015-01-30 20:45 +0000
Message-ID<magqhk$8ge$1@reader1.panix.com>
In reply to#2162
In article <7988e366-4e43-44e4-9ee9-a514f0f5baa4@googlegroups.com>,
luser- -droog  <mijoryx@yahoo.com> wrote:
>On Friday, January 30, 2015 at 12:38:36 AM UTC-6, luser- -droog wrote:
>> On Wednesday, January 28, 2015 at 11:40:34 PM UTC-6, luser- -droog wrote:
>> > https://github.com/luser-dr00g/ibis.ps/blob/master/ibis.ps
>> > https://github.com/luser-dr00g/debug.ps/blob/master/db5.ps
>> [snip]> 
>> With an array of fonts
>> 
>>    /font-fam [ -roman- -italic- -bold- -bold+italic- ] def
>> 
>
>Dammit! There's no /Palatino-Bold-Italic

But there is a Palatino-BoldItalic

-- 
					-- Rod --
rodd(at)polylogics(dot)com

[toc] | [prev] | [next] | [standalone]


#2164

Fromluser- -droog <mijoryx@yahoo.com>
Date2015-01-31 00:18 -0800
Message-ID<ce64b675-63d4-41bd-97aa-eb4f5ff93de5@googlegroups.com>
In reply to#2163
On Friday, January 30, 2015 at 2:45:42 PM UTC-6, Rod Dorman wrote:
> In article <7988e366-4e43-44e4-9ee9-a514f0f5baa4@googlegroups.com>,
> luser- -droog  <mijoryx@yahoo.com> wrote:
> >On Friday, January 30, 2015 at 12:38:36 AM UTC-6, luser- -droog wrote:
> >> On Wednesday, January 28, 2015 at 11:40:34 PM UTC-6, luser- -droog wrote:
> >> > https://github.com/luser-dr00g/ibis.ps/blob/master/ibis.ps
> >> > https://github.com/luser-dr00g/debug.ps/blob/master/db5.ps
> >> [snip]> 
> >> With an array of fonts
> >> 
> >>    /font-fam [ -roman- -italic- -bold- -bold+italic- ] def
> >> 
> >
> >Dammit! There's no /Palatino-Bold-Italic
> 
> But there is a Palatino-BoldItalic
> 

Awesome! It works!

[toc] | [prev] | [next] | [standalone]


#2166

FromYves Cloutier <yves.cloutier@gmail.com>
Date2015-02-01 18:42 -0800
Message-ID<2a3f301a-45e7-4bd0-b3a0-b290507a92e2@googlegroups.com>
In reply to#2164
On Saturday, January 31, 2015 at 3:18:40 AM UTC-5, luser- -droog wrote:
> On Friday, January 30, 2015 at 2:45:42 PM UTC-6, Rod Dorman wrote:
> > In article <7988e366-4e43-44e4-9ee9-a514f0f5baa4@googlegroups.com>,
> > luser- -droog  <mijoryx@yahoo.com> wrote:
> > >On Friday, January 30, 2015 at 12:38:36 AM UTC-6, luser- -droog wrote:
> > >> On Wednesday, January 28, 2015 at 11:40:34 PM UTC-6, luser- -droog wrote:
> > >> > https://github.com/luser-dr00g/ibis.ps/blob/master/ibis.ps
> > >> > https://github.com/luser-dr00g/debug.ps/blob/master/db5.ps
> > >> [snip]> 
> > >> With an array of fonts
> > >> 
> > >>    /font-fam [ -roman- -italic- -bold- -bold+italic- ] def
> > >> 
> > >
> > >Dammit! There's no /Palatino-Bold-Italic
> > 
> > But there is a Palatino-BoldItalic
> > 
> 
> Awesome! It works!

Hello Droog,  think what you are doing is really great and in fact would work well with my own project.

I am doing a higher-level markup for typesetting books.  Here is an example of inline formatting commands:

Some <bold<text>.  Some <bold, size +3<text>. Some <raise 3<superscript> text.

This is only a small example of a much more complete markup language. I currently generate Groff code, which can then get converted to .ps.  However I would like to be able to skip the groff middleman and be able to generate .ps directly from my markup.

I just bought a couple books on ps to see how much of a learning curse I have a head of me. I came on this group to look up things like how to do page layout, footnotes and other basic typesetting stuff...at least to get started.

But after seeing ibi, what I'm thinking is perhaps I could get my markup to generate ibis markup.

Anyhow, really interested in your work and where you are headed with this.

Regards,

yves

[toc] | [prev] | [next] | [standalone]


#2167

Fromluser- -droog <mijoryx@yahoo.com>
Date2015-02-01 23:04 -0800
Message-ID<280af8dc-0da4-45c3-970a-4aacda9fed27@googlegroups.com>
In reply to#2166
On Sunday, February 1, 2015 at 8:42:19 PM UTC-6, Yves Cloutier wrote:
> On Saturday, January 31, 2015 at 3:18:40 AM UTC-5, luser- -droog wrote:
> > On Friday, January 30, 2015 at 2:45:42 PM UTC-6, Rod Dorman wrote:
> > > In article <7988e366-4e43-44e4-9ee9-a514f0f5baa4@googlegroups.com>,
> > > luser- -droog  <mijoryx@yahoo.com> wrote:
> > > >On Friday, January 30, 2015 at 12:38:36 AM UTC-6, luser- -droog wrote:
> > > >> On Wednesday, January 28, 2015 at 11:40:34 PM UTC-6, luser- -droog wrote:
> > > >> > https://github.com/luser-dr00g/ibis.ps/blob/master/ibis.ps
> > > >> > https://github.com/luser-dr00g/debug.ps/blob/master/db5.ps
> > > >> [snip]> 
> > > >> With an array of fonts
> > > >> 
> > > >>    /font-fam [ -roman- -italic- -bold- -bold+italic- ] def
> > > >> 
> > > >
> > > >Dammit! There's no /Palatino-Bold-Italic
> > > 
> > > But there is a Palatino-BoldItalic
> > > 
> > 
> > Awesome! It works!
> 
> Hello Droog,  think what you are doing is really great and in fact would work well with my own project.
> 
> I am doing a higher-level markup for typesetting books.  Here is an example of inline formatting commands:
> 
> Some <bold<text>.  Some <bold, size +3<text>. Some <raise 3<superscript> text.
> 
> This is only a small example of a much more complete markup language. I currently generate Groff code, which can then get converted to .ps.  However I would like to be able to skip the groff middleman and be able to generate .ps directly from my markup.
> 
> I just bought a couple books on ps to see how much of a learning curse I have a head of me. I came on this group to look up things like how to do page layout, footnotes and other basic typesetting stuff...at least to get started.
> 
> But after seeing ibi, what I'm thinking is perhaps I could get my markup to generate ibis markup.
> 
> Anyhow, really interested in your work and where you are headed with this.
> 
> Regards,
> 
> yves

Excellent. Glad you're interested. The goals are to 
copy the syntax and styles from scribe, and
as many internal algorithms as possible from tex.
So things like explicitly increasing the font size
will be *possible*, but it's intended to separate
the appearance from the content by defining styles.

But in some ways, my track record on the project is
not good. It took me 4 years to get bold and italic
working. :)

This answer of mine has links to lots of related work:
http://tex.stackexchange.com/questions/64296/can-the-postscript-language-be-used-to-fully-replace-tex/170051#170051

For something "ready to use", I'd recommend looking
at anastigmatix's pages, and the "tinydict",

While I hope ultimately to surpass both of them,
it's still early days.

[toc] | [prev] | [next] | [standalone]


#2168

Fromluser- -droog <mijoryx@yahoo.com>
Date2015-02-03 03:27 -0800
Message-ID<85cd7be9-70fc-4534-8589-b0a1c440a592@googlegroups.com>
In reply to#2167
On Monday, February 2, 2015 at 1:04:16 AM UTC-6, luser- -droog wrote:
> On Sunday, February 1, 2015 at 8:42:19 PM UTC-6, Yves Cloutier wrote:
> > On Saturday, January 31, 2015 at 3:18:40 AM UTC-5, luser- -droog wrote:
> > > On Friday, January 30, 2015 at 2:45:42 PM UTC-6, Rod Dorman wrote:
> > > > In article <7988e366-4e43-44e4-9ee9-a514f0f5baa4@googlegroups.com>,
> > > > luser- -droog  <mijoryx@yahoo.com> wrote:
> > > > >On Friday, January 30, 2015 at 12:38:36 AM UTC-6, luser- -droog wrote:
> > > > >> On Wednesday, January 28, 2015 at 11:40:34 PM UTC-6, luser- -droog wrote:
> > > > >> > https://github.com/luser-dr00g/ibis.ps/blob/master/ibis.ps
> > > > >> > https://github.com/luser-dr00g/debug.ps/blob/master/db5.ps
> > > > >> [snip]> 
> 
> But in some ways, my track record on the project is
> not good. It took me 4 years to get bold and italic
> working. :)
> 
> This answer of mine has links to lots of related work:
> http://tex.stackexchange.com/questions/64296/can-the-postscript-language-be-used-to-fully-replace-tex/170051#170051
> 
> For something "ready to use", I'd recommend looking
> at anastigmatix's pages, and the "tinydict",
> 
> While I hope ultimately to surpass both of them,
> it's still early days.

Added paragraph-filling, which breaks most of the layout I had attempted
in the example. I've also been reading more deeply in the scribe paper.
Wondering how closely I need to follow his distinction between "inheriting"
and "non-inheriting" environment parameters.

$ cat ibis.ps
%!
%(debug.ps/db5.ps)run %currentfile cvx debug

%optionally dump text to stdout while writing
%/show { dup print (\n) print show } bind def

% essentially the same as level-2 >> operator
% but it is used in an attempt at level-1 compatibility
% but primarily for historical reasons:
% in 2011, xpost did not have >>
%
% mark k1 v1 .. kN vN  dicttomark  dict(N)
/dicttomark { counttomark dup dict begin 2 idiv { def } repeat pop currentdict end } def


% Composite Index  inc/dec  -
% (n.b. userdict is a composite object)
/inc { 2 copy get 1 add put } def
/dec { 2 copy get 1 sub put } def

/-= { 1 index load exch sub store } def

% Stack type is an array where element 0 contains the index of the top of the stack
%
% n  stack  array{n+1}:[0]=0
/stack { 1 add array dup 0 0 put } def
/top { dup 0 get get } def % S  top  a
/spop { dup top exch 0 dec } def % S  spop  a  (S{n}->S'(n-1})
/spush { % S a  spush  -  (S{n}->S'{n+1})
    dup type /stringtype eq { dup length string copy } if
    1 index 0 inc
    1 index 0 get exch put
} def
/sdrop { % S i  sdrop  -  (S{i}->removed)
    %(sdrop:)=
    1 index 0 get      % S i c
    1 index sub %1 sub  % S i c-i-1
    %pstack()=
    dup 0 gt {
        { % S i
            2 copy 2 copy % S i S i S i
            1 add get put % S' i
            1 add         % S i=i+1
        } repeat % S' i
    }{
        pop
    } ifelse
    pop
    0 dec    % S'
} def
% a b c d e f 2 sdrop
% a   c d e f  6-2=4 -1=3
% a c d e f
%/t { 6 a b c d e f } cvlit def t 2 sdrop t ==

% output device
/dev mark
    /size [ clippath pathbbox ]
    /bounds null
dicttomark def
/savebounds { dev /bounds [ x y X Y ] put } def
/restorebounds { dev /bounds get aload pop setbounds } def
/setbounds { % x y X Y  setbounds  -
    /Y exch def /X exch def /y exch def /x exch def
} def
/setmargin { % pts  setmargin  -
    dev /size get aload pop
    4 index sub 4 1 roll 4 index sub 4 1 roll
    4 index add 4 1 roll 4 index add 4 1 roll
    setbounds pop savebounds
} def

/nextpage { showpage restorebounds eol } def

/currentline 50 stack def

% text setting
/text mark
    /eol { /Y lead -=
        y Y lt { x Y moveto }
               { nextpage } ifelse }
    /heol { }
    /blank { setline eol }
    /fontchange true

    /setline {
        x Y
        (setline:)= pstack()=
        moveto
        currentline first 0 get 0 exch getinterval
        {
            %pstack()=
            aload pop setfont show
        } forall
        currentline 0 0 put
        eol
    }
    /setword {
        dup length 1 add string dup 3 1 roll copy pop
        dup dup length 1 sub ( ) putinterval
        currentpoint pop =
        (setword:)= pstack()=
        dup stringwidth pop dup currentpoint pop add X gt {
            setline
        } if
        0 rmoveto
        currentfont 2 array astore currentline exch spush
        %currentline ==
        %flush(%lineedit)(r)file pop
    }
    /settext {
        fontchange {
            fontfam tty 4 mul bold 2 mul add italic add get setfont
            /fontchange false store
        } if
        %show
        ( ) { search exch setword not { exit } if } loop
    }

    /fontsize 10
    /lead 12
    /setfontfam {
    text /fontfam [ %  -roman- -italic- -bold- -bold-italic- 
        /Palatino-Roman findfont fontsize scalefont
        /Palatino-Italic findfont fontsize scalefont
        /Palatino-Bold findfont fontsize scalefont
        /Palatino-BoldItalic findfont fontsize scalefont
        /Courier findfont fontsize scalefont
        /Courier-Oblique findfont fontsize scalefont
        /Courier-Bold findfont fontsize scalefont
        /Courier-BoldOblique findfont fontsize scalefont
    ] put
    }
    /italic 0
    /bold 0
    /tty 0

dicttomark def

% processing
% find takes 3 procedures, a string and search-string
% and executes on_a and on_b upon the returned substrings if found
% or the not procedure if not found
/find {               % {not} {on_b} {on_a} (aXb) (X)  find  -
    search {          % n b a (b) (X) (a)
        4 1 roll pop  % n b (a) a (b)
        4 1 roll      % n (b) b (a) a
        5 -1 roll pop % (b) b (a) a
        /exec cvx 5 3 roll % (a) a exec (b) b
        /exec cvx 6 array astore cvx exec
        %exec exec
    }{                   % n b a (a_b)
        4 1 roll pop pop % (a_b) n
        exec
    } ifelse
} def
%{(n)= =}{(b)= =}{(a)= =} (pretextpost) (text) find
%(stack:)= pstack
%quit

%shift a 1-char string off of a larger string
/first { % (abc)  first  (bc) (a)
    dup 1 1 index length 1 sub getinterval exch
    0 1 getinterval
} def

% delimiter pairs
/pairs mark
    ([)(]) (<)(>) (\()(\)) ({)(}) (`)(') (:)(;)
dicttomark def

% ([)  rhs  (])
% (q)  rhs  (q)
% (")  rhs  (")
/rhs { pairs exch 2 copy known { get }{ exch pop } ifelse } def

/nest 10 stack def
% {on_a} (])  deferal  {[{on_a} (])] nest exch spush}
% create a save-it-for-later proc
% for the not-found clause of find
/deferal {
    2 array astore
    [ exch /nest cvx /exch cvx /spush cvx ] cvx
} def

% {on_a} ([a]b)  delim  (b)
/delim {
    exch /process cvx exch /exec cvx 3 array astore cvx exch
    first rhs       % on_a (a]b) (])
    3 copy exch pop % on_a (a]b) (]) on_a (]) 
    deferal         % on_a (a]b) (]) not    %not-clause
    {}              % on_a (a]b) (]) not on_b  %on_b clause: leave string on stack
    5 2 roll        % not on_b on_a (a]b) (])
    %(delim)= pstack()=
    find
} def

% ([arg]rem) /name  short  (rem)
/short {
    %(short)= pstack()=
    alt exch get % s d
    dup /ini get exec % s d ?
    exch /fin get % s ? {}
    [ 3 1 roll /exec cvx ] cvx exch % undo s
    delim
} def

/pending 10 stack def
% (name)  checkpending  -
/checkpending {
    %(checking pending stack)= pending ==
    {
        pending 0 get -1 1 {  % (name) i
            %pstack()=
            pending 1 index get  % (name) i []
            0 get 2 index
            %pstack()=
            eq {  % (name) i
                %pstack()=
                stop
            } if
            pop
        } for
    } stopped {  % (name) i
        pending 1 index get 1 get  % (name) i fin-arg
        3 2 roll alt exch get /fin get exec  % i
        pending exch sdrop
    }{ Err:symbol-not-in-pending-stack } ifelse
} def

% ([name]rem)  long  (rem)
/long {
    first rhs          % (name]rem) (])
    {Err:long-form-arg-cannot-span-lines}
    {}
    {
        %pstack()=
        dup length string copy
        dup alt exch get /ini get exec
        2 array astore pending exch
        %pstack()=
        spush
        %pending ==
    }
    5 3 roll  % {} {} {} (name]rem) (])
    find
} def

% ([name]rem)  long-end  (rem)
/long-end {
    first rhs   % (name]rem) (])
    {Err:long-form-arg-cannot-span-lines}
    {}
    {checkpending} %search pending stack and remove match
    5 3 roll  % {} {} {} (name]rem) (])
    find
} def

% str  execute  -
/execute { token { exec process }{ BAD_COMMAND } ifelse } def

% the "at" sign indicates the start of an embedded command
/sigil <40> def

/command {
    {settext} {execute} {process} 4 3 roll
    sigil find
} def

% scan string for embedded @commands
% and call settext for other text.
/process { % str  process  -
    %(process:)= pstack()=
    dup length 0 eq {
        pop
        %blank
    }{
        nest 0 get 0 gt {
            {command} {process} nest top aload pop % str {!} {B} {A} (X)
            exch [ exch   % str {!} {B} (X) [ {A}
                nest exch /spop cvx exch /pop cvx exch %/process cvx exch
                    /exec cvx 
            ] cvx exch  % str {!} {B} {A}' (X)
            5 4 roll exch % {!} {B} {A} str (X)
            find
        %    {process}{process} nest top aload pop  % {!} {B} {A} (X)
        %    exch [
        %        %{nest spop pop process {defered "on_a"} exec}
        %        exch nest exch /spop cvx exch /pop cvx exch /process cvx exch /exec cvx
        %        ] cvx exch % {!} {B} {A}' (X)
        %    5 4 roll exch % {!} {B} {A} str (X)
        %    find
        }{
            command
        } ifelse
    } ifelse
} def

% call process on each line
%
/src null def
/buf 200 string def
/exitflag false def
/ibis { % file|string  ibis  -
    dup type /stringtype eq { (r) file } if
    dup type /filetype ne { NOT_A_FILE } if
    /src exch def

    %pstack()=
    {
        src buf readline {
            dup length 0 eq { blank } if
            process
            heol
        }{
            %process
            exit
        }ifelse
        heol
        exitflag { exit } if
    } loop

    setline
    showpage
} def

% @@ define the at-sign as a command to print itself
sigil { sigil settext } def


%alterations
/alt 20 dict def

% name dict  newalter  -
%
% dict should contain 2 procs
% -  ini  ?
% ?  fin  -
% where init returns an object that should be
% passed to final
/newalter {
    %install in alt dict
    2 copy alt 3 1 roll put
    %create short-form procedure
    pop [ 1 index /short cvx ] cvx def
} def

/updatefont { /fontchange true store } def

/r mark
    /ini { bold 2 mul italic add /bold 0 store /italic 0 store updatefont }
    /fin { dup 2 mod /italic exch store 2 idiv /bold exch store updatefont }
dicttomark newalter

/i mark
    /ini { italic /italic 1 store updatefont }
    /fin { /italic exch store updatefont }
dicttomark newalter

/b mark
    /ini { bold /bold 1 store updatefont }
    /fin { /bold exch store updatefont }
dicttomark newalter

/t mark
    /ini { tty /tty 1 store updatefont }
    /fin { /tty exch store updatefont }
dicttomark newalter

/Begin {
    long
} def

/End {
    long-end
} def

/default {
    text begin
    setfontfam
    72 setmargin
    %/Palatino-Roman 10 selectfont
    %alt /r get /ini get exec pop
    %/lead 12 def
    %eol
} def

/bye {/exitflag true def} def

%print manual only if /manual is defined (eg. `gs -dmanual ibis.ps`)
%/manual where { pop }{ currentfile flushfile } ifelse 

%/i load == quit
%stepon
%traceon

default
%currentfile /ibis load debug
currentfile ibis
Text is passed to the output.
Only ragged-right, explicit linebreaks for now.

There are various ways of executing a command to change
a section of text. All commands are introduced by the @@  character,
known internally as the "sigil".

The simple command @@ i for italics, can use the short form 
with various sets of delimiters.

    @@ i[italics] produces @{/tab currentpoint pop def}@i[italics]

    @@ i(italics) @{tab currentpoint exch pop moveto}@i(italics)

    @@ i<italics> @{tab currentpoint exch pop moveto}@i<italics>

    @@ i{italics} @{tab currentpoint exch pop moveto}@i{italics}

    @@ i `italics' @{tab currentpoint exch pop moveto}@i `italics'

    @@ i :italics; @{tab currentpoint exch pop moveto}@i :italics;

These last two require an extra space after the command name since
the backquote and colon are not postscript delimiters.

Incidentally, since the command name is scanned with 'token' and
executed with 'exec', it can even be a postscript procedure.
@{/oldfont currentfont def}

    @@ {/Courier 11 selectfont}text in Courier

    @{/Courier 11 selectfont}text in Courier

@{oldfont setfont}
Only "short-form" commands take a delimited argument. 
The @@ {arbitrary ps code} commands are not "short-form", 
and do not take an argument but apply directly to the current state.
But they do receive the remaining portion of the line as a string,
so a custom command may consume data from the string and yield the
remainder to be printed (it should leave a string on the stack).

Now with @b[bold].

I finally remembered what "deferal" was all about. So let's 
see if it works. It should allow bracketed commands to span
multiple lines. Like so @i[ This sentence should be all italics
despite spanning lines, in a line-oriented scanning routine. ]
And back to normal.

Long-form uses the same command names, but it is now the @i{argument}
to the @@ Begin{} or @@ End{} command.

@@ Begin{i}@Begin{i}Start italics.
@@ End{i}@End{i}End italics. 

@t[ typewriter-text @i<oblique> ]

Haha! I just read in the scribe paper that @@ Begin() and @@ End()
sections should always be properly nested.
So I just wasted some effort getting this to work:

    @@ Begin{i} italic @@ Begin{b} bold-italic @@ End{i} bold @@ End{b} normal
    @Begin{i} italic @Begin{b} bold-italic @End{i} bold @End{b} normal

But it's probably best to nest things properly anyway.
This should be considered "backup" behavior.

@bye
%(stack:)= pstack(---)= currentfile flushfile


[toc] | [prev] | [next] | [standalone]


#2169

Fromjdaw1 <jdawiseman@gmail.com>
Date2015-02-04 01:48 -0800
Message-ID<ea3ba15e-b929-4425-9176-9be078968dd5@googlegroups.com>
In reply to#2166
FYI, I have a mark-up that could be a middle step for you. The one program I maintain, linked from http://www.jdawiseman.com/placemat.html , uses an idea called a compound string. A 'compound string' is any of:
* (A string)
* /GlyphName 
* {code}
* [An array of compound strings]

The code is the interesting bit. It can change the font, move the current point, paint something, leave some compound strings on the stack, etc. E.g.,
{0 CurrentFontSize 0.375 mul rmoveto  CurrentFontName CurrentFontSize 1.7 div selectfont}

You are welcome to pillage my code for useful bits.

[toc] | [prev] | [next] | [standalone]


#2170

Fromluser- -droog <mijoryx@yahoo.com>
Date2015-02-07 02:11 -0800
Message-ID<7324f678-ccfa-452b-9d4e-273fbb1c183e@googlegroups.com>
In reply to#2169
On Wednesday, February 4, 2015 at 3:48:55 AM UTC-6, jdaw1 wrote:
> FYI, I have a mark-up that could be a middle step for you. The one program I maintain, linked from http://www.jdawiseman.com/placemat.html , uses an idea called a compound string. A 'compound string' is any of:
> * (A string)
> * /GlyphName 
> * {code}
> * [An array of compound strings]
> 
> The code is the interesting bit. It can change the font, move the current point, paint something, leave some compound strings on the stack, etc. E.g.,
> {0 CurrentFontSize 0.375 mul rmoveto  CurrentFontName CurrentFontSize 1.7 div selectfont}
> 
> You are welcome to pillage my code for useful bits.

I feel like we've had this conversation before. But I am definitely
looking at your code again for things to steal. Tx :)

IIRC it was centering text, the similar event I seem to remember.
A function to center the baseline at a specified point? 
I'm definitely going to need to do that again. But now my lines
are arrays of [ (string) <<font>> ] pairs.

[toc] | [prev] | [next] | [standalone]


#2171

Fromjdaw1 <jdawiseman@gmail.com>
Date2015-02-07 02:39 -0800
Message-ID<f4182f20-29c3-4e2a-a9cc-21d8c1d2c1c0@googlegroups.com>
In reply to#2170
Your markup allows font changes. But how would it allow a change of font size?

[toc] | [prev] | [next] | [standalone]


#2172

Fromluser- -droog <mijoryx@yahoo.com>
Date2015-02-07 15:15 -0800
Message-ID<35f1446a-824b-4239-b105-c574ad99db65@googlegroups.com>
In reply to#2171
On Saturday, February 7, 2015 at 4:39:24 AM UTC-6, jdaw1 wrote:
> Your markup allows font changes. But how would it allow a change of font size?

Good question. There are some things I still need to figure out.
I think the line buffer data structure (`[ [(text)<<font>>] * ]`) 
can work with changing sizes. But I need to add the /Leading in there
too, I think. The vertical space needed for a line should be the
max of the Leading of any text segment in the line.

BTW, my favorite book for this stuff is called "Production for the
Graphic Designer". It always describes font sizes as two numbers,
points/lead, like 9/11, 10/12.

In a later pass, I'll worry about collisions between ascenders and
descenders. 

I don't know how best to specify the font size from the input language.
My first thought is two commands

  @setfontsize{num}   where num is the absolute size
  @changefontsize{rel}   where rel is a difference 
                         relative to the current size

But then we'd need third command to specify the change
as a percentage. Maybe just @setfontsize and @currentfontsize
and need to do a little postscript arithmetic for a relative
change. Then any form of relative change can be realized.

Those names are kind of long, though. But, maybe that's good.
It will encourage using styles instead of arbitrary fontchanges
in running text.

So, that's what I'm thinking.

[toc] | [prev] | [next] | [standalone]


#2173

Fromtlvp <mPiOsUcB.EtLlLvEp@att.net>
Date2015-02-08 00:21 -0500
Message-ID<3ssxii9b79oy.1wjmmjgjxzow2.dlg@40tude.net>
In reply to#2172
On Sat, 7 Feb 2015 15:15:57 -0800 (PST), luser- -droog wrote:

>  @setfontsize{num}   where num is the absolute size
>   @changefontsize{rel}   where rel is a difference 
>                          relative to the current size
> 
> But then we'd need third command to specify the change
> as a percentage.

Just as you have absolute and relative LineTo commands (lineto and rlineto)
so you might have absolute (differential) and proportional ChangeFontSize
commands (perhaps @changefontsize{diff} and @rchangefontsize{percent}?).

Cheers, -- tlvp
-- 
Avant de repondre, jeter la poubelle, SVP.

[toc] | [prev] | [next] | [standalone]


#2174

Fromluser- -droog <mijoryx@yahoo.com>
Date2015-02-08 02:45 -0800
Message-ID<18b2b9f0-4f37-43ba-9a77-635587377951@googlegroups.com>
In reply to#2173
On Saturday, February 7, 2015 at 11:21:25 PM UTC-6, tlvp wrote:
> On Sat, 7 Feb 2015 15:15:57 -0800 (PST), luser- -droog wrote:
> 
> >  @setfontsize{num}   where num is the absolute size
> >   @changefontsize{rel}   where rel is a difference 
> >                          relative to the current size
> > 
> > But then we'd need third command to specify the change
> > as a percentage.
> 
> Just as you have absolute and relative LineTo commands (lineto and rlineto)
> so you might have absolute (differential) and proportional ChangeFontSize
> commands (perhaps @changefontsize{diff} and @rchangefontsize{percent}?).
> 

Useful thoughts. Thanks. I've been focusing on the
other part of just making something that works.
So the current example looks like this:

An interest has developed in changing the font size. Currently,
this can be hacked with explicit postscript. 
@{/fontsize 5 += /lead 3 += setfontfam /fontchange true store} Big text.
@{/fontsize 5 -= /lead 3 -= setfontfam /fontchange true store} back to normal.

But maybe it's inefficient to call setfontfam, which
calls findfont and scalefont for all 8 fonts.

The size of any given font is just its matrix, right?
So I could, I don't know, use that somehow. Store the
matrix separately? Does that help?

I can't use stringwidth easily without a scaled font
installed.

[toc] | [prev] | [next] | [standalone]


#2175

Fromtlvp <mPiOsUcB.EtLlLvEp@att.net>
Date2015-02-09 22:46 -0500
Message-ID<y9k1bchkq9hp.m8784nv8044g.dlg@40tude.net>
In reply to#2174
On Sun, 8 Feb 2015 02:45:21 -0800 (PST), luser- -droog wrote:

> Useful thoughts. Thanks.

YW. It's always handy to coin imperatives that are well motivated, hence
easy to remember :-) . Cheers, -- tlvp
-- 
Avant de repondre, jeter la poubelle, SVP.

[toc] | [prev] | [next] | [standalone]


#2184 — ibis (was: Re: anybody mind if I just ... already long have been

Fromluser- -droog <mijoryx@yahoo.com>
Date2015-02-18 00:02 -0800
Subjectibis (was: Re: anybody mind if I just ... already long have been
Message-ID<224a51b9-6e98-4f7c-adff-0b2e1ded1d2e@googlegroups.com>
In reply to#2175
I broke 1000 lines, and burned through my first wind, I think.
So, I thought I share since I can't think of anything more to 
do to it at the moment.

I think I've committed a synecdoche and used the word "style"
at the wrong granularity. I'm not sure if it should refer to 
a specific command, like `header` or a collection of these
commands, like `letter` | `manual` | `screenplay` | etc.

But the part I'm really proud of, I probably need to comment 
better. I think all this abstract algebra is rubbing off an
I've made something like a "group" for style-changes.

So, I've got a basic object called an "alt dict" (and a dict
named "alt" to hold them, for an extra level of obscurity).
An alt dict contains two functions named /ini and /fin where
ini returns an object which is passed to fin. Typically, ini
will change some definition, but return the previous value,
so fin can "undo" the change by restoring the old value.

A "style" then, as I've implemented it, can compose any 
number of alt dicts together to produce a new alt dict
which implements the composite behavior. The @code style
is very small and explicable.

/code { b t } addstyle

where b and t are 'bold' and 'typewriter' font changes.

The alt dict for code contains the ini and fin procedures
from the b and t dicts composed together into new procedures.

/code <<
    /ini { [ {b-ini} exec {t-ini} exec ] }
    /fin { aload pop {t-fin} exec {b-fin} exec }
>>

where {b-ini} designates the /ini from b, etc.

For the font size command, I've kept it real simple for now.

  @font+{big @font+[bigger]} @font-(smaller @font-<very small>)

would be the explicit, short-form syntax. As hinted, it can 
also be used in the long form.

  @Begin{font+}Big text@End{font+}

or composed in a style, as in the 'heading' style:

  /heading { eolbefore b i font+ eolafter } addstyle

I've tried to add comments liberally throughout, but I'm probably
not the best judge of which parts are confusing. 

So, questions/comments/ideas for what to add next?

Hmm. It's too big for my xterm scrollback buffer, so it's
probably getting a little too long to post here. So I'll just
do the link.
https://github.com/luser-dr00g/ibis.ps

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.postscript


csiph-web