- package Display::Markup;
-
- use strict;
- use warnings;
-
- use base qw(Exporter);
- our @EXPORT_OK = qw(line_parse image_markup gallery);
-
- use File::Basename;
- use Display::Image qw(image_size gallery);
- use Text::Textile;
-
- # Some useful defaults:
-
- my %tags = (
- retcon => q{div class="retcon"},
- freeverse => 'p',
- list => "ul>\n<li"
- );
-
- my %end_tags = (
- retcon => 'div',
- freeverse => 'p',
- list => "li>\n</ul"
- );
-
- my %blank_lines = (
- freeverse => "</p>\n\n<p>",
- list => "</li>\n\n<li>"
- );
-
- my %newlines = (
- freeverse => "<br />\n"
- );
-
- my %dashes = (
- freeverse => ' — '
- );
-
- =item line_parse
-
- Performs substitutions on lines called by fragment_slurp, at least. Calls
- image_markup, Text::Textile, Wala::wiki_page_to_html, eval_perl. Returns
- string.
-
- Parses some special markup, specifically:
-
- <perl>embedded perl</perl>
- ${variable} interpolation from %DISPLAY_CONF
- <textile></textile> - Text::Textile to HTML
- <wala></wala> - Wala::wikify();
- <freeverse></freeverse>
- <retcon></retcon>
- <list></list>
-
- <gallery>directory_name</gallery>
-
- <image>filename.ext
- optional alt tag</image>
-
- =cut
-
- sub line_parse {
- my $self = shift;
- my ($everything, $file) = (@_);
-
- # Take care of <wala>, <textile>, <gallery>, and <image> tags:
-
- #$everything =~ s/<wala>(.*?)<\/wala>/Wala::wikify($1)/seg;
- textile_process($everything);
- $everything =~ s!<gallery>(.*?)</gallery>!$self->gallery_markup($file, $1)!seg;
- $everything =~ s!<image>(.*?)</image>!$self->image_markup($file, $1)!seg;
-
- foreach my $key (keys %tags) {
- # Set some replacements, unless they've been explicitly set already:
- $end_tags{$key} ||= $tags{$key};
- $blank_lines{$key} ||= "\n\n";
- $newlines{$key} ||= "\n";
- $dashes{$key} ||= " -- ";
-
- # Transform blocks:
- while ($everything =~ m/(<$key>.*?<\/$key>)/s) {
- my $block = $1;
-
- # Save the bits between instances of the block:
- my (@interstices) = split /\Q$block\E/s, $everything;
-
- # Tags that surround the block:
- $block =~ s{\n?<$key>\n?}{<$tags{$key}>}gs;
- $block =~ s{\n?</$key>\n?}{</$end_tags{$key}>}gs;
-
- # Dashes, blank lines, and newlines:
- $block = dashes($dashes{$key}, $block);
- $block =~ s/\n\n/$blank_lines{$key}/gs;
- $block = newlines($newlines{$key}, $block);
-
- # ...and slap it all back together as $everything
- $everything = join $block, @interstices;
- }
- }
-
- return $everything;
- }
-
- sub newlines {
- my ($replacement, $block) = @_;
-
- # Single newlines (i.e., line ends) within the block,
- # except those preceded by a double-quote, which probably
- # indicates a still-open tag:
-
- $block =~ s/(?<=[^"\n]) # not a double-quote or newline
- # don't capture
-
- \n # end-of-line
-
- (?=[^\n]) # not a newline
- # don't capture
- /$replacement/xgs;
-
- return $block;
-
- }
-
- # might need a rewrite.
- sub dashes {
- my ($replacement, $block) =@_;
-
- $block =~ s/(\s+) # whitespace - no capture
- \-{2} # two dashes
- (\n|\s+|$) # newline, whitespace, or eol
- /$1${replacement}$2/xgs;
-
- return $block;
-
- }
-
- =item textile_process
-
- Inline replace <textile> markup in a string.
-
- Trying to implement some caching here, though it's questionable whether
- this makes any sense. There's also a closure which should retain the
- Text::Textile object between invocations, potentially saving some time at
- the expense of a little memory.
-
- =cut
-
- { my %cache;
- my $textile;
-
- sub textile_process {
- my $replacement;
-
- unless (defined $textile) {
- # head_offset: use h1., h2. in Textile formatting:
- $textile = Text::Textile->new( head_offset => 2 );
- }
-
- while ( $_[0] =~ m/<textile>(.*?)<\/textile>/sx ) {
- my $block = $1;
-
- if (exists $cache{$block}) {
- $replacement = $cache{$block};
- } else {
- $replacement = $textile->process($block);
- $cache{$block} = $replacement;
- }
-
- $_[0] =~ s/<textile>\Q$block\E<\/textile>/$replacement/sg;
- }
-
- return;
-
- }
-
- }
-
-
- =item image_markup
-
- Parse out an image tag and return the appropriate html.
-
- Relies on image_size from Display::Image.
-
- =cut
-
- sub image_markup {
- my $self = shift;
- my ($file, $block) = @_;
-
- # Get a basename and directory for the file referencing the image:
- my ($basename, $dir) = fileparse($file);
-
- # Truncated file date that just includes date + sub docs:
- my ($file_date) = $dir =~ m{([0-9]{4}/ # year
- [0-9]{1,2}/ # month
- [0-9]{1,2}/ # day
- ([a-z]*/)*)$ # sub-entries
- }x;
-
- # Process the contents of the <image> tag:
- my ($image_url, $alt_text, $title_text) = split /\n/, $block;
- $alt_text ||= q{};
- $title_text ||= $alt_text;
-
- # Resolve relative paths:
- my $image_file;
- if (-e "$dir/$image_url" ) {
- $image_file = "$dir/$image_url";
- $image_url = "${file_date}${image_url}";
- } elsif (-e $self->root_dir . "/$image_url") {
- $image_file = $self->root_dir . "/$image_url";
- }
-
- # Get width & height in pixels for known filetypes:
- my ($width, $height) = image_size($image_file);
-
- # This probably relies on mod_rewrite working:
- $image_url = $self->image_url_root . $image_url;
- return <<"IMG";
- <img src="$image_url"
- width="$width"
- height="$height"
- alt="$alt_text"
- title="$title_text" />
- IMG
- }
-
- =item gallery_markup
-
- Generate a gallery of images.
-
- =cut
-
- sub gallery_markup {
- my $self = shift;
- my ($file, $block) = @_;
-
- my ($dir, $basedir) = fileparse($file);
-
- if (-d "$basedir/$file") {
- return gallery("$basedir/$file", "");
- }
- }
-
- # Encapsulate some ugly file-location functionality.
- sub resolve_file {
- }
-
- 1;
|