summaryrefslogtreecommitdiffstats
path: root/scripts/MarkdownBook/Document.pm
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/MarkdownBook/Document.pm')
-rw-r--r--scripts/MarkdownBook/Document.pm180
1 files changed, 180 insertions, 0 deletions
diff --git a/scripts/MarkdownBook/Document.pm b/scripts/MarkdownBook/Document.pm
new file mode 100644
index 0000000..f9b9a13
--- /dev/null
+++ b/scripts/MarkdownBook/Document.pm
@@ -0,0 +1,180 @@
+# Copyright (C) 2012 Patrick "P. J." McDermott
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+use strict;
+use warnings;
+
+use MarkdownBook::HTMLTree;
+use HTML::TreeBuilder;
+
+package MarkdownBook::Document;
+
+sub new
+{
+ my ($class, $book, $file, $id, $title) = @_;
+ my $self;
+
+ $class = ref($class) || $class;
+ $self = {};
+ bless($self,$class);
+ $self->{'book'} = $book;
+ $self->{'file'} = $file;
+ $self->{'id'} = $id;
+ $self->{'title'} = $title;
+
+ return $self;
+}
+
+sub book
+{
+ my ($self, $book) = @_;
+ my $old = $self->{'book'};
+
+ $self->{'book'} = $book if defined($book);
+
+ return $old;
+}
+
+sub file
+{
+ my ($self, $file) = @_;
+ my $old = $self->{'file'};
+
+ $self->{'file'} = $file if defined($file);
+
+ return $old;
+}
+
+sub file_path
+{
+ my ($self) = @_;
+
+ return $self->{'book'}->dir() . '/' . $self->{'file'};
+}
+
+sub title
+{
+ my ($self, $title) = @_;
+ my $old = $self->{'title'};
+
+ $self->{'title'} = $title if defined($title);
+
+ return $old;
+}
+
+sub prev
+{
+ my ($self, $other) = @_;
+ my $old = $self->{'prev'};
+
+ $self->{'prev'} = $other if defined($other);
+
+ return $old;
+}
+
+sub next
+{
+ my ($self, $other) = @_;
+ my $old = $self->{'next'};
+
+ $self->{'next'} = $other if defined($other);
+
+ return $old;
+}
+
+sub parse_html
+{
+ my ($self) = @_;
+ my $file = $self->{'book'}->dir() . '/' . $self->{'file'} . '.html.in';
+
+ $self->{'tree'} = HTML::TreeBuilder->new();
+ $self->{'tree'}->parse_file($file);
+}
+
+sub number_sections
+{
+ my ($self) = @_;
+
+ my @headers;
+ my $header;
+ my @secnums = (0, 0);
+ my $curlev = -1;
+ my $newlev;
+ my $secstr;
+ my @children;
+ my $sectitle;
+ my $secid;
+
+ @{$self->{'tree_body'}} = MarkdownBook::HTMLTree::find_elements_by_tag_names(
+ $self->{'tree'}, ('body'));
+ @headers = MarkdownBook::HTMLTree::find_elements_by_tag_names(
+ @{$self->{'tree_body'}}[0], ('h1', 'h2'));
+
+ foreach $header (@headers) {
+
+ # Calculate section number.
+ $newlev = $header->tag();
+ $newlev =~ s/^h(\d)$/$1/;
+ if ($newlev != $curlev) {
+ foreach (@secnums[$newlev .. $#secnums]) {
+ $_ = 0;
+ }
+ }
+ $curlev = $newlev;
+ ++$secnums[$newlev - 1];
+ $secstr = join('.', @secnums);
+ $secstr =~ s/(\.0)*$//;
+
+ MarkdownBook::HTMLTree::each_text(sub {
+
+ # Prefix section title with section number.
+ my $sectitle = $_[1];
+ $sectitle =~ s/^([^\[]+)[ ]*\[[^\]]+\]$/$_[2].$secstr $1/;
+
+ # Set "id" attribute.
+ if ($_[1] =~ m/^[^\[\]]*\[([^\]]+)\][^\[\]]*$/) {
+ my $secid = $_[1];
+ $secid =~ s/^[^\[\]]*\[([^\]]+)\][^\[\]]*$/$1/;
+ ${$_[0]}->attr('id', $secid);
+ }
+
+ # Set section title.
+ $_[1] = $sectitle;
+
+ }, $header, $self->{'id'});
+
+ }
+}
+
+sub output
+{
+ my ($self) = @_;
+
+ my $elem;
+ my %opt_end_tags;
+ my $out;
+
+ # Don't omit any end tags.
+ %opt_end_tags = map([$_ => 0], %HTML::Element::optionalEndTag);
+
+ foreach $elem (@{$self->{'tree_body'}}[0]->content_list()) {
+ # It's safe to assume (ref($elem) eq 'HTML::Element').
+ $out .= $elem->as_HTML('<>&', '', \%opt_end_tags) . "\n";
+ }
+
+ return $out;
+}
+
+1;