Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Implemented XML text escaping, and 'structure' keyword.

  • Loading branch information...
commit ed24b24adfd4fcc5eff90bba6e4b139cb2d27f12 1 parent 76ae95b
@supernovus authored
View
8 README
@@ -33,9 +33,11 @@ Note: Flower is not yet complete, and is still missing a lot of functionality.
There is no equivelant to the Petal::Parser::HTB, and no plans for one.
Use well-formed XML, it's just better.
* Flower supports petal:block elements, as per the PHPTAL project.
- * There is no 'structure' keyword. Strings are turned into Exemel::Text
- objects. If you really want to use XML structures in a replace or content
- statement, return an Exemel::Element.
+ * While you can use the 'structure' keyword, it's not really needed.
+ If you want an unescaped XML structure for a replacement, send an
+ Exemel object (any class other than Document) and it will be added to
+ the XML tree. Send an array of Exemel objects, and they will additionally
+ be parsed for TAL statements.
* Nested repeats cannot use the same attribute name, it will get clobbered.
* The built-in repeat object is implemented as per the Zope/PHPTAL, not
the Petal version. Note: it does not support the 'letter' or 'Letter'
View
7 docs/TODO.txt
@@ -1,13 +1,12 @@
-Short Term (October 2010)
- - Implement XML escaping on text nodes.
+Short Term (October 2010, Version 1.0 stable)
- Finish implementing Flower::Utils, as per the README.
-Medium Term (December 2010)
+Medium Term (December 2010, Version 1.1 stable)
- Implement METAL support.
- Implement query caching.
- Implement multiple paths (/test/path1 | /test/path2) support.
-Long Term (2011)
+Long Term (2011, Undetermined versions)
- Implement I18N support.
- Implement on-error.
View
32 lib/Flower.pm
@@ -253,8 +253,8 @@ method !parse-omit-tag ($xml is rw, $tag) {
}
}
-## Query data, this
-method query ($query, :$noxml, :$forcexml, :$bool) {
+## Query data.
+method query ($query is copy, :$noxml, :$forcexml, :$bool, :$noescape is copy) {
if $query eq '' {
if ($bool) { return True; }
else { return ''; }
@@ -263,26 +263,34 @@ method query ($query, :$noxml, :$forcexml, :$bool) {
if ($bool) { return False; }
else { return ''; }
}
- if $query ~~ /^\'(.*?)\'$/ {
- if ($forcexml) {
- return Exemel::Text.new(:text(~$0));
- }
- return ~$0;
+ if $query ~~ /^ structure \s+ / {
+ $query.=subst(/^ structure \s+ /, '');
+ $noescape = True;
+ }
+ if $query ~~ /^\'(.*?)\'$/ {
+ return self.process-query(~$0, :$forcexml, :$noxml, :$noescape);
} # quoted string, no interpolation.
if $query ~~ /^<.ident>+\:/ {
my ($handler, $subquery) = $query.split(/\:\s*/, 2);
if %!modifiers.exists($handler) {
- my $data = %!modifiers{$handler}(self, $subquery, :$noxml, :$forcexml, :$bool);
- return self!query-xml($data, :$forcexml, :$noxml);
+ ## Modifiers are responsible for subqueries, and calls to process-query.
+ return %!modifiers{$handler}(self, $subquery, :$noxml, :$forcexml, :$bool, :$noescape);
}
}
my @paths = $query.split('/');
my $data = self!lookup(@paths, %.data);
- return self!query-xml($data, :$forcexml, :$noxml);
+ return self.process-query($data, :$forcexml, :$noxml, :$noescape);
}
-## Enforce forcexml and noxml rules for query().
-method !query-xml($data, :$forcexml, :$noxml) {
+## Enforce processing rules for query().
+method process-query($data is copy, :$forcexml, :$noxml, :$noescape, :$bool) {
+ ## First off, let's escape text, unless noescape is set.
+ if (!defined $noescape && $data ~~ Str) {
+ $data.=subst('&', '&amp;', :g);
+ $data.=subst('<', '&lt;', :g);
+ $data.=subst('>', '&gt;', :g);
+ $data.=subst('"', '&quot;', :g);
+ }
## Default rule for forcexml converts non-XML objects into Exemel::Text.
if ($forcexml && $data !~~ Exemel) {
return Exemel::Text.new(:text(~$data));
View
2  lib/Flower/DefaultModifiers.pm
@@ -25,6 +25,6 @@ our sub string ($parent, $query, *%opts) {
my $string = $query;
# $string ~~ s:g/ '${' (.*?) '}' / $parent.query($0) /; # NYI in rakudo.
$string.=subst(:g, rx/'${' (.*?) '}'/, -> $/ { $parent.query($0) });
- return $string;
+ return $parent.process-query($string, |%opts);
}
View
10 lib/Flower/Utils/Debug.pm
@@ -14,12 +14,14 @@ our sub all() {
}
our sub dump_perl($parent, $query, *%opts) {
- my $result = $parent.query($query);
- return $result.perl;
+ my $result = $parent.query($query, :noescape);
+ %opts.delete('noescape');
+ return $parent.process-query($result.perl, :noescape, |%opts);
}
our sub what_perl($parent, $query, *%opts) {
- my $result = $parent.query($query);
- return $result.WHAT.perl;
+ my $result = $parent.query($query, :noescape);
+ %opts.delete('noescape');
+ return $parent.process-query($result.WHAT.perl, :noescape, |%opts);
}
View
2  lib/Flower/Utils/Perl.pm
@@ -17,6 +17,6 @@ our sub perl_query ($parent, $query, *%opts) {
my $perl = $query.subst(/^(<&keyname>)/, -> $/ { '$parent.data<'~$0~'>' });
$perl.=subst('.eval','.chomp', :g); ## Kill any attempts to eval.
my $result = eval($perl);
- return $result;
+ return $parent.process-query($result, |%opts);
}
View
4 lib/Flower/Utils/Text.pm
@@ -14,11 +14,11 @@ our sub all() {
our sub upper ($parent, $query, *%opts) {
my $result = $parent.query($query);
- return $result.uc;
+ return $parent.process-query($result.uc, |%opts);
}
our sub lower ($parent, $query, *%opts) {
my $result = $parent.query($query);
- return $result.lc;
+ return $parent.process-query($result.lc, |%opts);
}
View
16 t/07-escape.t
@@ -0,0 +1,16 @@
+#!/usr/bin/env perl6
+
+BEGIN { @*INC.unshift: './lib' }
+
+use Test;
+use Flower;
+
+plan 1;
+
+my $xml = '<?xml version="1.0"?>';
+
+my $template = '<test><escaped tal:content="string"/><unescaped tal:content="structure string"/></test>';
+my $flower = Flower.new(:template($template));
+
+is $flower.parse(string=>'hello to you & your friend, "how are you?"'), $xml~'<test><escaped>hello to you &amp; your friend, &quot;how are you?&quot;</escaped><unescaped>hello to you & your friend, "how are you?"</unescaped></test>', 'XML escapes and structure keyword';
+
Please sign in to comment.
Something went wrong with that request. Please try again.