| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package WRT::Markup; | 
| 2 |  |  |  |  |  |  |  | 
| 3 | 3 |  |  | 3 |  | 17 | use strict; | 
|  | 3 |  |  |  |  | 6 |  | 
|  | 3 |  |  |  |  | 76 |  | 
| 4 | 3 |  |  | 3 |  | 13 | use warnings; | 
|  | 3 |  |  |  |  | 6 |  | 
|  | 3 |  |  |  |  | 89 |  | 
| 5 | 3 |  |  | 3 |  | 15 | use feature "state"; | 
|  | 3 |  |  |  |  | 4 |  | 
|  | 3 |  |  |  |  | 257 |  | 
| 6 |  |  |  |  |  |  |  | 
| 7 | 3 |  |  | 3 |  | 16 | use base qw(Exporter); | 
|  | 3 |  |  |  |  | 5 |  | 
|  | 3 |  |  |  |  | 293 |  | 
| 8 |  |  |  |  |  |  | our @EXPORT_OK = qw(line_parse image_markup eval_perl); | 
| 9 |  |  |  |  |  |  |  | 
| 10 | 3 |  |  | 3 |  | 18 | use File::Basename; | 
|  | 3 |  |  |  |  | 3 |  | 
|  | 3 |  |  |  |  | 185 |  | 
| 11 | 3 |  |  | 3 |  | 1697 | use Text::Textile; | 
|  | 3 |  |  |  |  | 107276 |  | 
|  | 3 |  |  |  |  | 127 |  | 
| 12 | 3 |  |  | 3 |  | 722 | use Text::Markdown::Discount; | 
|  | 3 |  |  |  |  | 1987 |  | 
|  | 3 |  |  |  |  | 147 |  | 
| 13 |  |  |  |  |  |  |  | 
| 14 | 3 |  |  | 3 |  | 20 | use WRT::Image qw(image_size); | 
|  | 3 |  |  |  |  | 5 |  | 
|  | 3 |  |  |  |  | 3619 |  | 
| 15 |  |  |  |  |  |  |  | 
| 16 |  |  |  |  |  |  | # Some useful defaults: | 
| 17 |  |  |  |  |  |  |  | 
| 18 |  |  |  |  |  |  | my %tags = ( | 
| 19 |  |  |  |  |  |  | retcon    => q{div class="retcon"}, | 
| 20 |  |  |  |  |  |  | freeverse => 'p', | 
| 21 |  |  |  |  |  |  | list      => "ul>\n<li" | 
| 22 |  |  |  |  |  |  | ); | 
| 23 |  |  |  |  |  |  |  | 
| 24 |  |  |  |  |  |  | my %end_tags = ( | 
| 25 |  |  |  |  |  |  | retcon    => 'div', | 
| 26 |  |  |  |  |  |  | freeverse => 'p', | 
| 27 |  |  |  |  |  |  | list      => "li>\n</ul" | 
| 28 |  |  |  |  |  |  | ); | 
| 29 |  |  |  |  |  |  |  | 
| 30 |  |  |  |  |  |  | my %blank_lines = ( | 
| 31 |  |  |  |  |  |  | freeverse => "</p>\n\n<p>", | 
| 32 |  |  |  |  |  |  | list      => "</li>\n\n<li>" | 
| 33 |  |  |  |  |  |  | ); | 
| 34 |  |  |  |  |  |  |  | 
| 35 |  |  |  |  |  |  | my %newlines = ( | 
| 36 |  |  |  |  |  |  | freeverse => "<br />\n" | 
| 37 |  |  |  |  |  |  | ); | 
| 38 |  |  |  |  |  |  |  | 
| 39 |  |  |  |  |  |  | my %dashes = ( | 
| 40 |  |  |  |  |  |  | freeverse => ' — ' | 
| 41 |  |  |  |  |  |  | ); | 
| 42 |  |  |  |  |  |  |  | 
| 43 |  |  |  |  |  |  | =item line_parse | 
| 44 |  |  |  |  |  |  |  | 
| 45 |  |  |  |  |  |  | Performs substitutions on lines called by fragment_slurp, at least.  Calls | 
| 46 |  |  |  |  |  |  | image_markup(), textile_process(), markdown_process(). | 
| 47 |  |  |  |  |  |  |  | 
| 48 |  |  |  |  |  |  | Returns string. | 
| 49 |  |  |  |  |  |  |  | 
| 50 |  |  |  |  |  |  | Parses some special markup, specifically: | 
| 51 |  |  |  |  |  |  |  | 
| 52 |  |  |  |  |  |  | <textile></textile> - Text::Textile to HTML | 
| 53 |  |  |  |  |  |  | <markdown></markdown> - Text::Markdown::Discount to HTML | 
| 54 |  |  |  |  |  |  | <freeverse></freeverse> | 
| 55 |  |  |  |  |  |  | <retcon></retcon> | 
| 56 |  |  |  |  |  |  | <list></list> | 
| 57 |  |  |  |  |  |  |  | 
| 58 |  |  |  |  |  |  | <image>filename.ext | 
| 59 |  |  |  |  |  |  | optional alt tag | 
| 60 |  |  |  |  |  |  | optional title text</image> | 
| 61 |  |  |  |  |  |  |  | 
| 62 |  |  |  |  |  |  | ${variable} interpolation from the WRT object | 
| 63 |  |  |  |  |  |  | <perl>print "hello world";</perl> | 
| 64 |  |  |  |  |  |  | <include>path/to/file/from/project/root</include> | 
| 65 |  |  |  |  |  |  |  | 
| 66 |  |  |  |  |  |  | =cut | 
| 67 |  |  |  |  |  |  |  | 
| 68 |  |  |  |  |  |  | sub line_parse { | 
| 69 | 35 |  |  | 35 | 1 | 40 | my $self = shift; | 
| 70 | 35 |  |  |  |  | 56 | my ($everything, $file) = (@_); | 
| 71 |  |  |  |  |  |  |  | 
| 72 |  |  |  |  |  |  | # Take care of <include>, <textile>, <markdown>, and <image> tags: | 
| 73 | 35 |  |  |  |  | 87 | include_process($self, $everything); | 
| 74 | 35 |  |  |  |  | 76 | textile_process($everything); | 
| 75 | 35 |  |  |  |  | 2190 | markdown_process($everything); | 
| 76 | 35 |  |  |  |  | 224 | $everything =~ s!<image>(.*?)</image>!$self->image_markup($file, $1)!seg; | 
|  | 1 |  |  |  |  | 8 |  | 
| 77 |  |  |  |  |  |  |  | 
| 78 | 35 |  |  |  |  | 119 | foreach my $key (keys %tags) { | 
| 79 |  |  |  |  |  |  | # Set some replacements, unless they've been explicitly set already: | 
| 80 | 105 |  | 33 |  |  | 194 | $end_tags{$key}    ||= $tags{$key}; | 
| 81 | 105 |  | 100 |  |  | 164 | $blank_lines{$key} ||= "\n\n"; | 
| 82 | 105 |  | 100 |  |  | 147 | $newlines{$key}    ||= "\n"; | 
| 83 | 105 |  | 100 |  |  | 146 | $dashes{$key}      ||= " -- "; | 
| 84 |  |  |  |  |  |  |  | 
| 85 |  |  |  |  |  |  | # Transform blocks: | 
| 86 | 105 |  |  |  |  | 1235 | while ($everything =~ m/(<$key>.*?<\/$key>)/s) { | 
| 87 | 2 |  |  |  |  | 5 | my $block = $1; | 
| 88 |  |  |  |  |  |  |  | 
| 89 |  |  |  |  |  |  | # Save the bits between instances of the block: | 
| 90 | 2 |  |  |  |  | 20 | my (@interstices) = split /\Q$block\E/s, $everything; | 
| 91 |  |  |  |  |  |  |  | 
| 92 |  |  |  |  |  |  | # Tags that surround the block: | 
| 93 | 2 |  |  |  |  | 31 | $block =~ s{\n?<$key>\n?}{<$tags{$key}>}gs; | 
| 94 | 2 |  |  |  |  | 24 | $block =~ s{\n?</$key>\n?}{</$end_tags{$key}>}gs; | 
| 95 |  |  |  |  |  |  |  | 
| 96 |  |  |  |  |  |  | # Dashes, blank lines, and newlines: | 
| 97 | 2 |  |  |  |  | 6 | $block = dashes($dashes{$key}, $block); | 
| 98 | 2 |  |  |  |  | 7 | $block =~ s/\n\n/$blank_lines{$key}/gs; | 
| 99 | 2 |  |  |  |  | 4 | $block = newlines($newlines{$key}, $block); | 
| 100 |  |  |  |  |  |  |  | 
| 101 |  |  |  |  |  |  | # ...and slap it all back together as $everything | 
| 102 | 2 |  |  |  |  | 11 | $everything = join $block, @interstices; | 
| 103 |  |  |  |  |  |  | } | 
| 104 |  |  |  |  |  |  | } | 
| 105 |  |  |  |  |  |  |  | 
| 106 | 35 |  |  |  |  | 233 | return $everything; | 
| 107 |  |  |  |  |  |  | } | 
| 108 |  |  |  |  |  |  |  | 
| 109 |  |  |  |  |  |  | =item eval_perl | 
| 110 |  |  |  |  |  |  |  | 
| 111 |  |  |  |  |  |  | Evaluate embedded Perl in a string, replacing blocks enclosed with <perl> tags | 
| 112 |  |  |  |  |  |  | with whatever they return (well, evaluated in a scalar context). Returns the | 
| 113 |  |  |  |  |  |  | modified string. | 
| 114 |  |  |  |  |  |  |  | 
| 115 |  |  |  |  |  |  | Also handles simple ${variables}, replacing them from the keys to $self. | 
| 116 |  |  |  |  |  |  |  | 
| 117 |  |  |  |  |  |  | =cut | 
| 118 |  |  |  |  |  |  |  | 
| 119 |  |  |  |  |  |  | sub eval_perl { | 
| 120 | 35 |  |  | 35 | 1 | 51 | my $self = shift; | 
| 121 | 35 |  |  |  |  | 53 | my ($text) = @_; | 
| 122 |  |  |  |  |  |  |  | 
| 123 | 35 |  |  |  |  | 159 | while ($text =~ m{<perl>(.*?)</perl>}s) { | 
| 124 | 15 |  |  |  |  | 38 | my $block = $1; | 
| 125 |  |  |  |  |  |  |  | 
| 126 |  |  |  |  |  |  | # Run the $block, and include anything returned: | 
| 127 | 15 |  |  |  |  | 895 | my $output = eval $block; | 
| 128 |  |  |  |  |  |  |  | 
| 129 | 15 | 50 |  |  |  | 62 | if ($@) { | 
| 130 |  |  |  |  |  |  | # Errors - log and return an empty string: | 
| 131 | 0 |  |  |  |  | 0 | print STDERR $@; | 
| 132 | 0 |  |  |  |  | 0 | $output = ''; | 
| 133 |  |  |  |  |  |  | } | 
| 134 |  |  |  |  |  |  |  | 
| 135 | 15 |  |  |  |  | 181 | $text =~ s{<perl>\Q$block\E</perl>}{$output}s; | 
| 136 |  |  |  |  |  |  | } | 
| 137 |  |  |  |  |  |  |  | 
| 138 |  |  |  |  |  |  | # Interpolate variables: | 
| 139 | 35 |  |  |  |  | 92 | $text =~ s{ | 
| 140 |  |  |  |  |  |  | \$\{ ([a-zA-Z_]+) \} | 
| 141 |  |  |  |  |  |  | }{ | 
| 142 | 126 | 50 |  |  |  | 217 | if (defined $self->{$1}) { | 
| 143 | 126 |  |  |  |  | 354 | $self->{$1}; | 
| 144 |  |  |  |  |  |  | } else { | 
| 145 |  |  |  |  |  |  | # TODO:  Possibly this should be fatal. | 
| 146 | 0 |  |  |  |  | 0 | "UNDEFINED: $1"; | 
| 147 |  |  |  |  |  |  | } | 
| 148 |  |  |  |  |  |  | }gex; | 
| 149 |  |  |  |  |  |  |  | 
| 150 | 35 |  |  |  |  | 132 | return $text; | 
| 151 |  |  |  |  |  |  | } | 
| 152 |  |  |  |  |  |  |  | 
| 153 |  |  |  |  |  |  | sub newlines { | 
| 154 | 2 |  |  | 2 | 0 | 4 | my ($replacement, $block) = @_; | 
| 155 |  |  |  |  |  |  |  | 
| 156 |  |  |  |  |  |  | # Single newlines (i.e., line ends) within the block, | 
| 157 |  |  |  |  |  |  | # except those preceded by a double-quote, which probably | 
| 158 |  |  |  |  |  |  | # indicates a still-open tag: | 
| 159 |  |  |  |  |  |  |  | 
| 160 | 2 |  |  |  |  | 9 | $block =~ s/(?<=[^"\n])  # not a double-quote or newline | 
| 161 |  |  |  |  |  |  | # don't capture | 
| 162 |  |  |  |  |  |  |  | 
| 163 |  |  |  |  |  |  | \n           # end-of-line | 
| 164 |  |  |  |  |  |  |  | 
| 165 |  |  |  |  |  |  | (?=[^\n])    # not a newline | 
| 166 |  |  |  |  |  |  | # don't capture | 
| 167 |  |  |  |  |  |  | /$replacement/xgs; | 
| 168 |  |  |  |  |  |  |  | 
| 169 | 2 |  |  |  |  | 5 | return $block; | 
| 170 |  |  |  |  |  |  |  | 
| 171 |  |  |  |  |  |  | } | 
| 172 |  |  |  |  |  |  |  | 
| 173 |  |  |  |  |  |  | # might need a rewrite. | 
| 174 |  |  |  |  |  |  | sub dashes { | 
| 175 | 2 |  |  | 2 | 0 | 5 | my ($replacement, $block) =@_; | 
| 176 |  |  |  |  |  |  |  | 
| 177 | 2 |  |  |  |  | 3 | $block =~ s/(\s+)      # whitespace - no capture | 
| 178 |  |  |  |  |  |  | \-{2}      # two dashes | 
| 179 |  |  |  |  |  |  | (\n|\s+|$) # newline, whitespace, or eol | 
| 180 |  |  |  |  |  |  | /$1${replacement}$2/xgs; | 
| 181 |  |  |  |  |  |  |  | 
| 182 | 2 |  |  |  |  | 5 | return $block; | 
| 183 |  |  |  |  |  |  | } | 
| 184 |  |  |  |  |  |  |  | 
| 185 |  |  |  |  |  |  | =item include_process | 
| 186 |  |  |  |  |  |  |  | 
| 187 |  |  |  |  |  |  | Inline replace <include>filename</include> tags, replacing them with the | 
| 188 |  |  |  |  |  |  | contents of files. | 
| 189 |  |  |  |  |  |  |  | 
| 190 |  |  |  |  |  |  | =cut | 
| 191 |  |  |  |  |  |  |  | 
| 192 |  |  |  |  |  |  | sub include_process { | 
| 193 | 35 |  |  | 35 | 1 | 37 | my $wrt = shift; | 
| 194 |  |  |  |  |  |  |  | 
| 195 | 35 |  |  |  |  | 82 | $_[0] =~ s{ | 
| 196 |  |  |  |  |  |  |  | 
| 197 |  |  |  |  |  |  | <include>  # start tag | 
| 198 |  |  |  |  |  |  | (.*?)     # anything (non-greedy) | 
| 199 |  |  |  |  |  |  | </include> # end tag | 
| 200 |  |  |  |  |  |  |  | 
| 201 |  |  |  |  |  |  | }{ | 
| 202 | 3 |  |  |  |  | 10 | retrieve_include($wrt, $1); | 
| 203 |  |  |  |  |  |  | }xesg; | 
| 204 |  |  |  |  |  |  | } | 
| 205 |  |  |  |  |  |  |  | 
| 206 |  |  |  |  |  |  | =item retrieve_include | 
| 207 |  |  |  |  |  |  |  | 
| 208 |  |  |  |  |  |  | Get the contents of an included file.  This probably needs a great | 
| 209 |  |  |  |  |  |  | deal more thought than I am presently giving it. | 
| 210 |  |  |  |  |  |  |  | 
| 211 |  |  |  |  |  |  | =cut | 
| 212 |  |  |  |  |  |  |  | 
| 213 |  |  |  |  |  |  | sub retrieve_include { | 
| 214 | 3 |  |  | 3 | 1 | 6 | my $wrt = shift; | 
| 215 | 3 |  |  |  |  | 9 | my ($file) = @_; | 
| 216 |  |  |  |  |  |  |  | 
| 217 |  |  |  |  |  |  | # Trim leading and trailing spaces: | 
| 218 | 3 |  |  |  |  | 7 | $file =~ s/^\s+//; | 
| 219 | 3 |  |  |  |  | 7 | $file =~ s/\s+$//; | 
| 220 |  |  |  |  |  |  |  | 
| 221 | 3 | 50 |  |  |  | 11 | if ($file =~ m{^ (/ | [.]/) }x) { | 
| 222 |  |  |  |  |  |  | # TODO: Leads with a slash or a ./ | 
| 223 | 0 |  |  |  |  | 0 | die('Tried to open an include path with a leading / or ./ - not yet supported.'); | 
| 224 |  |  |  |  |  |  | } else { | 
| 225 |  |  |  |  |  |  | # Use the archive root as path. | 
| 226 | 3 |  |  |  |  | 11 | $file = $wrt->root_dir . '/' . $file; | 
| 227 |  |  |  |  |  |  | } | 
| 228 |  |  |  |  |  |  |  | 
| 229 | 3 | 50 |  |  |  | 34 | unless (-e $file) { | 
| 230 | 0 |  |  |  |  | 0 | warn "No such file: $file"; | 
| 231 | 0 |  |  |  |  | 0 | return ''; | 
| 232 |  |  |  |  |  |  | } | 
| 233 |  |  |  |  |  |  |  | 
| 234 | 3 | 50 |  |  |  | 17 | if (-d $file) { | 
| 235 | 0 |  |  |  |  | 0 | die("Tried to open a directory as an include path: $file"); | 
| 236 |  |  |  |  |  |  | } | 
| 237 |  |  |  |  |  |  |  | 
| 238 | 3 | 50 |  |  |  | 70 | open my $fh, '<', $file | 
| 239 |  |  |  |  |  |  | or warn "Couldn't open $file: $!\n"; | 
| 240 |  |  |  |  |  |  |  | 
| 241 | 3 |  |  |  |  | 5 | my $file_contents; | 
| 242 |  |  |  |  |  |  | { | 
| 243 |  |  |  |  |  |  | # line separator: | 
| 244 | 3 |  |  |  |  | 5 | local $/ = undef; | 
|  | 3 |  |  |  |  | 11 |  | 
| 245 | 3 |  |  |  |  | 37 | $file_contents = <$fh>; | 
| 246 |  |  |  |  |  |  | } | 
| 247 |  |  |  |  |  |  |  | 
| 248 | 3 | 50 |  |  |  | 18 | close $fh or warn "Couldn't close $file: $!"; | 
| 249 |  |  |  |  |  |  |  | 
| 250 | 3 |  |  |  |  | 18 | return $file_contents; | 
| 251 |  |  |  |  |  |  | } | 
| 252 |  |  |  |  |  |  |  | 
| 253 |  |  |  |  |  |  | =item textile_process | 
| 254 |  |  |  |  |  |  |  | 
| 255 |  |  |  |  |  |  | Inline replace <textile> markup in a string. | 
| 256 |  |  |  |  |  |  |  | 
| 257 |  |  |  |  |  |  | =cut | 
| 258 |  |  |  |  |  |  |  | 
| 259 |  |  |  |  |  |  | # This is exactly the kind of code that, even though it isn't doing anything | 
| 260 |  |  |  |  |  |  | # especially insane, looks ghastly to people who don't read Perl, so I'll try | 
| 261 |  |  |  |  |  |  | # to explain a bit. | 
| 262 |  |  |  |  |  |  |  | 
| 263 |  |  |  |  |  |  | sub textile_process { | 
| 264 |  |  |  |  |  |  |  | 
| 265 |  |  |  |  |  |  | # First, there's a state variable here which can retain the Text::Textile | 
| 266 |  |  |  |  |  |  | # object between invocations, saving us a bit of time on subsequent calls. | 
| 267 |  |  |  |  |  |  | # This should be equivalent to creating a closure around the function and | 
| 268 |  |  |  |  |  |  | # keeping a $textile variable there. | 
| 269 | 35 |  |  | 35 | 1 | 33 | state $textile; | 
| 270 |  |  |  |  |  |  |  | 
| 271 |  |  |  |  |  |  | # Second, instead of unrolling the arguments to the function, we just act | 
| 272 |  |  |  |  |  |  | # directly on the first (0th) one.  =~ more or less means "do a regexy | 
| 273 |  |  |  |  |  |  | # thing on this".  It's followed by s, the substitution operator, which can | 
| 274 |  |  |  |  |  |  | # use curly braces as delimiters between pattern and replacement. | 
| 275 |  |  |  |  |  |  |  | 
| 276 | 35 |  |  |  |  | 76 | $_[0] =~ s{ | 
| 277 |  |  |  |  |  |  |  | 
| 278 |  |  |  |  |  |  | # find tags... | 
| 279 |  |  |  |  |  |  |  | 
| 280 |  |  |  |  |  |  | <textile>  # start tag | 
| 281 |  |  |  |  |  |  | (.*?)    # anything (non-greedy) | 
| 282 |  |  |  |  |  |  | </textile> # end tag | 
| 283 |  |  |  |  |  |  |  | 
| 284 |  |  |  |  |  |  | }{ | 
| 285 |  |  |  |  |  |  |  | 
| 286 |  |  |  |  |  |  | # ...and replace them with the result of evaluating this block. | 
| 287 |  |  |  |  |  |  |  | 
| 288 |  |  |  |  |  |  | # //= means "defined-or-equals"; if the var hasn't been defined yet, | 
| 289 |  |  |  |  |  |  | # then make a new Textile object: | 
| 290 | 1 |  | 33 |  |  | 11 | $textile //= Text::Textile->new(); | 
| 291 |  |  |  |  |  |  |  | 
| 292 |  |  |  |  |  |  | # Process the stuff we slurped out of our tags - this value will be | 
| 293 |  |  |  |  |  |  | # used to replace the entire match from above (in Perl, the last | 
| 294 |  |  |  |  |  |  | # expression evaluated is the return value of subs, evals, etc.): | 
| 295 | 1 |  |  |  |  | 188 | $textile->process($1); | 
| 296 |  |  |  |  |  |  |  | 
| 297 |  |  |  |  |  |  | }xesg; | 
| 298 |  |  |  |  |  |  |  | 
| 299 |  |  |  |  |  |  | # x: eXtended regexp - whitespace ignored by default, comments allowed | 
| 300 |  |  |  |  |  |  | # e: Execute the replacement as Perl code, and use its value | 
| 301 |  |  |  |  |  |  | # s: treat all lines of the search subject as a Single string | 
| 302 |  |  |  |  |  |  | # g: Globally replace all matches | 
| 303 |  |  |  |  |  |  |  | 
| 304 |  |  |  |  |  |  | # For the genuinely concise version of this, see markdown_process(). | 
| 305 |  |  |  |  |  |  | } | 
| 306 |  |  |  |  |  |  |  | 
| 307 |  |  |  |  |  |  | =item markdown_process | 
| 308 |  |  |  |  |  |  |  | 
| 309 |  |  |  |  |  |  | Inline replace <markdown> markup in a string. | 
| 310 |  |  |  |  |  |  |  | 
| 311 |  |  |  |  |  |  | =cut | 
| 312 |  |  |  |  |  |  |  | 
| 313 |  |  |  |  |  |  | sub markdown_process { | 
| 314 | 35 |  |  | 35 | 1 | 36 | state $markdown; | 
| 315 |  |  |  |  |  |  |  | 
| 316 | 35 |  |  |  |  | 41 | my $flags = Text::Markdown::Discount::MKD_EXTRA_FOOTNOTE(); | 
| 317 |  |  |  |  |  |  |  | 
| 318 | 35 |  |  |  |  | 87 | $_[0] =~ s{ | 
| 319 |  |  |  |  |  |  | <markdown>(.*?)</markdown> | 
| 320 |  |  |  |  |  |  | }{ | 
| 321 | 5 |  | 66 |  |  | 37 | $markdown //= Text::Markdown::Discount->new; | 
| 322 | 5 |  |  |  |  | 45 | $markdown->markdown($1, $flags); | 
| 323 |  |  |  |  |  |  | }xesg; | 
| 324 |  |  |  |  |  |  | } | 
| 325 |  |  |  |  |  |  |  | 
| 326 |  |  |  |  |  |  | =item image_markup | 
| 327 |  |  |  |  |  |  |  | 
| 328 |  |  |  |  |  |  | Parse out an image tag and return the appropriate html. | 
| 329 |  |  |  |  |  |  |  | 
| 330 |  |  |  |  |  |  | Relies on image_size from WRT::Image. | 
| 331 |  |  |  |  |  |  |  | 
| 332 |  |  |  |  |  |  | =cut | 
| 333 |  |  |  |  |  |  |  | 
| 334 |  |  |  |  |  |  | sub image_markup { | 
| 335 | 1 |  |  | 1 | 1 | 3 | my $self = shift; | 
| 336 | 1 |  |  |  |  | 6 | my ($file, $block) = @_; | 
| 337 |  |  |  |  |  |  |  | 
| 338 |  |  |  |  |  |  | # Get a basename and directory for the file referencing the image: | 
| 339 | 1 |  |  |  |  | 18 | my ($basename, $dir) = fileparse($file); | 
| 340 |  |  |  |  |  |  |  | 
| 341 |  |  |  |  |  |  | # Truncated file date that just includes date + sub docs: | 
| 342 | 1 |  |  |  |  | 4 | my ($file_date) = $dir =~ m{ | 
| 343 |  |  |  |  |  |  | ( | 
| 344 |  |  |  |  |  |  | [0-9]{4}/   # year | 
| 345 |  |  |  |  |  |  | [0-9]{1,2}/ # month | 
| 346 |  |  |  |  |  |  | [0-9]{1,2}/ # day | 
| 347 |  |  |  |  |  |  | ([a-z]*/)*  # sub-entries | 
| 348 |  |  |  |  |  |  | ) | 
| 349 |  |  |  |  |  |  | $ | 
| 350 |  |  |  |  |  |  | }x; | 
| 351 |  |  |  |  |  |  |  | 
| 352 |  |  |  |  |  |  | # Process the contents of the <image> tag: | 
| 353 | 1 |  |  |  |  | 6 | my ($image_url, $alt_text, $title_text) = split /\n/, $block; | 
| 354 | 1 |  | 50 |  |  | 10 | $alt_text   ||= q{}; | 
| 355 | 1 |  | 33 |  |  | 13 | $title_text ||= $alt_text; | 
| 356 |  |  |  |  |  |  |  | 
| 357 |  |  |  |  |  |  | # Resolve relative paths: | 
| 358 | 1 |  |  |  |  | 3 | my $image_file; | 
| 359 | 1 | 50 |  |  |  | 30 | if (-e "$dir/$image_url" ) { | 
|  |  | 50 |  |  |  |  |  | 
| 360 | 0 |  |  |  |  | 0 | $image_file = "$dir/$image_url"; | 
| 361 | 0 |  |  |  |  | 0 | $image_url = "${file_date}${image_url}"; | 
| 362 |  |  |  |  |  |  | } elsif (-e $self->entry_dir . "/$image_url") { | 
| 363 | 1 |  |  |  |  | 7 | $image_file = $self->entry_dir . "/$image_url"; | 
| 364 |  |  |  |  |  |  | } | 
| 365 |  |  |  |  |  |  |  | 
| 366 |  |  |  |  |  |  | # Get width & height in pixels for known filetypes: | 
| 367 | 1 |  |  |  |  | 7 | my ($width, $height) = image_size($image_file); | 
| 368 |  |  |  |  |  |  |  | 
| 369 |  |  |  |  |  |  | # This probably relies on mod_rewrite working: | 
| 370 | 1 |  |  |  |  | 2539 | $image_url = $self->image_url_root . $image_url; | 
| 371 | 1 |  |  |  |  | 17 | return <<"IMG"; | 
| 372 |  |  |  |  |  |  | <img src="$image_url" | 
| 373 |  |  |  |  |  |  | width="$width" | 
| 374 |  |  |  |  |  |  | height="$height" | 
| 375 |  |  |  |  |  |  | alt="$alt_text" | 
| 376 |  |  |  |  |  |  | title="$title_text" /> | 
| 377 |  |  |  |  |  |  | IMG | 
| 378 |  |  |  |  |  |  | } | 
| 379 |  |  |  |  |  |  |  | 
| 380 |  |  |  |  |  |  | # Encapsulate some ugly file-location functionality. | 
| 381 |  |  |  |  |  |  | sub resolve_file { | 
| 382 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 383 | 0 |  |  |  |  |  | my ($filename) = @_; | 
| 384 |  |  |  |  |  |  |  | 
| 385 |  |  |  |  |  |  | # Get a basename and directory for the file: | 
| 386 | 0 |  |  |  |  |  | my ($basename, $dir) = fileparse($filename); | 
| 387 |  |  |  |  |  |  |  | 
| 388 |  |  |  |  |  |  | #if (-e "$dir/$image_url" ) { | 
| 389 |  |  |  |  |  |  | #$image_file = "$dir/$image_url"; | 
| 390 |  |  |  |  |  |  | #$image_url = "${file_date}${image_url}"; | 
| 391 |  |  |  |  |  |  | #} elsif (-e $self->entry_dir . "/$image_url") { | 
| 392 |  |  |  |  |  |  | #$image_file = $self->entry_dir . "/$image_url"; | 
| 393 |  |  |  |  |  |  | #} | 
| 394 |  |  |  |  |  |  |  | 
| 395 |  |  |  |  |  |  | } | 
| 396 |  |  |  |  |  |  |  | 
| 397 |  |  |  |  |  |  | 1; |