summaryrefslogtreecommitdiffstats
path: root/scripts/MarkdownBook
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/MarkdownBook')
-rw-r--r--scripts/MarkdownBook/Book.pm264
-rw-r--r--scripts/MarkdownBook/Document.pm245
-rw-r--r--scripts/MarkdownBook/Document/html.pm153
-rw-r--r--scripts/MarkdownBook/Document/txt.pm46
-rw-r--r--scripts/MarkdownBook/HTMLTree.pm44
-rw-r--r--scripts/MarkdownBook/Section.pm67
6 files changed, 0 insertions, 819 deletions
diff --git a/scripts/MarkdownBook/Book.pm b/scripts/MarkdownBook/Book.pm
deleted file mode 100644
index 4f30afb..0000000
--- a/scripts/MarkdownBook/Book.pm
+++ /dev/null
@@ -1,264 +0,0 @@
-# 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 Carp;
-
-package MarkdownBook::Book;
-
-sub new
-{
- my ($class, $format, $dir) = @_;
- my $self;
- my $control_fh;
-
- $class = ref($class) || $class;
- $self = {};
- bless($self, $class);
-
- unless ($format =~ m/^[a-z]+/) {
- Carp::croak('Invalid format "' . $format . '"');
- }
- eval {
- require 'MarkdownBook/Document/' . $format . '.pm';
- 1;
- } or Carp::croak('Unsupported format "' . $format . '"');
- $self->{'format'} = $format;
-
- $self->{'dir'} = $dir;
- $self->{'docs'} = [];
- $self->{'sections'} = [];
- $self->{'sections_by_id'} = {};
-
- open($control_fh, '<', $dir . '/control');
- while (<$control_fh>) {
- chomp($_);
- if (m/^Title: /) {
- s/^Title: (.*)$/$1/;
- $self->{'title'} = $_;
- }
- }
- close($control_fh);
-
- $self->create_documents();
-
- return $self;
-}
-
-sub dir
-{
- my ($self, $dir) = @_;
- my $old = $self->{'dir'};
-
- $self->{'dir'} = $dir if defined($dir);
-
- return $old;
-}
-
-sub title
-{
- my ($self, $title) = @_;
- my $old = $self->{'title'};
-
- $self->{'title'} = $title if defined($title);
-
- return $old;
-}
-
-sub documents
-{
- my ($self, $documents) = @_;
- my $old = $self->{'docs'};
-
- $self->{'docs'} = $documents if defined($documents);
-
- return $old;
-}
-
-sub _get_document_module
-{
- my ($self) = @_;
-
- return 'MarkdownBook::Document::' . $self->{'format'};
-}
-
-sub create_documents
-{
- my ($self) = @_;
- my $series_fh;
- my $file;
- my $title;
- my $i;
- my $doc;
- my $doc_prev;
- my @letters;
-
- # Create index document.
- $doc = $self->_get_document_module()->new($self, 'index', 'index',
- undef, $self->{'title'});
- $doc_prev = $doc;
- push(@{$self->{'docs'}}, $doc);
-
- # Create chapter documents.
- $i = 0;
- open($series_fh, '<', $self->{'dir'} . '/chapters')
- or Carp::croak('Cannot open chapters file');
- while (<$series_fh>) {
- chomp($_);
- ($file, $title) = split(/[ \t]+/, $_, 2);
- $doc = $self->_get_document_module()->new($self, 'chapter', $file,
- ++$i, $title);
- $doc->prev($doc_prev);
- $doc_prev->next($doc) if defined $doc_prev;
- $doc_prev = $doc;
- push(@{$self->{'docs'}}, $doc);
- }
- close($series_fh);
-
- # Create appendix documents.
- $i = -1;
- @letters = ('A' .. 'Z');
- if (-e $self->{'dir'} . '/appendices') {
- open($series_fh, '<', $self->{'dir'} . '/apendices')
- or Carp::croak('Cannot open appendices file');
- while (<$series_fh>) {
- chomp($_);
- ($file, $title) = split(/[ \t]+/, $_, 2);
- $doc = $self->_get_document_module()->new($self, 'appendix', $file,
- $letters[++$i], $title);
- $doc->prev($doc_prev);
- $doc_prev->next($doc) if defined $doc_prev;
- $doc_prev = $doc;
- push(@{$self->{'docs'}}, $doc);
- }
- close($series_fh);
- }
-}
-
-sub add_section
-{
- my ($self, $section) = @_;
-
- push(@{$self->{'sections'}}, $section);
-
- # Index sections (not documents) by ID.
- if (ref($section) eq 'MarkdownBook::Section') {
- $self->{'sections_by_id'}->{$section->id()} = $section;
- }
-}
-
-sub subst_macros
-{
- my ($self, $text) = @_;
-
- # Substitute macros with arguments.
- $text =~ s/
- \$ # Dollar sign
- \[ # Left square bracket
- ([^\]]+) # Macro
- \] # Right square bracket
- (
- \[ # Left square bracket
- ([^\]]+) # Macro arguments
- \] # Right square bracket
- )
- /$self->_do_subst_macro($1, split(m@[ \t]+@, $3))/exg;
-
- # Substitute macros without arguments.
- $text =~ s/
- \$ # Dollar sign
- \[ # Left square bracket
- ([^\]]+) # Macro
- \] # Right square bracket
- /$self->_do_subst_macro($1)/exg;
-
- return $text;
-}
-
-sub _do_subst_macro
-{
- my ($self, $macro, @args) = @_;
- my $sec;
-
- if ($macro eq 'toc') {
- return $self->_do_gen_toc();
- } elsif ($macro eq 'sectlink') {
- if (@args != 1) {
- Carp::carp('Invalid arguments to "sectlink" macro');
- } else {
- $sec = $self->{'sections_by_id'}->{$args[0]};
- return '[ยง ' . $sec->number() . '][' . $sec->id() . ']';
- }
- } else {
- Carp::carp("Unrecognized macro \"$macro\"");
- }
-}
-
-sub _do_gen_toc
-{
- my ($self) = @_;
- my $section;
- my $toc = '';
-
- foreach $section (@{$self->{'sections'}}) {
- $toc .= "\n" if $toc ne '';
- if (ref($section) =~ m/^MarkdownBook::Document/) {
- next if $section->type() eq 'index';
- $toc .= ' * [';
- $toc .= $section->id();
- $toc .= ' ';
- $toc .= $section->title();
- $toc .= '][';
- $toc .= $section->file();
- $toc .= ']';
- } elsif (ref($section) eq 'MarkdownBook::Section') {
- $toc .= ' ' x $section->level();
- $toc .= ($section->level() == 1 ? ' - [' : ' * [');
- $toc .= $section->number();
- $toc .= ' ';
- $toc .= $section->title();
- $toc .= '][';
- $toc .= $section->id();
- $toc .= ']';
- }
- }
-
- return $toc;
-}
-
-sub parse
-{
- my ($self) = @_;
- my $doc;
-
- foreach $doc (@{$self->{'docs'}}) {
- $self->add_section($doc);
- $doc->parse();
- }
-}
-
-sub output
-{
- my ($self) = @_;
- my $doc;
-
- foreach $doc (@{$self->{'docs'}}) {
- $doc->output();
- }
-}
-
-1;
diff --git a/scripts/MarkdownBook/Document.pm b/scripts/MarkdownBook/Document.pm
deleted file mode 100644
index 2a30396..0000000
--- a/scripts/MarkdownBook/Document.pm
+++ /dev/null
@@ -1,245 +0,0 @@
-# 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::Section;
-use Carp;
-
-package MarkdownBook::Document;
-
-sub new
-{
- my ($class, $book, $type, $file, $id, $title) = @_;
- my $self;
-
- $class = ref($class) || $class;
- $self = {};
- bless($self, $class);
-
- $self->{'book'} = $book;
- $self->{'type'} = $type;
- $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 type
-{
- my ($self, $type) = @_;
- my $old = $self->{'type'};
-
- $self->{'type'} = $type if defined($type);
-
- 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 id
-{
- my ($self) = @_;
-
- return $self->{'id'};
-}
-
-sub title
-{
- my ($self, $title) = @_;
- my $old = $self->{'title'};
-
- $self->{'title'} = $title if defined($title);
-
- return $old;
-}
-
-sub full_title
-{
- my ($self) = @_;
-
- if ($self->{'type'} eq 'chapter') {
- return sprintf('Chapter %d - %s', $self->{'id'}, $self->{'title'});
- } elsif ($self->{'type'} eq 'appendix') {
- return sprintf('Appendix %s - %s', $self->{'id'}, $self->{'title'});
- } else {
- return undef;
- }
-}
-
-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 sections
-{
- my ($self) = @_;
-
- # FIXME: Why is this necessary?!
- foreach my $sec (@{$self->{'sections'}}) {
- }
-
- return $self->{'sections'};
-}
-
-sub parse
-{
- my ($self) = @_;
- my $source_fh;
- my $source_text;
-
- open($source_fh, '<',
- $self->{'book'}->dir() . '/' . $self->{'file'} . '.mdwn')
- or Carp::croak('Cannot open "' . $self->{'file'} . '" source document');
- $source_text = join('', <$source_fh>);
- close($source_fh);
-
- # Parse headings of non-index documents.
- if ($self->{'type'} ne 'index') {
- $self->{'section_level_numbers'} = [0, 0];
- $self->{'section_level'} = -1;
- $source_text =~ s/
- ^
- (.+) # Heading text
- [ \t]* # Optional trailing whitespace
- \n # Line break
- (=+|-+) # Underline
- [ \t]* # Optional trailing whitespace
- $
- /$self->_do_heading($1, $2)/mexg;
- }
-
- # Store parsed text.
- $self->{'source_text'} = $source_text;
-}
-
-sub _do_heading
-{
- my ($self, $text, $underline) = @_;
- my $level;
- my $levels;
- my $section_number;
- my $section_title;
- my $section_id;
- my $section;
-
- # Shorten underline to one character.
- $underline =~ s/^([=-]).*$/$1/;
-
- # Detect heading level.
- if ($underline eq '=') {
- $level = 1;
- } else {
- $level = 2;
- }
-
- # Calculate section number.
- $levels = $#{$self->{'section_level_numbers'}};
- if ($level != $self->{'section_level'}) {
- foreach (@{$self->{'section_level_numbers'}}[$level .. $levels]) {
- $_ = 0;
- }
- }
- $self->{'section_level'} = $level;
- ++${$self->{'section_level_numbers'}}[$level - 1];
- $section_number = join('.', @{$self->{'section_level_numbers'}});
-
- # Add document ID to section number.
- $section_number = $self->{'id'} . '.' . $section_number;
-
- # Trim off unused subsection parts.
- $section_number =~ s/(?:\.0)*$//;
-
- # Parse out section title.
- $section_title = $text;
- $section_title =~ s/
- ^
- ([^\[]+) # Section title
- [ \t]+ # Whitespace
- \[ # Left square bracket
- [^\]]+ # Section ID
- \] # Right square bracket
- $
- /$1/x;
-
- # Parse out section ID.
- $section_id = $text;
- $section_id =~ s/
- ^
- [^\[\]]+ # Section title
- [ \t]+ # Whitespace
- \[ # Left square bracket
- ([^\]]+) # Section ID
- \] # Right square bracket
- $
- /$1/x;
-
- # Create and store section object.
- $section = MarkdownBook::Section->new($self,
- $level, $section_number, $section_id, $section_title);
- push(@{$self->{'sections'}}, $section);
- $self->{'book'}->add_section($section);
-
- # Prepend number to section title.
- $text = $section_number . ' ' . $section_title;
-
- # Return underlined section title.
- return $text . "\n" . $underline x length($text);
-}
-
-1;
diff --git a/scripts/MarkdownBook/Document/html.pm b/scripts/MarkdownBook/Document/html.pm
deleted file mode 100644
index 60f22c7..0000000
--- a/scripts/MarkdownBook/Document/html.pm
+++ /dev/null
@@ -1,153 +0,0 @@
-# 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::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 Carp::croak('Cannot open "' . $self->{'file'} . '" destination document');
- $doc_tmpl->output(print_to => $doc_fh);
- close($doc_fh);
-}
-
-1;
diff --git a/scripts/MarkdownBook/Document/txt.pm b/scripts/MarkdownBook/Document/txt.pm
deleted file mode 100644
index f150477..0000000
--- a/scripts/MarkdownBook/Document/txt.pm
+++ /dev/null
@@ -1,46 +0,0 @@
-# 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::Document;
-use Carp;
-
-package MarkdownBook::Document::txt;
-
-our @ISA = qw(MarkdownBook::Document);
-
-sub output
-{
- my ($self) = @_;
- my $out_fh;
-
- open($out_fh, '>',
- $self->{'book'}->dir() . '/' . $self->{'file'} . '.txt')
- or Carp::croak('Cannot open "' . $self->{'file'} .
- '" destination document');
-
- # Print document title.
- print($out_fh $self->{'title'} . "\n" .
- '*' x length($self->{'title'}) . "\n\n\n");
-
- # Print document text with macro substitutions.
- print($out_fh $self->{'book'}->subst_macros($self->{'source_text'}));
-
- close($out_fh);
-}
-
-1;
diff --git a/scripts/MarkdownBook/HTMLTree.pm b/scripts/MarkdownBook/HTMLTree.pm
deleted file mode 100644
index e01bab0..0000000
--- a/scripts/MarkdownBook/HTMLTree.pm
+++ /dev/null
@@ -1,44 +0,0 @@
-# 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 HTML::Element;
-
-package MarkdownBook::HTMLTree;
-
-sub find_elements_by_tag_names
-{
- my ($elem, @tagnames) = @_;
-
- my @list = $elem->content_list();
- my $tag;
- my @retlist = ();
-
- foreach (@list) {
- if (ref($_) ne 'HTML::Element') {
- next;
- }
- $tag = $_->tag();
- if (grep($_ eq $tag, @tagnames)) {
- push(@retlist, $_);
- }
- }
-
- return @retlist;
-}
-
-1;
diff --git a/scripts/MarkdownBook/Section.pm b/scripts/MarkdownBook/Section.pm
deleted file mode 100644
index 82ff897..0000000
--- a/scripts/MarkdownBook/Section.pm
+++ /dev/null
@@ -1,67 +0,0 @@
-# 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;
-
-package MarkdownBook::Section;
-
-sub new
-{
- my ($class, $doc, $lev, $num, $id, $title) = @_;
- my $self;
-
- $class = ref($class) || $class;
- $self = {};
- bless($self, $class);
-
- $self->{'document'} = $doc;
- $self->{'level'} = $lev;
- $self->{'number'} = $num;
- $self->{'id'} = $id;
- $self->{'title'} = $title;
-
- return $self;
-}
-
-sub level
-{
- my ($self) = @_;
-
- return $self->{'level'};
-}
-
-sub number
-{
- my ($self) = @_;
-
- return $self->{'number'};
-}
-
-sub id
-{
- my ($self) = @_;
-
- return $self->{'id'};
-}
-
-sub title
-{
- my ($self) = @_;
-
- return $self->{'title'};
-}
-
-1;