# @COPYRIGHT@ package Socialtext::Formatter::WaflPhrase; use strict; use warnings; use base 'Socialtext::Formatter::Wafl', 'Socialtext::Formatter::Phrase'; use Class::Field qw( const field ); use Socialtext::Paths; use Socialtext::Permission 'ST_READ_PERM'; const formatter_id => 'wafl_phrase'; const pattern_start => qr/(^|(?<=[\s\-]))\{[\w-]+(?=[\:\ \}])(\s*:)?\s*.*?\}(?=[^A-Za-z0-9]|\z)/; field 'method'; field 'arguments'; field error => ''; sub html_start { ''} sub html_end { my $self = shift; ''; } sub match { my $self = shift; return unless $self->SUPER::match(@_); return unless $self->matched =~ /^\{([\w\-]+)(?:\s*\:)?\s*(.*)\}$/; $self->arguments($2); my $method = lc $1; $method =~ s/-/_/g; $self->method($method); } sub set_error { my $self = shift; $self->error(shift); 0; } sub syntax_error { my $self = shift; my $text = shift || $self->arguments; return qq[$text]; } sub permission_error { my $self = shift; my $text = shift || $self->arguments; return qq[]; } sub existence_error { my $self = shift; my $text = shift || $self->arguments; return qq[$text]; } sub parse_wafl_reference { my $self = shift; $self->arguments =~ /^\s*(?:([\w\-]+)?\s*\[(.*?)\])?\s*(\S.*?)?\s*$/ or return; my ( $workspace_name, $page_title, $qualifier ) = ( $1, $2, $3 ); $workspace_name ||= $self->current_workspace_name; # XXX this just feels wrong. It's necessary for the many ways # we might enter the formatter. This is probably the wrong place # for this. my $page_id = Socialtext::Page->name_to_id($page_title) || $self->hub->viewer->page_id || $self->current_page_id; my $title = $page_title || ''; # XXX using hub here may causes issues with page titles # from other workspaces return ( $workspace_name, $title, $qualifier, $page_id, Socialtext::Pages->id_to_uri($page_id) ); } sub parse_wafl_category { my $self = shift; $self->arguments =~ /^\s*(?:([\w\-]+)\s*;)?\s*(\S.*?)?\s*$/ ? ( $1, $2 ) : (); } sub hub_for_workspace_name { my $self = shift; my $workspace_name = shift; my $hub = $self->hub; if ( $workspace_name ne $self->current_workspace_name ) { my $main = Socialtext->new(); $main->load_hub( current_user => Socialtext::User->SystemUser(), current_workspace => Socialtext::Workspace->new( name => $workspace_name ), ); $main->hub->registry->load; $hub = $main->hub; } return $hub; } sub get_file_id { my $self = shift; # XXX maybe belongs in Socialtext::Attachments my ( $workspace_name, $page_id, $filename ) = @_; my $ws = Socialtext::Workspace->new( name => $workspace_name ); return $self->set_error( $self->permission_error ) unless $ws && $self->authz->user_has_permission_for_workspace( user => $self->current_user, permission => ST_READ_PERM, workspace => $ws, ); my $path = Socialtext::Paths::plugin_directory($workspace_name); my $hub = $self->hub_for_workspace_name($workspace_name); my $all = $hub->attachments->all( page_id => $page_id ); $filename = lc($filename); my @attachments = sort { $b->Date cmp $a->Date } grep { lc( $_->filename ) eq $filename } @$all or return $self->set_error( $self->existence_error ); $attachments[0]->id; } ################################################################################ package Socialtext::Formatter::WaflPhraseDiv; use base 'Socialtext::Formatter::WaflPhrase'; sub html_start { my $page = $Socialtext::Formatter::Viewer::in_paragraph ? '
' : ''; return qq($page' : ''; '
$page"; } ################################################################################ package Socialtext::Formatter::Image; use base 'Socialtext::Formatter::WaflPhrase'; use Class::Field qw( const ); const wafl_id => 'image'; sub html { my $self = shift; my ( $workspace_name, $page_title, $image_name, $page_id, $page_uri ) = $self->parse_wafl_reference; return $self->syntax_error unless $image_name; my $file_id = $self->get_file_id( $workspace_name, $page_id, $image_name ) or return $self->error; $image_name = $self->uri_escape($image_name); my $link = $self->hub->viewer->link_dictionary->format_link( link => 'attachment', url_prefix => $self->url_prefix, workspace => $workspace_name, filename => $image_name, page_uri => $page_uri, id => $file_id, ); return qq{Table of Contents: ) . $page->title . "
\n"; { no warnings 'once'; local *Socialtext::Formatter::WaflPhrase::get_text = sub { my $self = shift; return $self->arguments; }; # Headers are going to be blocks one step underneath the top_class # get them, their text, and their level to create a wiki list of # InterWikilinkS my $units = $parse_tree->units; foreach my $unit (@$units) { next unless ref $unit; next unless $unit->formatter_id eq 'hx'; $wikitext .= '*' x $unit->level . ' ' . qq({link $wikitext_workspace_name ) . qq($wikitext_page_id ) . $unit->get_text . "}\n"; } $wikitext = "> {link $wikitext_workspace_name [" . $page->title . ']} does not have any headers.' unless $wikitext; } my $html = $self->hub->viewer->text_to_html( "\n" . $wikitext . "\n\n" ); return $title . $html . '