# 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 . use strict; use warnings; use MarkdownBook::Document; use MarkdownBook::HTMLTree; use Carp; use Text::Markdown; use HTML::TreeBuilder; use HTML::Template; package MarkdownBook::Document::html; our @ISA = qw(MarkdownBook::Document); sub output { my ($self) = @_; my $text; my $doc; my $sec; # Substitute macros. $text = $self->{'book'}->subst_macros( $self->{'source_text'}); # Append link definitions. $text .= "\n"; foreach $doc (@{$self->{'book'}->documents()}) { $text .= "\n"; $text .= '['; $text .= $doc->file(); $text .= ']: '; $text .= $doc->file(); $text .= '.html'; foreach $sec (@{$doc->sections()}) { $text .= "\n"; $text .= '['; $text .= $sec->id(); $text .= ']: '; $text .= $doc->file(); $text .= '.html#'; $text .= $sec->id(); } } # Convert to HTML. $text = Text::Markdown::Markdown($text); # Set "id" attributes of headings. $self->_do_set_heading_id_attrs($text); # Output the templated HTML. $self->_do_output_template(); # Clean up. $self->{'tree'}->delete(); } sub _do_set_heading_id_attrs { my ($self, $text) = @_; my @headings; my $heading; my $i = -1; # Parse HTML. $self->{'tree'} = HTML::TreeBuilder->new(); $self->{'tree'}->parse($text); $self->{'tree'}->eof($text); # Find the "body" element. @{$self->{'tree_body'}} = MarkdownBook::HTMLTree::find_elements_by_tag_names( $self->{'tree'}, ('body')); # Don't modify headings of index documents. return if $self->{'type'} eq 'index'; # Find all headings. @headings = MarkdownBook::HTMLTree::find_elements_by_tag_names( @{$self->{'tree_body'}}[0], ('h1', 'h2')); # Set "id" attributes. foreach $heading (@headings) { $heading->attr('id', ${$self->{'sections'}}[++$i]->id()); } } sub _do_output_template { my ($self) = @_; my $doc_tmpl; my %opt_end_tags; my $elem; my $body; my $doc_fh; $doc_tmpl = HTML::Template->new(filename => 'include/document.tmpl'); # Don't omit any end tags. %opt_end_tags = map([$_ => 0], %HTML::Element::optionalEndTag); # Get HTML text of all children of the "body" element. foreach $elem (@{$self->{'tree_body'}}[0]->content_list()) { # It's safe to assume (ref($elem) eq 'HTML::Element'). $body .= $elem->as_HTML('<>&', '', \%opt_end_tags) . "\n"; } $doc_tmpl->param(IS_INDEX => ($self->{'type'} eq 'index')); $doc_tmpl->param(BOOK_TITLE => $self->{'book'}->title()); $doc_tmpl->param(TITLE => $self->{'title'}); $doc_tmpl->param(CHAPT_TITLE => $self->full_title()); if (defined($self->{'prev'})) { $doc_tmpl->param(PREV_LINK => $self->{'prev'}->file() . '.html'); $doc_tmpl->param(PREV_TITLE => $self->{'prev'}->title()); } else { $doc_tmpl->param(PREV_LINK => undef); $doc_tmpl->param(PREV_TITLE => undef); } if (defined($self->{'next'})) { $doc_tmpl->param(NEXT_LINK => $self->{'next'}->file() . '.html'); $doc_tmpl->param(NEXT_TITLE => $self->{'next'}->title()); } else { $doc_tmpl->param(NEXT_LINK => undef); $doc_tmpl->param(NEXT_TITLE => undef); } $doc_tmpl->param(BODY => $body); open($doc_fh, '>', $self->file_path() . '.html') or croak('Cannot open "' . $self->{'file'} . '" destination document'); $doc_tmpl->output(print_to => $doc_fh); close($doc_fh); } 1;