Tinderbox User-to-User Forum (for formal tech support please email: info@eastgate.com)
http://www.eastgate.com/Tinderbox/forum//YaBB.cgi
Tinderbox Users >> Exporting from Tinderbox >> runCommand and single quotes in exports
http://www.eastgate.com/Tinderbox/forum//YaBB.cgi?num=1223700471

Message started by Nate Eagleson on Oct 11th, 2008, 12:47am

Title: runCommand and single quotes in exports
Post by Nate Eagleson on Oct 11th, 2008, 12:47am

Hi folks.

I've just been working on an export template that generates SQL for a MySQL database.

This is pretty straightforward - I've done some pretty complex templating in the past on various templating systems, and Tbox templates are straightforward enough.

However, I wanted to escape single quote characters in the text of certain notes, as per MySQL's standard behavior - '' represents a single quote inside a string, since ' is the string delimiter.

By using ^value(), I found it was possible to embed the results of runCommand() in an export template, which I figured was perfect - I could just use sed to find/replace the single quotes.

At a bash prompt, the following sed command did what I wanted:


Code:
sed -e s/\'/\'\'/g < test.txt


where test.txt had some sample text to be escaped.

So, I tried the following line in my export template:


Code:
^value(runCommand("sed -e s/\'/\'\'/g", $Text(this)))


However, when I previewed this, it output nothing.

After some head-scratching and confusion, I found that expressions without single quotes, like


Code:
^value(runCommand("sed -e s/a/4/g", $Text(this)))


did what I expected. Further experimentation seemed to indicate that Tinderbox was parsing the single quotes in some way that caused sed to choke on them.

Poking around Google and this forum, looking for advice and/or things I might be overlooking, I found the code in the post at http://www.eastgate.com/Tinderbox/forum//YaBB.pl?num=1215890864/6#6, which clearly used single quotes and sed in runCommand, and worked fine. I noticed, though, that it wasn't being used in a template, and that he recommended storing the command string in a note, for reusability.

Out of curiosity, I tried putting this text:


Code:
sed -e s/\'/\'\'/g


in a note named 'escape_quotes'. I then updated my template to use the line


Code:
^value(runCommand($Text(escape_quotes), $Text(this)))


which had the result I would have expected from my first attempt - single quotes in the note's text were doubled.

So, my question is, why doesn't the first example, which works at a prompt, work in a Tbox export template? Is there some subtlety I'm missing about exports and single quotes, or maybe the way Tinderbox handles runCommand()? I've looked through the manual a bit for an explanation and couldn't find one, but maybe I just missed it.

In case it's relevant, I'm using Tinderbox 4.0.2 on OS X 10.5.5, on a PowerBook G4.

(on a side note, having runCommand available in templates seems like it should allow for some really cool tricks. I haven't needed more power in templates than Tbox offers yet, but it would seem to allow for pretty arbitrary extension of Tbox templates if you needed it.)

-Nate

Title: Re: runCommand and single quotes in exports
Post by Mark Anderson on Oct 11th, 2008, 7:38am

You need to escape your escapes as the string is double-processed by \-escape aware process: first TB itself, then the command line. IIRC - not time to test now - you need to to use either 2 or 4 backslashes where your actual command line uses one. I describe this is the forum thread to which you linked.

Title: Re: runCommand and single quotes in exports
Post by Nate Eagleson on Oct 11th, 2008, 8:04am

I had tried multiple levels of escaping, but it hadn't worked for me - I also hadn't mentioned it, since I was trying to minimize the size of my test case.

I just now tried double backslashes

Code:
^value(runCommand("sed -e s/\\'/\\'\\'/g", exportedString(this, "^text^")))


which rendered as an empty string, and then quadruple

Code:
^value(runCommand("sed -e s/\\\\'/\\\\'\\\\'/g", exportedString(this, "^text^")))


which also rendered as an empty string.

Any other thoughts?

-Nate

Title: Re: runCommand and single quotes in exports
Post by Mark Bernstein on Oct 11th, 2008, 10:50am

Both Tinderbox and the shell treat quotes and backslashes as special characters; as you observe, getting everyone to play nicely together can be a headache!

You can avoid the whole bother by saving your one-liner sed command (or, if you wanted, awk or perl or ruby) in a file.  Then, invoke that file, and all will be fine.

Title: Re: runCommand and single quotes in exports
Post by Mark Anderson on Oct 11th, 2008, 12:44pm

Aha, if I recall, Mark B's suggestion was how I came to put the CL into a note in examples elsewhere in the forum. The CL was made a script (file) but to make the solution portable, I 'stored' the script file as the text of a TB note rather than as a separate file in the OS.  Whether external script file or sourced from a TB note, both have the same effect in terms of reducing  the issue of escaping quotes.

Title: Re: runCommand and single quotes in exports
Post by Nate Eagleson on Oct 11th, 2008, 1:18pm

Okay, thanks for the explanations - I really just wanted to make sure I wasn't missing anything, and to document this for anyone else who might run into the same problems.

The solutions work just fine, and are in some ways better than inlining it - it just wasn't immediately obvious to me what was going on, so I figured I'd double-check, and hopefully make someone else's life easier while I was at it.

Thanks again.

-Nate

Tinderbox User-to-User Forum (for formal tech support please email: info@eastgate.com) » Powered by YaBB 2.2.1!
YaBB © 2000-2008. All Rights Reserved.