(re:3a) the code in note 3a has a missing quote. Here's a fix:
Code:
changequote`'
define(askUser,enter pattern: `pushdef(userParam,esyscmd({ read a;echo $a;}))')dnl
-----
The previous version of the userParam_ macro only allows
single strings (without whitespace) to be entered as input.
3c. So, use this version of the userParam_ macro to match
any number of whitespace separated strings as valid input:
Code:
pushdef(userParam_,`translit(userParam,userParam,regexp(userParam,`^\(.*\).\(.*\)*$',`\0 \1'))')
userParam_
Discussion:
..This method is better than the previous userParam_, since
it allows you to enter input like:
"abracadabra w00w b1b2 dcd3"
Daniel.On Thu, Jul 21, 2011 at 7:22 AM, daniel daniel
<address@hidden> wrote:
..to get the newline out of the input
here's a trick I brewed using regexp and translit:
3a. Say the user enters their input, and you capture/store input
using the said method (so a macro `userParam' gets defined with
the input -- but, as of yet, it contains the newline):
define(askUser,enter pattern: [pushdef(userParam,esyscmd({ read a;echo $a;}))dnl
askUser()
3b. So, use the following code to strip the newline, and store
the value without the newline in a macro `userParam_':
define(userParam_,[translit(userParam,userParam,regexp(userParam,[[^]\(\w\)\n[$]],[\0 ]))])
This method also allows you to get around the single-line nature of regexp().
Daniel.On Thu, Jul 21, 2011 at 3:54 AM, daniel daniel
<address@hidden> wrote:
Here is a neat m4 hack I've come up with to capture user input from within m4.
There are two variations I propose to capture user input:
1. The first method captures user input from the shell, exploiting pipelines
from the shell and how this relates to /dev/fd/0:
Code:
dnl call this file m4stdin.m4
pushdef(userParam,`include(/dev/fd/0)')
eval(userParam+1)
Discussion:
Given the shell command: { echo 1|m4 m4stdin.m4;}
the output will be: 2
2. The second method exploits the `read' shell builtin command:
Code:
changequote([,])
define(askUser,enter A or B: [pushdef(userParam,esyscmd({ read a;echo $a;}))dnl
ifelse(userParam,[A
],[include(110721m4a.m4)],dnl
ifelse(userParam,[B
],[include(110721m4b.m4)]))][popdef([userParam])])dnl
askUser()
Discussion:
on running this code, the user will be prompted with the text: "enter A or B: "
the user will then type either an A or a B; then, in this example, i've implemented
conditional file inclusion (i.e., if the user inputs A, then 110721m4a.m4 will be
evaluated; if the user inputs B, then 110721m4b.m4 will be included and evaluated.)
;P
Daniel.