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


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

Putting lines from a file into an array

Started byCecil Westerhof <Cecil@decebal.nl>
First post2012-12-02 21:02 +0100
Last post2016-08-22 22:31 -0700
Articles 20 on this page of 24 — 8 participants

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


Contents

  Putting lines from a file into an array Cecil Westerhof <Cecil@decebal.nl> - 2012-12-02 21:02 +0100
    Re: Putting lines from a file into an array Chris <cjl@spamcop.net> - 2012-12-02 20:47 +0000
      Re: Putting lines from a file into an array Cecil Westerhof <Cecil@decebal.nl> - 2012-12-03 00:52 +0100
        Re: Putting lines from a file into an array Don Lancaster <don@tinaja.com> - 2012-12-05 11:58 -0700
          Re: Putting lines from a file into an array "luser.droog" <luser.droog@gmail.com> - 2012-12-05 23:19 -0600
      Re: Putting lines from a file into an array John Deubert <john@acumentraining.com> - 2012-12-03 13:20 -0800
        Re: Putting lines from a file into an array "luser.droog" <luser.droog@gmail.com> - 2012-12-04 00:58 -0600
        Re: Putting lines from a file into an array Chris <cjl@spamcop.net> - 2012-12-04 09:09 +0000
          Re: Putting lines from a file into an array John Deubert <john@acumentraining.com> - 2012-12-04 07:03 -0800
            Re: Putting lines from a file into an array Chris <cjl@spamcop.net> - 2012-12-04 17:46 +0000
          Re: Putting lines from a file into an array Cecil Westerhof <Cecil@decebal.nl> - 2012-12-04 17:17 +0100
    Re: Putting lines from a file into an array "luser.droog" <luser.droog@gmail.com> - 2012-12-02 15:31 -0600
      Re: Putting lines from a file into an array Cecil Westerhof <Cecil@decebal.nl> - 2012-12-03 02:19 +0100
        Re: Putting lines from a file into an array "luser.droog" <luser.droog@gmail.com> - 2012-12-02 23:28 -0600
          Re: Putting lines from a file into an array Cecil Westerhof <Cecil@decebal.nl> - 2012-12-03 10:01 +0100
    Re: Putting lines from a file into an array luser droog <luser.droog@gmail.com> - 2016-08-01 13:25 -0700
      Re: Putting lines from a file into an array JohnF <john@please.see.sig.for.email.com> - 2016-08-02 03:39 +0000
        Re: Putting lines from a file into an array luser droog <luser.droog@gmail.com> - 2016-08-02 21:58 -0700
          Re: Putting lines from a file into an array Tonton Th <tTh@nowhere.invalid> - 2016-08-03 05:10 +0000
          Re: Putting lines from a file into an array luser droog <luser.droog@gmail.com> - 2016-08-02 22:20 -0700
            Re: Putting lines from a file into an array luser droog <luser.droog@gmail.com> - 2016-08-02 22:35 -0700
              Re: Putting lines from a file into an array JohnF <john@please.see.sig.for.email.com> - 2016-08-03 06:21 +0000
              Re: Putting lines from a file into an array JohnF <john@please.see.sig.for.email.com> - 2016-08-03 06:32 +0000
                Re: Putting lines from a file into an array luser droog <luser.droog@gmail.com> - 2016-08-22 22:31 -0700

Page 1 of 2  [1] 2  Next page →


#1127 — Putting lines from a file into an array

FromCecil Westerhof <Cecil@decebal.nl>
Date2012-12-02 21:02 +0100
SubjectPutting lines from a file into an array
Message-ID<87624kp6hc.fsf@Compaq.site.inet>
I have the following script:
    /buffer 80 string def
    /inputFile INPUT (r) file def
    {
        inputFile buffer readline {
            =
        }{
            pop
            inputFile closefile
            exit
        } ifelse
    } loop

This displays the file. But instead of displaying I would like to put
the lines into an array.

Just keeping the values on the stack Like:
    /buffer 80 string def
    /inputFile INPUT (r) file def
    {
        inputFile buffer readline {
            % Keep it on the stack
        }{
            pop
            inputFile closefile
            exit
        } ifelse
    } loop
    stack

does not work, because the lower values are overwritten.

The first script gives:
    They are not only idle who do nothing,
    but they are idle also
    who might be better employed.

    Socrates

While the second gives:
    Socrates

    Socratest be better employed.
    Socratest be better em
    Socratest be better employed. nothing,

How would I get the lines correctly into an array?

-- 
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof

[toc] | [next] | [standalone]


#1128

FromChris <cjl@spamcop.net>
Date2012-12-02 20:47 +0000
Message-ID<y7Pus.223533$kt5.184865@fx08.am4>
In reply to#1127
On Sun, 02 Dec 2012 21:02:55 +0100, Cecil Westerhof wrote:

> I have the following script:
>     /buffer 80 string def /inputFile INPUT (r) file def {
>         inputFile buffer readline {
>             =
>         }{
>             pop inputFile closefile exit
>         } ifelse
>     } loop
> 
> This displays the file. But instead of displaying I would like to put
> the lines into an array.
> 
> Just keeping the values on the stack Like:
>     /buffer 80 string def /inputFile INPUT (r) file def {
>         inputFile buffer readline {
>             % Keep it on the stack
>         }{
>             pop inputFile closefile exit
>         } ifelse
>     } loop stack
> 
> does not work, because the lower values are overwritten.
> 
> The first script gives:
>     They are not only idle who do nothing,
>     but they are idle also who might be better employed.
> 
>     Socrates
> 
> While the second gives:
>     Socrates
> 
>     Socratest be better employed. Socratest be better em Socratest be
>     better employed. nothing,
> 
> How would I get the lines correctly into an array?

The values get overwritten because you only allocate one string for the 
lines to be read into ("/buffer 80 string def"), then reuse it for each 
iteration through the loop.

Something like:

  /inputFile INPUT (r) file def
  /linearray
  [
    {
      inputFile 80 string readline
      not
      {
        pop inputFile closefile
        currentdict /inputFile undef
        exit
      } if
    } loop
  ]
  def


will give you the lines of the file in an array called "linearray".

You can dump the contents thus:

  linearray {print (\n) print } forall

(Note the explicit new line)

Chris

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


#1130

FromCecil Westerhof <Cecil@decebal.nl>
Date2012-12-03 00:52 +0100
Message-ID<871uf8ovud.fsf@Compaq.site.inet>
In reply to#1128
Op zondag 2 dec 2012 21:47 CET schreef Chris:

> The values get overwritten because you only allocate one string for the
> lines to be read into ("/buffer 80 string def"), then reuse it for each 
> iteration through the loop.
>
> Something like:
>
> /inputFile INPUT (r) file def
> /linearray
> [
> {
> inputFile 80 string readline
> not
> {
> pop inputFile closefile
> currentdict /inputFile undef
> exit
> } if
> } loop
> ]
> def
>
>
> will give you the lines of the file in an array called "linearray".

Works like a charm. Thanks.

-- 
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof

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


#1149

FromDon Lancaster <don@tinaja.com>
Date2012-12-05 11:58 -0700
Message-ID<ai9jq2FddlnU1@mid.individual.net>
In reply to#1130
On 12/2/2012 4:52 PM, Cecil Westerhof wrote:
> Op zondag 2 dec 2012 21:47 CET schreef Chris:
>
>> The values get overwritten because you only allocate one string for the
>> lines to be read into ("/buffer 80 string def"), then reuse it for each
>> iteration through the loop.
>>
>> Something like:
>>
>> /inputFile INPUT (r) file def
>> /linearray
>> [
>> {
>> inputFile 80 string readline
>> not
>> {
>> pop inputFile closefile
>> currentdict /inputFile undef
>> exit
>> } if
>> } loop
>> ]
>> def
>>
>>
>> will give you the lines of the file in an array called "linearray".
>
> Works like a charm. Thanks.
>


The need is called "string dereferencing"

As in   (reusable_string) dup length string cvs ----> (safe_string)

More at http://www.tinaja.com/glib/strconv.pdf

-- 
Many thanks,

Don Lancaster                          voice phone: (928)428-4073
Synergetics   3860 West First Street   Box 809 Thatcher, AZ 85552
rss: http://www.tinaja.com/whtnu.xml   email: don@tinaja.com

Please visit my GURU's LAIR web site at http://www.tinaja.com

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


#1150

From"luser.droog" <luser.droog@gmail.com>
Date2012-12-05 23:19 -0600
Message-ID<k9p9u4$jv2$1@dont-email.me>
In reply to#1149
Don Lancaster wrote:

> On 12/2/2012 4:52 PM, Cecil Westerhof wrote:
>> Op zondag 2 dec 2012 21:47 CET schreef Chris:
>>
>>> The values get overwritten because you only allocate one string for the
>>> lines to be read into ("/buffer 80 string def"), then reuse it for each
>>> iteration through the loop.
>>>
>>> Something like:
>>>
>>> /inputFile INPUT (r) file def
>>> /linearray
>>> [
>>> {
>>> inputFile 80 string readline
>>> not
>>> {
>>> pop inputFile closefile
>>> currentdict /inputFile undef
>>> exit
>>> } if
>>> } loop
>>> ]
>>> def
>>>
>>>
>>> will give you the lines of the file in an array called "linearray".
>>
>> Works like a charm. Thanks.
>>
> 
> 
> The need is called "string dereferencing"
> 
> As in   (reusable_string) dup length string cvs ----> (safe_string)
> 
> More at http://www.tinaja.com/glib/strconv.pdf
> 

A very nice resource! A few nits:

`dup length string copy` is probably more straightforward than `dup length
string cvs` although cvs detects that it's already a string and simply does
a copy. 

On the next page, the example 
  (yourstring) cvs exec
should be 
  (yourstring) cvx exec

And this one's really minor, but... Sometimes you use '[' and other times
you use 'mark' but nowhere (in THIS doc) do you tell the noobs that they're
the same thing. 

Aside from these things, I love it! My only complaint about your writings is
that they're toooo extensive! You've written so so so much. I enjoyed a
busride just the other day by re-reading PS Insider Secrets. :)

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


#1137

FromJohn Deubert <john@acumentraining.com>
Date2012-12-03 13:20 -0800
Message-ID<2012120313202243338-john@acumentrainingcom>
In reply to#1128
On 2012-12-02 20:47:26 +0000, Chris said:

> On Sun, 02 Dec 2012 21:02:55 +0100, Cecil Westerhof wrote:
> 
>> I have the following script:
>> /buffer 80 string def /inputFile INPUT (r) file def {
>> inputFile buffer readline {
>> =
>> }{
>> pop inputFile closefile exit
>> } ifelse
>> } loop
>> 
>> This displays the file. But instead of displaying I would like to put
>> the lines into an array.
>> 
>> Just keeping the values on the stack Like:
>> /buffer 80 string def /inputFile INPUT (r) file def {
>> inputFile buffer readline {
>> % Keep it on the stack
>> }{
>> pop inputFile closefile exit
>> } ifelse
>> } loop stack
>> 
>> does not work, because the lower values are overwritten.
>> 
>> The first script gives:
>> They are not only idle who do nothing,
>> but they are idle also who might be better employed.
>> 
>> Socrates
>> 
>> While the second gives:
>> Socrates
>> 
>> Socratest be better employed. Socratest be better em Socratest be
>> better employed. nothing,
>> 
>> How would I get the lines correctly into an array?
> 
> The values get overwritten because you only allocate one string for the
> lines to be read into ("/buffer 80 string def"), then reuse it for each
> iteration through the loop.
> 
> Something like:
> 
>   /inputFile INPUT (r) file def
>   /linearray
>   [
>     {
>       inputFile 80 string readline
>       not
>       {
>         pop inputFile closefile
>         currentdict /inputFile undef
>         exit
>       } if
>     } loop
>   ]
>   def
> 
> 
> will give you the lines of the file in an array called "linearray".
> 
> You can dump the contents thus:
> 
>   linearray {print (\n) print } forall
> 
> (Note the explicit new line)
> 
> Chris

Note that there is possible error condition implicit in the above 
method; using brackets to construct the array places the array contents 
temporarily on the stack. All of the lines in the file are being piled 
up on the stack, remaining there until the close bracket. If you have a 
very large file (that is, a file with a large number of lines in it), 
you will eventually provoke a stack overflow. The maximum size of the 
operand stack is implementation dependent in Level 2 & 3 devices, so 
it's hard to say when (or if) you'll encounter the problem.

I'm not at all saying this is a bad solution; it's probably how I'd do 
it. But if you get the very occasional stack overflow from this 
solution, that's probably the source of the problem.

Hmmm. How can we fix this? The problem is that unless you use the 
brackets to construct your array, PostScript requires you allocate the 
array ahead of time, which, in turn, requires knowing how many lines 
there are in the file. You could read the file twice (once counting 
lines, the second actually constructing the array), but that seems 
inelegant, somehow.

<< ... some minutes later ... >>

Here's a novel solution based on the fact that PostScript dictionaries 
automatically expand as needed. Let's read the lines into a dictionary, 
see how many key-value pairs end up in the dictionary, make an array 
with room for that many items, and then transfer the strings from the 
dictionary to the array. A bit convoluted, but should be immune to 
stackoverflow errors.

Lessee here...

% ============== Cut here ==============
/$lines 100 dict def	% Our dictionary of lines; initially room for 100 
lines, expandable

/inputFile INPUT (r) file def
/i 0 def
$lines begin		% Put the dict on the dict stack for convenience

% Let's construct the dictionary
{	inputFile 100 string readline		% read a line of text
	exch				% Bring the string to the top of the stack
	i exch def			% define i and the line as a key-value pair
	/i i 1 add store	% and increment i
	not { exit } if		% leave the loop if that was the last line
} loop

% At this point, the $lines dictionary contains line numbers and line 
text as key-value pairs
% Now we need to transfer the lines to an array.

% First we create the array:
/numLines currentdict length def 	% Note that numLines ends up in our 
"$lines" dict; this is fine with me.
numLines array				% Create the new array

0 1 numLines 1 sub		% Interate through the lines in the dictionary
{					% Stack:  [ ] i
	2 copy			% Stack:  [ ] i [ ] i
	dup load		% Stack:  [ ] i [ ] i (line o' text)
	put pop			% Stack:  [ ]
} for
% The loop exits with our array of strings on the stack

end		% We don't need $lines anymore 


% Save the array as a variable, if we wish:
/linearray exch def


% =============== Cut here =================

As I say, not as simple as Chris' version, but it does work around the 
stack limitation. I'd go with Chris' code unless the number of lines 
was likely to be northward of 1000 lines or so. (By the way, there's 
some cleanup one could do on this code, but lunch is beckoning.)

- John


-- 
========
John Deubert
Acumen Training
PostScript & PDF Engineering Classes & Consulting
www.acumentraining.com

Learn PostScript programming techniques
Read the free Acumen Journal
acumentraining.com/acumenjournal.html

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


#1138

From"luser.droog" <luser.droog@gmail.com>
Date2012-12-04 00:58 -0600
Message-ID<k9k6us$boq$1@dont-email.me>
In reply to#1137
John Deubert wrote:

> On 2012-12-02 20:47:26 +0000, Chris said:
> 
>> On Sun, 02 Dec 2012 21:02:55 +0100, Cecil Westerhof wrote:
>> 
>>> I have the following script:
<snip original>
>>> This displays the file. But instead of displaying I would like to put
>>> the lines into an array.
<snip [{readline}loop]>
>> will give you the lines of the file in an array called "linearray".
>> 
>> You can dump the contents thus:
>> 
>>   linearray {print (\n) print } forall
>> 
>> (Note the explicit new line)
>> 
>> Chris
> 
> Note that there is possible error condition implicit in the above
> method; using brackets to construct the array places the array contents
> temporarily on the stack. All of the lines in the file are being piled
> up on the stack, remaining there until the close bracket. If you have a
> very large file (that is, a file with a large number of lines in it),
> you will eventually provoke a stack overflow. The maximum size of the
> operand stack is implementation dependent in Level 2 & 3 devices, so
> it's hard to say when (or if) you'll encounter the problem.
> 
> I'm not at all saying this is a bad solution; it's probably how I'd do
> it. But if you get the very occasional stack overflow from this
> solution, that's probably the source of the problem.
> 
> Hmmm. How can we fix this? The problem is that unless you use the
> brackets to construct your array, PostScript requires you allocate the
> array ahead of time, which, in turn, requires knowing how many lines
> there are in the file. You could read the file twice (once counting
> lines, the second actually constructing the array), but that seems
> inelegant, somehow.
> 
> << ... some minutes later ... >>
<snip <<0()1()>>count array {fill-array}loop>

You're totally right. This is one of the big problems I've had with xpost
(for which I have only myself to blame) that the stack sizes are fixed at
compile-time. When I tried testing it with the Barcode Writer In Pure
Postscript, stackoverflow was a constant (:() companion.

So here's a version of the file-slurping which scans the string twice. Still
limited (except on Jaws, prolly) to 16bit file sizes.

I tried to be clever in the second loop, so the stack comments reflect
[possible stack contents]. I'm not sure I can recommend doing this, but
I've been itching to try it. 

%!
%farr.ps File into Array
(farr.ps)(r)file  % File
dup bytesavailable string  % File String
readstring pop  % fileString
dup 0 exch % S 0 S
(\n){ % S 0 S \n
    search{ % S 0 Se \n Sb
        pop % S 0 Se \n
        3 -1 roll % S Se \n 0
        1 add     % S Se \n 1
        3 1 roll  % S 1 Se \n
    }{ % n Se
        pop
        1 add
        exit
    }ifelse
}loop % S numlines
dup =
array exch % A S
/i 0 def
(\n){ % A S \n
    search % A Se [\n Sb] bool
    exch % A [Se \n] bool [Sb|Se]
    count 1 sub index % A [Se \n] bool [Sb|Se] A
    exch i exch put % A [Se \n] bool
    /i i 1 add def
    not{exit}if
}loop % A
==

%(\n){ search { 3 1 roll }{ exit } ifelse }loop count array astore ==

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


#1140

FromChris <cjl@spamcop.net>
Date2012-12-04 09:09 +0000
Message-ID<o5jvs.446497$Wc4.79492@fx10.am4>
In reply to#1137
On Mon, 03 Dec 2012 13:20:22 -0800, John Deubert wrote:

<SNIP> 
> As I say, not as simple as Chris' version, but it does work around the
> stack limitation. I'd go with Chris' code unless the number of lines was
> likely to be northward of 1000 lines or so. (By the way, there's some
> cleanup one could do on this code, but lunch is beckoning.)

FWIW, that wasn't "my version": I tried to answer the question by making 
minimal changes to the OP's code.

If I were writing it from scratch myself, I would either (assuming we 
know we'd always have a positionable file stream, or that we're allowed 
to use ReusableStreamDecode) not read in the entire file at all, but just 
find and keep the line(s) of interest at a given time.

*Or* I would use (sort of) half of your solution, and use a dictionary as 
the "permanent" storage for the file contents, with the line numbers as 
the keys. In addition, I would have a single, large line buffer which 
gets reused for reading from the file, then I would get the actual length 
of each line, and copy it to a new, correctly sized string. Thus 
minimising redundant memory use.

Creating and copying the strings and writing to the dictionary would be 
appreciably slower, *but* the bottleneck will always be reading from the 
file. And on a decent interpreter, there shouldn't be an appreciable 
difference in performance between iterating through a dictionary vs an 
array.

I feel both those would scale better than using an array.

Chris

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


#1141

FromJohn Deubert <john@acumentraining.com>
Date2012-12-04 07:03 -0800
Message-ID<2012120407031929493-john@acumentrainingcom>
In reply to#1140
On 2012-12-04 09:09:40 +0000, Chris said:

> On Mon, 03 Dec 2012 13:20:22 -0800, John Deubert wrote:
> 
> <SNIP>
>> As I say, not as simple as Chris' version, but it does work around the
>> stack limitation. I'd go with Chris' code unless the number of lines was
>> likely to be northward of 1000 lines or so. (By the way, there's some
>> cleanup one could do on this code, but lunch is beckoning.)
> 
> FWIW, that wasn't "my version": I tried to answer the question by making
> minimal changes to the OP's code.
> 
> If I were writing it from scratch myself, I would either (assuming we
> know we'd always have a positionable file stream, or that we're allowed
> to use ReusableStreamDecode) not read in the entire file at all, but just
> find and keep the line(s) of interest at a given time.
> 
> *Or* I would use (sort of) half of your solution, and use a dictionary as
> the "permanent" storage for the file contents, with the line numbers as
> the keys. In addition, I would have a single, large line buffer which
> gets reused for reading from the file, then I would get the actual length
> of each line, and copy it to a new, correctly sized string. Thus
> minimising redundant memory use.
> 
> Creating and copying the strings and writing to the dictionary would be
> appreciably slower, *but* the bottleneck will always be reading from the
> file. And on a decent interpreter, there shouldn't be an appreciable
> difference in performance between iterating through a dictionary vs an
> array.
> 
> I feel both those would scale better than using an array.
> 
> Chris

No offense intended. I assumed you knew about the stackoverflow problem 
and were presenting a minimum-change solution. I called it "Chris' 
solution" because, um, well, I had to call it *something.*

- J
-- 
========
John Deubert
Acumen Training
PostScript & PDF Engineering Classes & Consulting
www.acumentraining.com

Learn PostScript programming techniques
Read the free Acumen Journal
acumentraining.com/acumenjournal.html

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


#1143

FromChris <cjl@spamcop.net>
Date2012-12-04 17:46 +0000
Message-ID<UFqvs.446503$Wc4.334216@fx10.am4>
In reply to#1141
On Tue, 04 Dec 2012 07:03:19 -0800, John Deubert wrote:
> 
> No offense intended. I assumed you knew about the stackoverflow problem
> and were presenting a minimum-change solution. I called it "Chris'
> solution" because, um, well, I had to call it *something.*

None taken. I just didn't want to risk you being disappointed in a 
"graduate" of your Postscript training....
;-)

Chris

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


#1142

FromCecil Westerhof <Cecil@decebal.nl>
Date2012-12-04 17:17 +0100
Message-ID<87boe9dc6w.fsf@Compaq.site.inet>
In reply to#1140
Op dinsdag 4 dec 2012 10:09 CET schreef Chris:

> If I were writing it from scratch myself, I would either (assuming we
> know we'd always have a positionable file stream, or that we're allowed 
> to use ReusableStreamDecode) not read in the entire file at all, but just 
> find and keep the line(s) of interest at a given time.

Well, the way I now want to use it (never know about the future) is
that it is a small file (below 1 KB) and I want to use all the lines.

At the moment all the lines except the last in the same way. But that
properly will change. For example beginning a line with {l}, {r} or
{c} would mean that the line should be left justified, right justified
or centered.


> *Or* I would use (sort of) half of your solution, and use a dictionary as
> the "permanent" storage for the file contents, with the line numbers
> as 

Agree, no use converting a dictionary to an array, if you can loop
over both. ;-)


> the keys. In addition, I would have a single, large line buffer which 
> gets reused for reading from the file, then I would get the actual length 
> of each line, and copy it to a new, correctly sized string. Thus 
> minimising redundant memory use.

At the moment I leave the code alone. Done enough with it. But I am
still interested how you would do that? Just to learn the language.
And who knows: when my usage changes, it would maybe become a good
idea to implement it.

-- 
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof

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


#1129

From"luser.droog" <luser.droog@gmail.com>
Date2012-12-02 15:31 -0600
Message-ID<k9gput$d8j$1@dont-email.me>
In reply to#1127
Cecil Westerhof wrote:

> I have the following script:
>     /buffer 80 string def
>     /inputFile INPUT (r) file def
>     {
>         inputFile buffer readline {
>             =
>         }{
>             pop
>             inputFile closefile
>             exit
>         } ifelse
>     } loop
> 
> This displays the file. But instead of displaying I would like to put
> the lines into an array.
> 
> Just keeping the values on the stack Like:
>     /buffer 80 string def
>     /inputFile INPUT (r) file def
>     {
>         inputFile buffer readline {
>             % Keep it on the stack
>         }{
>             pop
>             inputFile closefile
>             exit
>         } ifelse
>     } loop
>     stack
> 
> does not work, because the lower values are overwritten.
> 
> The first script gives:
>     They are not only idle who do nothing,
>     but they are idle also
>     who might be better employed.
> 
>     Socrates
> 
> While the second gives:
>     Socrates
> 
>     Socratest be better employed.
>     Socratest be better em
>     Socratest be better employed. nothing,
> 
> How would I get the lines correctly into an array?
> 

Chris's response is totally correct. But here's another way to do it.
You can slurp the whole file into one string (assuming the file size is less
than 65535 bytes), and then use `search` to chop it up.

%!
%farr.ps File into Array
/infile (farr.ps)(r)file def
infile dup bytesavailable string readstring pop
(\n){ search { 3 1 roll }{ exit } ifelse }loop
count array astore ==

gs output:

[(%!) (%farr.ps File into Array) (/infile \(farr.ps\)\(r\)file def) (infile
dup bytesavailable string readstring pop) (\(\\n\){ search { 3 1 roll }{
exit } ifelse }loop) (count array astore ==) ()]

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


#1132

FromCecil Westerhof <Cecil@decebal.nl>
Date2012-12-03 02:19 +0100
Message-ID<87r4n8nd8x.fsf@Compaq.site.inet>
In reply to#1129
Op zondag 2 dec 2012 22:31 CET schreef luser droog:

> Chris's response is totally correct. But here's another way to do it.
> You can slurp the whole file into one string (assuming the file size is less
> than 65535 bytes), and then use `search` to chop it up.
>
> %!
> %farr.ps File into Array
> /infile (farr.ps)(r)file def
> infile dup bytesavailable string readstring pop
> (\n){ search { 3 1 roll }{ exit } ifelse }loop
> count array astore ==
>
> gs output:
>
> [(%!) (%farr.ps File into Array) (/infile \(farr.ps\)\(r\)file def) (infile
> dup bytesavailable string readstring pop) (\(\\n\){ search { 3 1 roll }{
> exit } ifelse }loop) (count array astore ==) ()]

I already implemented Chris's way, but I'll look into this one also.

-- 
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof

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


#1134

From"luser.droog" <luser.droog@gmail.com>
Date2012-12-02 23:28 -0600
Message-ID<k9hdaa$7pf$1@dont-email.me>
In reply to#1132
Cecil Westerhof wrote:

> Op zondag 2 dec 2012 22:31 CET schreef luser droog:
> 
>> Chris's response is totally correct. But here's another way to do it.
>> You can slurp the whole file into one string (assuming the file size is
>> less than 65535 bytes), and then use `search` to chop it up.
>>
>> %!
>> %farr.ps File into Array
>> /infile (farr.ps)(r)file def
>> infile dup bytesavailable string readstring pop
>> (\n){ search { 3 1 roll }{ exit } ifelse }loop
>> count array astore ==
>>
>> gs output:
>>
>> [(%!) (%farr.ps File into Array) (/infile \(farr.ps\)\(r\)file def)
>> [(infile
>> dup bytesavailable string readstring pop) (\(\\n\){ search { 3 1 roll }{
>> exit } ifelse }loop) (count array astore ==) ()]
> 
> I already implemented Chris's way, but I'll look into this one also.
> 

No worries. Some caveats are you usually can't rely on `bytesavailable` for
terminal input or pipes, so you can only slurp a file where the size can be
discovered by the interpreter. And my use of `search` above left an empty
string. Adding `pop` just before `exit` will discard it.
And `count array astore` is just the innards of the `]` operator. Just
trying to show you some of the flexibility. And, as a rule, I try to avoid
multiline `{}{}ifelse` constructs because they nest so clumsily. A tight
little block like this I find much easier to read. And using `count` is
also an `assert(stack-is-empty-at-start-of-paragraph)`, cause clearly it
would be wrong if it weren't! :)

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


#1136

FromCecil Westerhof <Cecil@decebal.nl>
Date2012-12-03 10:01 +0100
Message-ID<87fw3no6gc.fsf@Compaq.site.inet>
In reply to#1134
Op maandag 3 dec 2012 06:28 CET schreef luser droog:

>>> Chris's response is totally correct. But here's another way to do it.
>>> You can slurp the whole file into one string (assuming the file size is
>>> less than 65535 bytes), and then use `search` to chop it up.
>>>
>>> %!
>>> %farr.ps File into Array
>>> /infile (farr.ps)(r)file def
>>> infile dup bytesavailable string readstring pop
>>> (\n){ search { 3 1 roll }{ exit } ifelse }loop
>>> count array astore ==
>>>
>>> gs output:
>>>
>>> [(%!) (%farr.ps File into Array) (/infile \(farr.ps\)\(r\)file def)
>>> [(infile
>>> dup bytesavailable string readstring pop) (\(\\n\){ search { 3 1 roll }{
>>> exit } ifelse }loop) (count array astore ==) ()]
>>
>> I already implemented Chris's way, but I'll look into this one also.
>>
>
> No worries. Some caveats are you usually can't rely on `bytesavailable` for
> terminal input or pipes, so you can only slurp a file where the size can be
> discovered by the interpreter. And my use of `search` above left an empty
> string. Adding `pop` just before `exit` will discard it.

I only use real files, so I can use bytesavailable.
I already implemented it. I now added the pop.

It was a lot of work. But I now have a better implementation as I had
with Image Magick (the graphic is always the right width), so it was
worth it. And I can implement other effects also.

-- 
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof

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


#2718

Fromluser droog <luser.droog@gmail.com>
Date2016-08-01 13:25 -0700
Message-ID<bb7c7717-e527-41ca-b264-ef2f9d3cb23e@googlegroups.com>
In reply to#1127
On Sunday, December 2, 2012 at 2:02:55 PM UTC-6, Cecil Westerhof wrote:
> I have the following script:
>     /buffer 80 string def
>     /inputFile INPUT (r) file def
>     {
>         inputFile buffer readline {
>             =
>         }{
>             pop
>             inputFile closefile
>             exit
>         } ifelse
>     } loop
> 
> This displays the file. But instead of displaying I would like to put
> the lines into an array.
> 
> Just keeping the values on the stack Like:
>     /buffer 80 string def
>     /inputFile INPUT (r) file def
>     {
>         inputFile buffer readline {
>             % Keep it on the stack
>         }{
>             pop
>             inputFile closefile
>             exit
>         } ifelse
>     } loop
>     stack
> 
> does not work, because the lower values are overwritten.
> 
> The first script gives:
>     They are not only idle who do nothing,
>     but they are idle also
>     who might be better employed.
> 
>     Socrates
> 
> While the second gives:
>     Socrates
> 
>     Socratest be better employed.
>     Socratest be better em
>     Socratest be better employed. nothing,
> 
> How would I get the lines correctly into an array?
> 

Sorry for bumping an old thread, but for the archive...
I have a very short bash script here which uses gs and
imagemagick which creates a "meme", an image superposed
with specified text, which was the larger goal of the
file-reading sub-task.
It takes arguments from the command-line, but the technique
should be readily adaptable to other configurations.
http://codegolf.stackexchange.com/questions/71375/dank-meme-generator/71388#71388

Earlier revisions are less "golfed" and easier to read:
http://codegolf.stackexchange.com/revisions/71388/1

Incidentally, the small file-slurping example I posted
in this thread (which I believe Cecil eventually used)
exhibits the same stackoverflow potential that is solved 
in John's code.

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


#2720

FromJohnF <john@please.see.sig.for.email.com>
Date2016-08-02 03:39 +0000
Message-ID<nnp4lg$5e1$1@reader2.panix.com>
In reply to#2718
luser droog <luser.droog@gmail.com> wrote:
> I have a very short bash script here which uses gs and
> imagemagick which creates a "meme", an image superposed
> with specified text, which was the larger goal of the
> file-reading sub-task.
> It takes arguments from the command-line, but the technique
> should be readily adaptable to other configurations.
> http://codegolf.stackexchange.com/questions/71375/dank-meme-generator/71388#71388

Thanks for the useful little script.
Your superman example in the stackexchange question looks fine.
But when I tried it on my own image
  http://www.forkosh.com/images/duckrabbit.jpg
as
  ./meme.sh duckrabbit.jpg "Duck" "Rabbit"
the originally-centered duckrabbit.jpg image got shrunk and put
in the lower-left corner of a much larger duckrabbit.jpg.png image,
with text centered top and bottom, but lots of unnecessary
(and unwanted) whitespace.
   I gave it ~five minutes, but couldn't make heads or tails
(or should I say ducks or rabbits) out of what's going on.
You have any quick understanding/solution? (Don't spend more
than five mins -- just not that important for me.) Thanks.

> Earlier revisions are less "golfed" and easier to read:
> http://codegolf.stackexchange.com/revisions/71388/1

-- 
John Forkosh  ( mailto:  j@f.com  where j=john and f=forkosh )

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


#2721

Fromluser droog <luser.droog@gmail.com>
Date2016-08-02 21:58 -0700
Message-ID<61d3b2d1-0318-4be3-959b-b955192dab31@googlegroups.com>
In reply to#2720
On Monday, August 1, 2016 at 10:39:30 PM UTC-5, JohnF wrote:
> luser droog <luser.droog@gmail.com> wrote:
> > I have a very short bash script here which uses gs and
> > imagemagick which creates a "meme", an image superposed
> > with specified text, which was the larger goal of the
> > file-reading sub-task.
> > It takes arguments from the command-line, but the technique
> > should be readily adaptable to other configurations.
> > http://codegolf.stackexchange.com/questions/71375/dank-meme-generator/71388#71388
> 
> Thanks for the useful little script.
> Your superman example in the stackexchange question looks fine.
> But when I tried it on my own image
>   http://www.forkosh.com/images/duckrabbit.jpg
> as
>   ./meme.sh duckrabbit.jpg "Duck" "Rabbit"
> the originally-centered duckrabbit.jpg image got shrunk and put
> in the lower-left corner of a much larger duckrabbit.jpg.png image,
> with text centered top and bottom, but lots of unnecessary
> (and unwanted) whitespace.
>    I gave it ~five minutes, but couldn't make heads or tails
> (or should I say ducks or rabbits) out of what's going on.
> You have any quick understanding/solution? (Don't spend more
> than five mins -- just not that important for me.) Thanks.
> 
> > Earlier revisions are less "golfed" and easier to read:
> > http://codegolf.stackexchange.com/revisions/71388/1

#!/bin/bash
filename=$1
toptext=$2
bottext=$3

dims=`identify $filename | cut -d' ' -f3`
dimx=`echo $dims | cut -d'x' -f1`
dimy=`echo $dims | cut -d'x' -f2`
convert $filename $filename.eps
gs -q -g"$dims" -o $filename.png -sDEVICE=png48 -c "
    /oldshowpage /showpage load def /showpage {} def
    ($filename.eps)run matrix defaultmatrix setmatrix
    /Helvetica-Bold 22 selectfont
    /ceshow {
        dup stringwidth pop neg 2 div 0 rmoveto
        dup gsave 1 setgray show grestore
        0 setgray false charpath stroke
    } def
    $dimx 2 div $dimy 42 sub moveto ($toptext) ceshow
    $dimx 2 div 8 moveto ($bottext) ceshow
oldshowpage "

echo Your meme is ready in $filename.png

Stupid MS Edge won't let me save the image. So while firing
up X, let me quote the readable version and offer my first 
guess that the black and white image produces a different
number of words from `identify` and so the dims are not
found in field 3. 

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


#2722

FromTonton Th <tTh@nowhere.invalid>
Date2016-08-03 05:10 +0000
Message-ID<slrnnq2v6f.2dr.tTh@hangartistique.cispeo.fr>
In reply to#2721
On 2016-08-03, luser droog <luser.droog@gmail.com> wrote:

> dims=`identify $filename | cut -d' ' -f3`

   dims=$(identify -format "%G" $filename)

> up X, let me quote the readable version and offer my first 
> guess that the black and white image produces a different
> number of words from `identify` and so the dims are not
> found in field 3. 

   http://www.imagemagick.org/script/escape.php

-- 
---- http://weblog.mixart-myrys.org/?post/2016/03/De-la-temporalisation ----

        I'm <tth> on freenode. Film at 11, take your popcorn.

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


#2723

Fromluser droog <luser.droog@gmail.com>
Date2016-08-02 22:20 -0700
Message-ID<c7f6de83-cb5c-4510-92f4-2844130c4a1c@googlegroups.com>
In reply to#2721
On Tuesday, August 2, 2016 at 11:58:10 PM UTC-5, luser droog wrote:
> On Monday, August 1, 2016 at 10:39:30 PM UTC-5, JohnF wrote:
> > luser droog <luser.droog@gmail.com> wrote:
> > > I have a very short bash script here which uses gs and
> > > imagemagick which creates a "meme", an image superposed
> > > with specified text, which was the larger goal of the
> > > file-reading sub-task.
> > > It takes arguments from the command-line, but the technique
> > > should be readily adaptable to other configurations.
> > > http://codegolf.stackexchange.com/questions/71375/dank-meme-generator/71388#71388
> > 
> > Thanks for the useful little script.
> > Your superman example in the stackexchange question looks fine.
> > But when I tried it on my own image
> >   http://www.forkosh.com/images/duckrabbit.jpg
> > as
> >   ./meme.sh duckrabbit.jpg "Duck" "Rabbit"
> > the originally-centered duckrabbit.jpg image got shrunk and put
> > in the lower-left corner of a much larger duckrabbit.jpg.png image,
> > with text centered top and bottom, but lots of unnecessary
> > (and unwanted) whitespace.
> >    I gave it ~five minutes, but couldn't make heads or tails
> > (or should I say ducks or rabbits) out of what's going on.
> > You have any quick understanding/solution? (Don't spend more
> > than five mins -- just not that important for me.) Thanks.
> > 
> > > Earlier revisions are less "golfed" and easier to read:
> > > http://codegolf.stackexchange.com/revisions/71388/1
> 
> #!/bin/bash
> filename=$1
> toptext=$2
> bottext=$3
> 
> dims=`identify $filename | cut -d' ' -f3`
> dimx=`echo $dims | cut -d'x' -f1`
> dimy=`echo $dims | cut -d'x' -f2`
> convert $filename $filename.eps
> gs -q -g"$dims" -o $filename.png -sDEVICE=png48 -c "
>     /oldshowpage /showpage load def /showpage {} def
>     ($filename.eps)run matrix defaultmatrix setmatrix
>     /Helvetica-Bold 22 selectfont
>     /ceshow {
>         dup stringwidth pop neg 2 div 0 rmoveto
>         dup gsave 1 setgray show grestore
>         0 setgray false charpath stroke
>     } def
>     $dimx 2 div $dimy 42 sub moveto ($toptext) ceshow
>     $dimx 2 div 8 moveto ($bottext) ceshow
> oldshowpage "
> 
> echo Your meme is ready in $filename.png
> 
> Stupid MS Edge won't let me save the image. So while firing
> up X, let me quote the readable version and offer my first 
> guess that the black and white image produces a different
> number of words from `identify` and so the dims are not
> found in field 3.

Weird. That isn't the problem at all. The  eps is getting a 
smaller sized version.

josh@LAPTOP-ILO10OOF ~/meme
$ identify duckrabbit.jpg 
duckrabbit.jpg JPEG 519x350 519x350+0+0 8-bit sRGB 39.3KB 0.031u 0:00.027

josh@LAPTOP-ILO10OOF ~/meme
$ grep BoundingBox duckrabbit.jpg.eps
%%BoundingBox: -0 -0 187 126
%%HiResBoundingBox: 0 0 186.84 126
%%PageBoundingBox: 0 0 187 126

If the script were to get the dims with something like

convert $1 $1.eps
dims=`grep %%BoundingBox $1.eps`
x=`echo $dims| cut -d' ' -f4`
y=`echo $dims| cut -d' ' -f5`

that should get the right numbers to gs.

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


Page 1 of 2  [1] 2  Next page →

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


csiph-web