summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid A. Madore <david+git@madore.org>2010-03-27 14:55:25 (GMT)
committerDavid A. Madore <david+git@madore.org>2010-03-27 14:55:25 (GMT)
commit31b87b24ce3bc9b4cb5f9b6877a2101a922d463b (patch)
tree5a196554de4fa00dd7c1926973ae03a1cd1aaf6a
parent2afa29d680e9ce34551b97ea7efcc4043efe9822 (diff)
downloadblogengine-31b87b24ce3bc9b4cb5f9b6877a2101a922d463b.zip
blogengine-31b87b24ce3bc9b4cb5f9b6877a2101a922d463b.tar.gz
blogengine-31b87b24ce3bc9b4cb5f9b6877a2101a922d463b.tar.bz2
Create <style> and <script> nodes, and <title> correctly.
-rwxr-xr-xdaml2html.pl130
1 files changed, 112 insertions, 18 deletions
diff --git a/daml2html.pl b/daml2html.pl
index cf98ed5..e522966 100755
--- a/daml2html.pl
+++ b/daml2html.pl
@@ -99,13 +99,45 @@ my $xpc = XML::LibXML::XPathContext->new($doc);
$xpc->registerNs('h', XHTML_NS);
$xpc->registerNs('d', DAML_NS);
-my @node_stack;
-
-unshift @node_stack, [$doc->documentElement, {is_root=>1}];
-
+# @todo_stack is a list of array references of "things to do"; note
+# that while it functions mainly as a stack, the stack pointer is at
+# the start (use Perl shift/unshift to pop/push things to do, and Perl
+# push to add something to do at the very end). The program's main
+# loop repeatedly shifts the first element off @todo_stack and
+# processes it until the list is empty. A "thing to do" is a
+# reference to an array: the first element ($call_this) is generally
+# undef, meaning handle a node as usual, otherwise it is a reference
+# to a function that will be called with the rest of the array as
+# arguments; the second argument ($node) is the node to examine; the
+# third ($optref) is a reference to a hash giving some extra context
+# on this node or why it is being examined now; the rest are optional
+# arguments to the handler function. The default behavior (when
+# $call_this is null) is to examine $node and, if a special handler is
+# registered for it, invoke that, otherwise invoke the default
+# handler: the latter simply lists all element children of the node
+# and shifts them at the beginning of @todo_stack.
+my @todo_stack;
+
+unshift @todo_stack, [undef, $doc->documentElement, {is_root=>1}];
+
+# Global variables for processing:
my $html_node;
my $head_node;
-my $title_node;
+my $src_title;
+my $style_content = "";
+my $script_content = "";
+
+if ( open my $common_style_file, "<", "included.css" ) {
+ local $/;
+ $style_content = <$common_style_file>;
+ close $common_style_file;
+}
+
+if ( open my $common_script_file, "<", "included.js" ) {
+ local $/;
+ $script_content = <$common_script_file>;
+ close $common_script_file;
+}
sub default_handler_nodeonly {
my $node = shift;
@@ -115,9 +147,10 @@ sub default_handler_nodeonly {
my @child_nodes = $node->childNodes;
my @to_process;
foreach my $child ( @child_nodes ) {
- push @to_process, [$child, {}] if $child->nodeType == XML_ELEMENT_NODE;
+ push @to_process, [undef, $child, {}]
+ if $child->nodeType == XML_ELEMENT_NODE;
}
- unshift @node_stack, @to_process;
+ unshift @todo_stack, @to_process;
}
sub default_handler {
@@ -141,12 +174,40 @@ sub create_meta_element_helper {
($doc->documentElement)->appendChild($meta); # Work around libxml2 bug <URL: https://bugzilla.gnome.org/show_bug.cgi?id=614068 >
$src_node->replaceNode($meta);
} else {
- die "\$head_node should have been defined at this point" unless defined($head_node);
+ die "\$head_node should have been defined at this point"
+ unless defined($head_node);
$head_node->appendChild($meta);
$head_node->appendChild($doc->createTextNode("\n"));
}
}
+sub create_style_or_script_node {
+ my $node = shift;
+ my $optref = shift;
+ my $type = shift;
+ die "create_style_or_script_node with type other than \"style\" or \"script\""
+ unless defined($type) && ($type eq "style" || $type eq "script");
+ my $valref = shift;
+ die "\$head_node should have been defined at this point"
+ unless defined($head_node);
+ die "fix broken assumption: \$node == \$head_node"
+ unless $node == $head_node;
+ my $snode = $doc->createElementNS(XHTML_NS, $type);
+ $head_node->appendChild($snode);
+ $head_node->appendChild($doc->createTextNode("\n"));
+ $snode->setAttributeNS("", "type", ($type eq "style"?"text/css":"text/javascript"));
+ $snode->setAttributeNS("", "defer", "defer") if $type eq "script";
+ if ( $type eq "style" ) {
+ $snode->appendChild($doc->createTextNode("\n/* "));
+ $snode->appendChild($doc->createCDATASection(" */\n".$$valref."/* "));
+ $snode->appendChild($doc->createTextNode(" */\n"));
+ } else {
+ $snode->appendChild($doc->createTextNode("\n// "));
+ $snode->appendChild($doc->createCDATASection("\n".$$valref."// "));
+ $snode->appendChild($doc->createTextNode("\n"));
+ }
+}
+
sub daml_handler {
my $node = shift;
my $optref = shift;
@@ -162,7 +223,8 @@ sub daml_handler {
$html_node->appendChild($doc->createTextNode("\n"));
$html_node->appendChild($doc->createComment(" This file is automatically generated. Do not edit! "));
$html_node->appendChild($doc->createTextNode("\n"));
- die "\$head_node already defined: what magic is this?" if defined($head_node);
+ die "\$head_node already defined: what magic is this?"
+ if defined($head_node);
$head_node = $doc->createElementNS(XHTML_NS, "head");
$html_node->appendChild($head_node);
$html_node->appendChild($doc->createTextNode("\n"));
@@ -181,14 +243,18 @@ sub daml_handler {
$head_node->appendChild($child);
$head_node->appendChild($doc->createTextNode("\n"));
}
- push @to_process, [$child, {is_daml_child=>1}];
+ push @to_process, [undef, $child, {is_daml_child=>1}];
} elsif ( $child->nodeType == XML_TEXT_NODE
|| $child->nodeType == XML_CDATA_SECTION_NODE ) {
die "daml element cannot contain text"
unless $child->data =~ m/^\s*$/s;
}
}
- unshift @node_stack, @to_process;
+ unshift @todo_stack, @to_process;
+ push @todo_stack, [\&create_style_or_script_node, $head_node, {special=>1},
+ "style", \$style_content];
+ push @todo_stack, [\&create_style_or_script_node, $head_node, {special=>1},
+ "script", \$script_content];
}
sub body_handler {
@@ -199,6 +265,7 @@ sub body_handler {
if ( my $lang = $node->getAttributeNS(XML_XML_NS, "lang") ) {
$body_node->setAttributeNS(XML_XML_NS, "lang", $lang);
}
+ $body->setAttributeNS("", "onload", "onLoad()");
($doc->documentElement)->appendChild($body_node); # Work around libxml2 bug <URL: https://bugzilla.gnome.org/show_bug.cgi?id=614068 >
$node->replaceNode($body_node);
my @child_nodes = $node->childNodes;
@@ -210,9 +277,10 @@ sub body_handler {
unless $child->data =~ m/^\s*$/s;
}
$body_node->appendChild($child);
- push @to_process, [$child, {}] if $child->nodeType == XML_ELEMENT_NODE;
+ push @to_process, [undef, $child, {}]
+ if $child->nodeType == XML_ELEMENT_NODE;
}
- unshift @node_stack, @to_process;
+ unshift @todo_stack, @to_process;
}
sub title_handler {
@@ -220,8 +288,16 @@ sub title_handler {
my $optref = shift;
print STDERR "warning: title handler doesn't handle arguments\n" if @_;
if ( $$optref{is_daml_child} ) {
- $title_node = $node;
- create_meta_element_helper $node, "name", "Title", $title_node->textContent;
+ $src_title = $node;
+ my $title_text = $node->textContent;
+ my $title_node = $doc->createElementNS(XHTML_NS, "title");
+ if ( my $lang = $node->getAttributeNS(XML_XML_NS, "lang") ) {
+ $title_node->setAttributeNS(XML_XML_NS, "lang", $lang);
+ }
+ ($doc->documentElement)->appendChild($title_node); # Work around libxml2 bug <URL: https://bugzilla.gnome.org/show_bug.cgi?id=614068 >
+ $node->replaceNode($title_node);
+ $title_node->appendChild($doc->createTextNode($title_text));
+ create_meta_element_helper undef, "name", "Title", $title_text;
}
}
@@ -236,20 +312,38 @@ sub meta_handler {
}
}
+sub extra_style_handler {
+ my $node = shift;
+ my $optref = shift;
+ print STDERR "warning: extra-style handler doesn't handle arguments\n" if @_;
+ $style_content .= $node->textContent;
+ if ( ($node->nextSibling)->nodeType == XML_TEXT_NODE
+ && ($node->nextSibling)->data =~ m/^\s*$/s ) {
+ $node->nextSibling->unbindNode;
+ }
+ $node->unbindNode;
+}
+
my %daml_handler = (
"daml" => \&daml_handler,
"body" => \&body_handler,
"title" => \&title_handler,
"meta-description" => \&meta_handler,
"meta-keywords" => \&meta_handler,
+ "extra-style" => \&extra_style_handler,
);
-NODELOOP:
-while ( my $process = shift @node_stack ) {
+TODO_LOOP:
+while ( my $process = shift @todo_stack ) {
+ my $call_this = shift @$process;
+ if ( $call_this ) {
+ &$call_this(@$process);
+ next TODO_LOOP;
+ }
my $node = $$process[0];
unless ( defined($node->namespaceURI) ) {
printf STDERR "warning: skipping %s node with missing namespace\n", $node->nodeName;
- next NODELOOP;
+ next TODO_LOOP;
}
if ( $node->namespaceURI eq DAML_NS && defined($daml_handler{$node->localName}) ) {
&{$daml_handler{$node->localName}}(@$process);