From 17d095e78d3e0c04d22a88c7d213690209b4dc84 Mon Sep 17 00:00:00 2001 From: kts Date: Mon, 22 Dec 2014 18:22:52 -0800 Subject: [PATCH] Added .include functionality to block elements (paragraph, pre, code). In the case of the former, the given file is fully parsed and all parsed elements are inserted in the place of the calling block element. In the case of the latter block elements, the file is included but not parsed. Options/formatters are now hashes rather than var=value strings. --- kettext.pm | 99 +++++++++++++++++++++++++++++++++++++++++------- test/include.ktx | 24 +++++++++++- 2 files changed, 108 insertions(+), 15 deletions(-) diff --git a/kettext.pm b/kettext.pm index 12e8781..8121e95 100644 --- a/kettext.pm +++ b/kettext.pm @@ -23,6 +23,12 @@ sub parseFile { my @elements = (); # our list of ALL distinct elements my %block = (); # some block of data, such as paragraph, pre, etc. my %settings = (); + # get dirname for includes + my $dir_name = $file_name; + $dir_name =~ s/\/(.*)$/\//g; + if ($dir_name eq $file_name) { + $dir_name = "./"; + } # create file handler and read into @lines binmode STDOUT, ":utf8"; use utf8; @@ -49,16 +55,41 @@ sub parseFile { # code if ($2 eq '#') { if (!%block) { - if ($3 =~ m/^([^\s]*)(\..*\)(\s|))(.*)/) { - %block = (type => TYPE_CODE, text => $3, opts => parseOptions($2)); + #if ($3 =~ m/^([^\s]*)(\..*\)(\s|))(.*)/) { + if ($3 =~ m/^(\..*?\)(?:\s|\n|))(.*?)/) { + %block = (type => TYPE_CODE, text => $2, opts => parseOptions($1)); + if (exists ${$block{'opts'}}{'include'}) { + my $include = $dir_name.${$block{'opts'}}{'include'}; + if (open(my $fh, '<:encoding(UTF-8)', $include)) { + while (my $row = <$fh>) { + chomp $row; + $block{'text'} .= "$row\n"; + } + } else { + print $file_name; + $block{'text'} .= "Could not read ".$include."\n"; + } + delete ${$block{'opts'}}{'include'}; + } } else { %block = (type => TYPE_CODE, text => $3); } } else { if ($block{"type"} != TYPE_CODE) { push @elements, {%block}; - if ($3 =~ m/^([^\s*])(\..*\)(\s|))(.*)/) { + if ($3 =~ m/^(\..*?\)(?:\s|\n|))(.*?)/) { %block = (type => TYPE_CODE, text => $3, opts => parseOptions($2)); + if (${$block{'opts'}}{'include'}) { + if (open(my $fh, '<:encoding(UTF-8)', ${$block{'opts'}}{'include'})) { + while (my $row = <$fh>) { + chomp $row; + $block{'text'} .= "$row\n"; + } + } else { + $block{'text'} .= "Could not read ".${$block{'opts'}}{'include'}."\n"; + } + delete ${$block{'opts'}}{'include'}; + } } else { %block = (type => TYPE_CODE, text => $3); } @@ -110,6 +141,19 @@ sub parseFile { if (!%block) { if ($2 eq '.' && $3 =~ m/^(.*\)(\s|))(.*)/) { %block = (type => TYPE_PRE, text => $3, opts => parseOptions('.'.$1)); + if (exists ${$block{'opts'}}{'include'}) { + my $include = $dir_name.${$block{'opts'}}{'include'}; + if (open(my $fh, '<:encoding(UTF-8)', $include)) { + while (my $row = <$fh>) { + chomp $row; + $block{'text'} .= "$row\n"; + } + } else { + print $file_name; + $block{'text'} .= "Could not read ".$include."\n"; + } + delete ${$block{'opts'}}{'include'}; + } } else { %block = (type => TYPE_PRE, text => $2.$3); } @@ -118,6 +162,19 @@ sub parseFile { push @elements, {%block}; %block=(); if ($2 eq '.' && $3 =~ m/^(.*\)(\s|))(.*)/) { %block = (type => TYPE_PRE, text => $3, opts => parseOptions('.'.$1)); + if (exists ${$block{'opts'}}{'include'}) { + my $include = $dir_name.${$block{'opts'}}{'include'}; + if (open(my $fh, '<:encoding(UTF-8)', $include)) { + while (my $row = <$fh>) { + chomp $row; + $block{'text'} .= "$row\n"; + } + } else { + print $file_name; + $block{'text'} .= "Could not read ".$include."\n"; + } + delete ${$block{'opts'}}{'include'}; + } } else { %block = (type => TYPE_PRE, text => $2.$3); } @@ -250,6 +307,13 @@ sub parseFile { if (!%block) { if ($lines[$i] =~ m/^(\..*\)(\s|))(.*)/) { %block = (type => TYPE_PARAGRAPH, text => $2, opts => parseOptions($1)); + if (${$block{'opts'}}{'include'}) { + my %sub_file = kettext::parseFile($dir_name.${$block{'opts'}}{'include'}, \%cmd_settings); + for my $i (0 .. $#{$sub_file{'elements'}}) { + push @elements, ${$sub_file{'elements'}}[$i]; + } + delete ${$block{'opts'}}{'include'}; + } } else { %block = (type => TYPE_PARAGRAPH, text => $lines[$i]); } @@ -328,11 +392,11 @@ sub parseFile { } sub parseOptions { my $text = $_[0]; - my $opts; + my %opts = (); while ($text =~ m/(\.)([a-zA-Z]*[^\(])(\()([^\)]*)/g) { - $opts.=" $2=\"$4\""; + $opts{$2} = $4; } - return $opts; + return \%opts; } package kettext::convertTo; @@ -373,7 +437,7 @@ sub HTML { if ($_->{type} == kettext::TYPE_HEADER) { my $hid = $_->{text}; $hid =~ s/ /_/g; - print("{hsize}".($_->{opts} ? $_->{opts} : '').($settings{'header.ids'} ? " id=\"".$hid."\"" : '').">".convertText($_->{text})."{hsize}>\n"); + print("{hsize}".($_->{opts} ? convertOpts($_->{opts}) : '').($settings{'header.ids'} ? " id=\"".$hid."\"" : '').">".convertText($_->{text})."{hsize}>\n"); } elsif ($_->{type} == kettext::TYPE_BREAK) { if ($previous_type == kettext::TYPE_BREAK) { print("
\n"); @@ -381,13 +445,13 @@ sub HTML { } elsif ($_->{type} == kettext::TYPE_PARAGRAPH) { my $text = convertText($_->{text}); $text =~ s/\n/
\n/g; - print("{opts} ? $_->{opts} : '').">$text

\n"); + print("{opts} ? convertOpts($_->{opts}) : '').">$text

\n"); } elsif ($_->{type} == kettext::TYPE_PRE) { - print("{opts} ? $_->{opts} : '').">$_->{text}\n"); + print("{opts} ? convertOpts($_->{opts}) : '').">$_->{text}\n"); } elsif ($_->{type} == kettext::TYPE_CODE) { - print("
{opts} ? $_->{opts} : '').">$_->{text}
\n"); + print("
{opts} ? convertOpts($_->{opts}) : '').">$_->{text}
\n"); } elsif ($_->{type} == kettext::TYPE_BLOCKQUOTE) { - print("{opts} ? $_->{opts} : '').">".($settings{'blockquote.parse'} ? convertText($_->{text}) : $_->{text})."\n"); + print("{opts} ? convertOpts($_->{opts}) : '').">".($settings{'blockquote.parse'} ? convertText($_->{text}) : $_->{text})."\n"); } elsif ($_->{type} == kettext::TYPE_SPACER) { print("
\n"); } elsif ($_->{type} == kettext::TYPE_LIST) { @@ -455,7 +519,7 @@ sub HTML { if ($4) { my $ts = substr($media[0], 0, -1); my $te = substr($media[0], -1); - $converted_text = $ts.kettext::parseOptions($4).$te.$media[1]; + $converted_text = $ts.convertOpts(kettext::parseOptions($4)).$te.$media[1]; } else { $converted_text = $media[0].$media[1]; } @@ -464,7 +528,7 @@ sub HTML { if ($4) { my $ts = substr($text_replace[$i], 0, -1); my $te = substr($text_replace[$i], -1); - $converted_text = $ts.kettext::parseOptions($4).$te.$2.$text_replace[$i+1]; + $converted_text = $ts.convertOpts(kettext::parseOptions($4)).$te.$2.$text_replace[$i+1]; } else { $converted_text = $text_replace[$i].$2.$text_replace[$i+1]; } @@ -494,6 +558,15 @@ sub HTML { } } } + sub convertOpts { + my $opts = $_[0]; + my $string = ""; + keys %{$opts}; + while (my ($key, $value) = each %{$opts}) { + $string .= " $key=\"$value\""; + } + return $string; + } # 2. check for (http(s)://)(www.)youtube/youtu.be/vimeo/etc. my @media = urlToMedia($text); if (!$media[0] eq "") { #"http://..." diff --git a/test/include.ktx b/test/include.ktx index f78e69d..5c10107 100644 --- a/test/include.ktx +++ b/test/include.ktx @@ -1,3 +1,23 @@ -This file includes "spacer.ktx" +This file includes "spacer.ktx" using the following line: -.include(spacer.ktx).imply(header.depth=1,version.hide) +,,,,,,,,,,,,,,,,,,,,,,,, +Code include +```````````````````````` + # .include(spacer.ktx) + + #.include(spacer.ktx) + +,,,,,,,,,,,,,,,,,,,,,,,, +Pre include +```````````````````````` + .include(spacer.ktx) + + .include(spacer.ktx) + +,,,,,,,,,,,,,,,,,,,,,,,, +Paragraph include +```````````````````````` + .include(spacer.ktx) + +.include(spacer.ktx) +Yes.