Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

Replacing placeholders?

 [1/11] from: kpeters:otaksoft at: 7-Aug-2007 11:30


Hi ~ I am trying to use pdfmaker to perform a mail-merge mailout. I have created a file holding the dialect code for the letter template: thankyou-letter: [ [ ; the one & only page page size 216 279 ; US letter textbox [ { Dear $NAME, thank you so much for your generous donation.} p { And some more text - maybe the same placeholder multiple times $NAME ...} ] ] ] All this up to creating the PDF works well. I am struggling with this: How can i replace all instances of placeholders like $NAME in thankyou-letter with the mailmerge variables? Thanks for any help, Kai

 [2/11] from: carlos:lorenz:g:mail at: 7-Aug-2007 15:46


Hi Kai, Maybe this old mail from Tim may help you. Take a look:
>>>
Here's an example of dynamically composing a PDF document using records: ;; ====================================================== do %pdf-maker.r records: [ [first_name "Tim" last_name "Johnson"] [first_name "Gabriele" last_name "Santilli"] ] build-page: func[record[block!]][ blue-font: [FONT Courier 4.23 0.0.200] black-font: [FONT Helvetica 4.23 0.0.0] ;; Place any code that you want evaluated inside of parenthesis [ ;; Each page must be a block textbox[ LEFT ALIGN (blue-font) "First Name: " (black-font) (record/first_name) newline (blue-font) "Last Name: " (black-font) (record/last_name) newline ] ] ] ;; make block for the document document: make block! length? records ;; Process records foreach record records[ ;; Use 'compose to evaluate the code and data ;; inside of the parens in the 'page block page: compose/deep build-page record ;; append as a block append/only document page ] write/binary %pdf-test.pdf layout-pdf document ;; ====================================================== It's my hope that someone else may find this as helpful as it was for me in doing it. And as always - thanks to Gabrielle for his good work. cheers Tim
>>>>>
2007/8/7, Kai Peters <kpeters-otaksoft.com>:
> Hi ~ > I am trying to use pdfmaker to perform a mail-merge mailout.
<<quoted lines omitted: 19>>
> To unsubscribe from the list, just send an email to > lists at rebol.com with unsubscribe as the subject.
-- Carlos Lorenz www.revistaeletronica.com.br Unidade Lorenz Ltda (11) 4034 1971

 [3/11] from: kpeters::otaksoft::com at: 7-Aug-2007 12:53


Carlos ~ thank you so much for this - this would have been the next step for me to wrestle with! Now that I have seen this code, my ultimate goal is to be able to do this: Have the actual "page content" made "load"able from an external file In Tim's code this would be this section (I believe): textbox[ LEFT ALIGN (blue-font) "First Name: " (black-font) (record/first_name) newline (blue-font) "Last Name: " (black-font) (record/last_name) newline ] } and pass it on to build-page as an additional parameter. This should add a lot of flexibility as it separates the actual PDF definitions from the code. I have just tried in vain to achieve this as I somehow always end up with empty PDFs or worse.... Would you be able to advise me once more? TIA, Kai

 [4/11] from: carlos:lorenz:g:mail at: 8-Aug-2007 15:15


Kai, I am afraid a cannot go further on advising you since I am not a heavy user of pdf-maker. Anyway are you using COMPOSE to evaluate data and surrounding them with parens as Tim said?
>> Timīs code
;; Process records foreach record records[ ;; Use 'compose to evaluate the code and data ;; inside of the parens in the 'page block page: compose/deep build-page record ;; append as a block append/only document page ] 2007/8/7, Kai Peters <kpeters-otaksoft.com>:
> Carlos ~ > thank you so much for this - this would have been the next step for me
<<quoted lines omitted: 22>>
> To unsubscribe from the list, just send an email to > lists at rebol.com with unsubscribe as the subject.
-- Carlos Lorenz www.revistaeletronica.com.br Unidade Lorenz Ltda (11) 4034 1971

 [5/11] from: tim-johnsons::web::com at: 8-Aug-2007 12:15


On Wednesday 08 August 2007, Carlos Lorenz wrote:
> Kai, > > I am afraid a cannot go further on advising you since I am not a heavy user > of pdf-maker. > Anyway are you using COMPOSE to evaluate data and surrounding them with > parens as Tim said?
<blush> I've been extremely busy here and I've got a little time for this - first - a disclaimer - I whipped up that code in preperation for implementing it for a client. But my partner ended doing the functionality with perl. Furthermore, I've deleted much of *this* thread from my mailer. Let me suggest that you just play with compose for a bit, without your target in mind. Just a have a bit of fun with it. What compose allows you to do is to create a data structure, evaluate it as much as you like and change values within that data structure targeted by parenthesis. Since I am not myself an expert with compose, and if I don't write rebol for a week, I get behind the curve even more, let me propose a problem and perhaps the solution will edify me and help you: Here's the problem, define a block with a parenthesized word and evaluate it as a place holder names: ["Tim" "Carlos" "Kai"] == ["Tim" "Carlos" "Kai"]
>> template: [My name is (name)]
== [My name is (name)]
>> foreach name names[print compose template]
** Script Error: name has no value ** Near: name ;; I *don't* know the solution myself, but finding it will be most helpful for ;; both of us cheers tim

 [6/11] from: tim-johnsons:web at: 8-Aug-2007 13:03


On Wednesday 08 August 2007, Tim Johnson wrote:
> Here's the problem, define a block with a parenthesized word and evaluate > it as a place holder
<<quoted lines omitted: 7>>
> ;; I *don't* know the solution myself, but finding it will be most helpful > for ;; both of us
:-) Oh, I couldn't help myself: solution is:
>> foreach name names[bind template 'name print form compose template]
My name is Tim My name is Carlos My name is Kai ---- Tim

 [7/11] from: kpeters:otaksoft at: 8-Aug-2007 14:14


Thanks for that one - no way that this newbie here would have figured this out anytime soon... If that's what you refer to as "getting behind the curve.." you must be fishing for compliments :) Well, at least I learned one little (unrelated) detail from your exercise: Having a word previously defined with the same name as the implicit loop variable overshadows the loop variable (forgive me if this terminology is not Rebol proper) Kai On Wed, 8 Aug 2007 13:03:18 -0800, Tim Johnson wrote:

 [8/11] from: tim-johnsons:web at: 8-Aug-2007 15:09


On Wednesday 08 August 2007, Kai Peters wrote:
> Thanks for that one - no way that this newbie here would have figured this > out anytime soon... > > If that's what you refer to as "getting behind the curve.." you must be > fishing for compliments :)
No. I code in several languages. When I get away from rebol for a while, my "reb-Q" drops.
> Well, at least I learned one little (unrelated) detail from your exercise: > > Having a word previously defined with the same name as the implicit loop > variable > overshadows the loop variable (forgive me if this terminology is not Rebol > proper)
There is a term called "shadowing" - used in scheme and lisp, but: see this:
>> names
== ["Tim" "Carlos" "Kai"]
>> key: "George"
== "George"
>> foreach key names[print key]
Tim Carlos Kai
>> key
== "George" ;; 'key has scope local to the 'foreach loop, ;; no shadowing here. Tim

 [9/11] from: Tom:Conlin:gma:il at: 8-Aug-2007 18:36


Tim Johnson wrote:
> On Wednesday 08 August 2007, Carlos Lorenz wrote: >> Kai,
<<quoted lines omitted: 27>>
> cheers > tim
names: ["Tim" "Carlos" "Kai"] template: [My name is (first names)] while[not tail? names][probe compose template names: next names] [My name is "Tim"] [My name is "Carlos"] [My name is "Kai"] == [] names: head names while[not tail? names][print form compose template names: next names] My name is Tim My name is Carlos My name is Kai == []
>>

 [10/11] from: kpeters:otaksoft at: 8-Aug-2007 21:11


Tim ~ my "overshadowing" assumption was wrongly based on output below Kai
>> names: [ "tim" "carlos" "kai" ]
== ["tim" "carlos" "kai"]
>> template: [ "My name is " (name) ]
== ["My name is " (name)]
>> foreach name names [ print compose template ]
** Script Error: name has no value ** Where: halt-view ** Near: name
>> >> >> name: "Joe"
== "Joe"
>> foreach name names [ print compose template ]
My name is Joe My name is Joe My name is Joe
>>
On Wed, 8 Aug 2007 15:09:33 -0800, Tim Johnson wrote:

 [11/11] from: tim-johnsons:web at: 9-Aug-2007 12:07


On Wednesday 08 August 2007, Kai Peters wrote:
> Tim ~ > > my "overshadowing" assumption was wrongly based on output below >
Rebol's approach to scope can be problematic, especially in large applications. Example: ;; global value (not inside of a function) username: "Kai" ;; used for all kinds of things in large application scopekiller: func[uname[string!] /local user][ username: uname ;; OOPS! typo with unpredicable consequences ] scopekiller "Tim" ;; username is now me :-) This is where 'protect can be your friend. username: "Kai" protect 'username and: ;;use 'unprotect before resetting a 'protect'ed global word. unprotect 'username username: "Tim" ;;;;;;;;;;;;;; I also use global words as part of an object, this has a tendency to lessen typos. glbs: context[unsername: "Kai"] glbs/username: "Tim" tim

Notes
  • Quoted lines have been omitted from some messages.
    View the message alone to see the lines that have been omitted