Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.postscript > #1127 > unrolled thread
| Started by | Cecil Westerhof <Cecil@decebal.nl> |
|---|---|
| First post | 2012-12-02 21:02 +0100 |
| Last post | 2016-08-22 22:31 -0700 |
| Articles | 20 on this page of 24 — 8 participants |
Back to article view | Back to comp.lang.postscript
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 →
| From | Cecil Westerhof <Cecil@decebal.nl> |
|---|---|
| Date | 2012-12-02 21:02 +0100 |
| Subject | Putting 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]
| From | Chris <cjl@spamcop.net> |
|---|---|
| Date | 2012-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]
| From | Cecil Westerhof <Cecil@decebal.nl> |
|---|---|
| Date | 2012-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]
| From | Don Lancaster <don@tinaja.com> |
|---|---|
| Date | 2012-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]
| From | "luser.droog" <luser.droog@gmail.com> |
|---|---|
| Date | 2012-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]
| From | John Deubert <john@acumentraining.com> |
|---|---|
| Date | 2012-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]
| From | "luser.droog" <luser.droog@gmail.com> |
|---|---|
| Date | 2012-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]
| From | Chris <cjl@spamcop.net> |
|---|---|
| Date | 2012-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]
| From | John Deubert <john@acumentraining.com> |
|---|---|
| Date | 2012-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]
| From | Chris <cjl@spamcop.net> |
|---|---|
| Date | 2012-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]
| From | Cecil Westerhof <Cecil@decebal.nl> |
|---|---|
| Date | 2012-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]
| From | "luser.droog" <luser.droog@gmail.com> |
|---|---|
| Date | 2012-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]
| From | Cecil Westerhof <Cecil@decebal.nl> |
|---|---|
| Date | 2012-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]
| From | "luser.droog" <luser.droog@gmail.com> |
|---|---|
| Date | 2012-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]
| From | Cecil Westerhof <Cecil@decebal.nl> |
|---|---|
| Date | 2012-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]
| From | luser droog <luser.droog@gmail.com> |
|---|---|
| Date | 2016-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]
| From | JohnF <john@please.see.sig.for.email.com> |
|---|---|
| Date | 2016-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]
| From | luser droog <luser.droog@gmail.com> |
|---|---|
| Date | 2016-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]
| From | Tonton Th <tTh@nowhere.invalid> |
|---|---|
| Date | 2016-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]
| From | luser droog <luser.droog@gmail.com> |
|---|---|
| Date | 2016-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