This is similar to what
embperl,
eperl and other
"embedded Perl" meta-languages do. They might be a better
choice than rolling your own, so it is certainly advised
to check into them first.
Back to the code you posted. I'm not sure that it will work
outside of your carefully constructed and manicured test
environment. I would suggest taking a "hands-off" approach
to the whole parsing thing and let Perl do that for you.
If I understand your requirements correctly, you are saying
that you have an arbitrary function "f()" which you want
to use in your code by inserting something along the lines
of "<?f(...)?>" This text would be replaced with the
result of that function call.
In your code you make reference to something called
"Function()" but the actual Perl code refers to
"some_param_stuff()" which is likely to be very confusing
if you add more than one function. Keeping them the same
would help improve readability substantially.
If you have control over the input data from the file,
meaning that no "unauthorized" users will be able to insert
potentially malicious code, you can implement this very
quickly using a small amount of code. The key is getting the
regexp right, and although confidence is high in the utility
of the one below, I am certain it could be improved.
sub Reformat
{
local ($_) = shift;
my ($out) = '';
while (/<\?([A-Za-z_][A-Za-z0-9_]*\s*\(
(?:
(?:
(?:"(\\"|[^"])*?") |
(?:'(\\'|[^'])*?') |
\)(?!\s*\?\>) |
(?:[^'"\)]+)
)*?
)
\))\s*\?>/sx)
{
$out .= $`;
$_ = $';
$out .= eval $1;
}
$out .= $_;
return $out;
}
You'll note that this passes any code you put into your
document into the eval() directly, without any checks.
Obviously you will not want just anyone putting code in
these documents.
Since this is using the Perl interpreter, you can put all
sorts of stuff in the tag and it should work out fine. The
regexp catches single and double quoted strings, which will
prevent the parser from terminating prematurely on a
quoted ")?>", for example. Support for "qq()" could be
added as well, but this may be extraneous considering your
application.
Additionally, the result of the eval() may be undef, and the tag
will disappear from your document without a trace. A
simple modification could help you:
$out .= eval $1;
$out .= "<!-- $@ -->" if $@;
This will, at least, put some error information in the
output should something go horribly wrong during processing.
To use this, you would define functions in your parse program
that could be accessed by the script. If you wanted to limit
the functions used by this to a package, at least in a casual
sense, you could always do this:
$out .= eval "MyPackage::$1";
This would force all function calls into the desired package,
however, it would not prevent something like this from
appearing in your code:
Something about <?account_name(uc("foo"))?>:
"uc()" will be called in the main package space unless
explicitly specified otherwise.
I hope that's in line with what you were looking for.
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
| |
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.