Hi All, I'm trying to create a command that will apply a consistent style to a word or phrase. For example, when documenting source code, I'd like to be able to mark variables with \Var{var_name}. Then if I want the variable names to be in mono, I can \def\Var#1{\type{#1}}. No problem there. If I want variable names to be in quotes, then \def\Var#1{\quote{#1}}. The problem is that in my ConTeXt code I'd write "This is \Var{var_name}, a variable." Which would get typeset as "This is 'var_name', a variable." where punctuation convention (at least in American English) would have the comma inside the quote like this: "This is 'var_name,' a variable." I've tried four different ways of implementing this, but none of them work consistently. Here's my last attempt: ========================== \startluacode function move_end_punctuation (text, punc, cmd_start, cmd_mid, cmd_end) context(cmd_start .. text .. cmd_mid) if string.find('.,!?', punc, 1, true) then context(punc .. cmd_end) else context(cmd_end .. ' ' .. punc) end end \stopluacode \def\Var#1#2{\ctxlua{move_end_punctuation([==[#1]==],[==[#2]==], '\\quote{\\type{','}','}')}} \starttext This is \Var{var_name}, a variable. \stoptext ========================== This works, until the \Var{} macro appears in the argument of another macro. For example, make the text: \framed{This is \Var{var_name}, a variable.} and the following error results: ========================== systems : begin file test.tex at line 16 ! Missing $ inserted. <inserted text> $ <to be read again> _ l.1 ...spaces quote{unskip ignorespaces type{var_ name} \Var ...=],[==[#2]==], '\\quote{\\type{','}','}')} l.18 \framed{This is \Var{var_name}, a variable.} ? ========================== I think my problem has to do with parameter expansion, but I don't understand the intricacies enough to solve this. I flailed away, unsuccessfully, with various combinations of \unexpanded, \normalunexpanded, luaescapestring, etc. Does anyone have a solution or a pointer in the right direction? Thank you, Tad
Am 08.01.2010 um 17:27 schrieb Tad Ashlock:
Hi All,
I'm trying to create a command that will apply a consistent style to a word or phrase. For example, when documenting source code, I'd like to be able to mark variables with \Var{var_name}. Then if I want the variable names to be in mono, I can \def\Var#1{\type{#1}}. No problem there. If I want variable names to be in quotes, then \def\Var#1{\quote{#1}}.
The problem is that in my ConTeXt code I'd write "This is \Var{var_name}, a variable." Which would get typeset as "This is 'var_name', a variable." where punctuation convention (at least in American English) would have the comma inside the quote like this: "This is 'var_name,' a variable."
I've tried four different ways of implementing this, but none of them work consistently. Here's my last attempt:
========================== \startluacode function move_end_punctuation (text, punc, cmd_start, cmd_mid, cmd_end) context(cmd_start .. text .. cmd_mid) if string.find('.,!?', punc, 1, true) then context(punc .. cmd_end) else context(cmd_end .. ' ' .. punc) end end \stopluacode
\def\Var#1#2{\ctxlua{move_end_punctuation([==[#1]==],[==[#2]==], '\\quote{\\type{','}','}')}}
\starttext
This is \Var{var_name}, a variable.
\stoptext ==========================
This works, until the \Var{} macro appears in the argument of another macro. For example, make the text:
\framed{This is \Var{var_name}, a variable.}
and the following error results: ========================== systems : begin file test.tex at line 16 ! Missing $ inserted. <inserted text> $ <to be read again> _ l.1 ...spaces quote{unskip ignorespaces type{var_ name} \Var ...=],[==[#2]==], '\\quote{\\type{','}','}')} l.18 \framed{This is \Var{var_name}, a variable.} ? ==========================
I think my problem has to do with parameter expansion, but I don't understand the intricacies enough to solve this. I flailed away, unsuccessfully, with various combinations of \unexpanded, \normalunexpanded, luaescapestring, etc.
Does anyone have a solution or a pointer in the right direction?
\nonknuthmode % make '_' a normal character in text mode \define[1]\Var {\doifnextcharelse{,}{\doVar{#1,}\gobbleoneargument}{\noVar{#1}}} \define[1]\doVar {\mono{#1}} \define[1]\noVar {\mono{#1}% \doifnextcharelse{;} % \autoinsertnextspace is no longer available in MkIV :( {\donothing} {\doifnextcharelse{.} {\donothing} {\space}}} \starttext This is \Var{var_name}, a variable. This is \Var{var_name,} a variable. \framed{This is \Var{var_name}, a variable.} \stoptext Wolfgang
Wolfgang Schuster wrote:
Am 08.01.2010 um 17:27 schrieb Tad Ashlock:Hi All,
======================== \startluacode function move_end_punctuation (text, punc, cmd_start, cmd_mid, cmd_end) context(cmd_start .. text .. cmd_mid) if string.find('.,!?', punc, 1, true) then context(punc .. cmd_end) else context(cmd_end .. ' ' .. punc) end end \stopluacode
\def\Var#1#2{\ctxlua{move_end_punctuation([=#1]==],[==[#2]==], '\\quote{\\type{','}','}')}}
\starttext
This is \Var{var_name}, a variable.
\stoptext ========================
This works, until the \Var{} macro appears in the argument of another macro. For example, make the text:
\framed{This is \Var{var_name}, a variable.}
\nonknuthmode % make '_' a normal character in text mode
\define[1]\Var {\doifnextcharelse{,}{\doVar{#1,}\gobbleoneargument}{\noVar{#1}}}
\define[1]\doVar {\mono{#1}}
\define[1]\noVar {\mono{#1}% \doifnextcharelse{;} % \autoinsertnextspace is no longer available in MkIV :( {\donothing} {\doifnextcharelse{.} {\donothing} {\space}}}
\starttext
This is \Var{var_name}, a variable.
This is \Var{var_name,} a variable.
\framed{This is \Var{var_name}, a variable.}
\stoptext
Wolfgang
Thanks for responding Wolfgang. But this solution has some problems. The first problem is that it only works for commas. I'm sure I can figure out how to next the \doifnextcharelse commands to add periods, question marks, and exclamation points, but then the command becomes rather unwieldy. Not really a problem for a single command, but this leads to... Problem number 2 is that I'm going to need many of these commands for different types of things. I'd like to abstract out the "punctuation swapping" so that it doesn't have to be repeated for each command. But the show-stopper is problem number 3: this solution still breaks in other places, like captions: ======================== \starttext \placefigure [left] {This is \Var{var_name}, a variable.} {\framed{And \Var{another_var_name} is yet another variable.}} \stoptext ======================== results in: ========================
! Argument of \gobbleoneargument has an extra }. <inserted text> \par <to be read again> } \doifnextcharelse ...token =#1\def \!!stringa {#2} \def \!!stringb {#3}\futur... \@@kjfiguretitle ->This is \Var {var_name} , a variable. \doif #1#2->\edef \!!stringa {#1 }\edef \!!stringb {#2}\ifx \!!stringa \!!str... \dostructurecountercomponent ...\c!title }\v!none {\setfalse \hasstructureco... ... l.47 ...other_var_name} is yet another variable.}}
? ========================
This is the sort of problem I was flailing around with. I'd get a definition that worked in one case, but broke in another. One attempt broke when I included a table of contents. Thanks again! Tad
What about: \def\Var#1#2{'\type{#1}% \directlua{ if "#2" == "," then tex.sprint("#2'") else tex.sprint("'#2") end}} \Var{555}, hello \Var{666}. \Var{666}\par On Fri, Jan 08, 2010 at 09:27:37AM -0700, Tad Ashlock wrote:
Hi All,
I'm trying to create a command that will apply a consistent style to a word or phrase. For example, when documenting source code, I'd like to be able to mark variables with \Var{var_name}. Then if I want the variable names to be in mono, I can \def\Var#1{\type{#1}}. No problem there. If I want variable names to be in quotes, then \def\Var#1{\quote{#1}}.
The problem is that in my ConTeXt code I'd write "This is \Var{var_name}, a variable." Which would get typeset as "This is 'var_name', a variable." where punctuation convention (at least in American English) would have the comma inside the quote like this: "This is 'var_name,' a variable."
I've tried four different ways of implementing this, but none of them work consistently. Here's my last attempt:
========================== \startluacode function move_end_punctuation (text, punc, cmd_start, cmd_mid, cmd_end) context(cmd_start .. text .. cmd_mid) if string.find('.,!?', punc, 1, true) then context(punc .. cmd_end) else context(cmd_end .. ' ' .. punc) end end \stopluacode
\def\Var#1#2{\ctxlua{move_end_punctuation([==[#1]==],[==[#2]==], '\\quote{\\type{','}','}')}}
\starttext
This is \Var{var_name}, a variable.
\stoptext ==========================
This works, until the \Var{} macro appears in the argument of another macro. For example, make the text:
\framed{This is \Var{var_name}, a variable.}
and the following error results: ========================== systems : begin file test.tex at line 16 ! Missing $ inserted. <inserted text> $ <to be read again> _ l.1 ...spaces quote{unskip ignorespaces type{var_ name} \Var ...=],[==[#2]==], '\\quote{\\type{','}','}')} l.18 \framed{This is \Var{var_name}, a variable.} ? ==========================
I think my problem has to do with parameter expansion, but I don't understand the intricacies enough to solve this. I flailed away, unsuccessfully, with various combinations of \unexpanded, \normalunexpanded, luaescapestring, etc.
Does anyone have a solution or a pointer in the right direction?
Thank you, Tad
___________________________________________________________________________________ If your question is of interest to others as well, please add an entry to the Wiki!
maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context webpage : http://www.pragma-ade.nl / http://tex.aanhet.net archive : http://foundry.supelec.fr/projects/contextrev/ wiki : http://contextgarden.net ___________________________________________________________________________________
-- Khaled Hosny Arabic localiser and member of Arabeyes.org team Free font developer
Khaled Hosny wrote:
On Fri, Jan 08, 2010 at 09:27:37AM -0700, Tad Ashlock wrote:
========================== \startluacode function move_end_punctuation (text, punc, cmd_start, cmd_mid, cmd_end) context(cmd_start .. text .. cmd_mid) if string.find('.,!?', punc, 1, true) then context(punc .. cmd_end) else context(cmd_end .. ' ' .. punc) end end \stopluacode
\def\Var#1#2{\ctxlua{move_end_punctuation([==[#1]==],[==[#2]==], '\\quote{\\type{','}','}')}}
\starttext
This is \Var{var_name}, a variable.
\stoptext ==========================
What about:
\def\Var#1#2{'\type{#1}% \directlua{ if "#2" == "," then tex.sprint("#2'") else tex.sprint("'#2") end}}
\Var{555}, hello \Var{666}. \Var{666}\par
Thank you, Khaled, for the response. This solution works as is. But it has a problem as soon as you want to put double quotes around the variable name. Simply replacing the single quotes with double quotes in your solution doesn't produce open- and close-quotes pairs: ================== \def\Var#1#2{"\type{#1}% \directlua{ if "#2" == "," then tex.sprint('#2"') else tex.sprint('"#2') end}} ================== In order to do that, you need (I think) to use the \quotation{} command: ================== \def\Var#1#2{\quotation{\type{#1}% \directlua{ if "#2" == "," then tex.sprint("#2}") else tex.sprint("}#2") end}} ================== resulting in: ================== ! Too many }'s. l.7 end}} ================== I also tried \bgroup...\egroup: ================== \def\Var#1#2{\quotation\bgroup\type{#1}% \directlua{ if "#2" == "," then tex.sprint("#2\egroup ") else tex.sprint("\egroup #2") end}} ================== giving: ================== ! Missing } inserted. <inserted text> } <to be read again> \normalend l.18 \stoptext ================== Thanks again! Tad
participants (3)
-
Khaled Hosny
-
Tad Ashlock
-
Wolfgang Schuster