#?SuikaWikiConfig/2.0 Plugin: @Name: WikiLinking @Description: @@@: Wiki hyperlinking support @@lang:en @License: %%Perl%% @Author: @@Name: @@@@: Wakaba @@@lang:ja @@@script:Latn @@Mail[list]: w@suika.fam.cx @Date.RCS: $Date: 2004/08/06 03:37:04 $ @Use: use Message::Util::Error; our $NestLevel = 0; my $WIKIRESOURCE; my $ERROR; my $LINK_TO_RESOURCE; @Namespace: @@iw: http://suika.fam.cx/~wakaba/archive/2004/8/6/sw-iw# PluginConst: @NS_XHTML1: http://www.w3.org/1999/xhtml @NS_XHTML2: http://www.w3.org/2002/06/xhtml2 @NS_XLINK: http://www.w3.org/1999/xlink @NS_HLINK: http://www.w3.org/2002/06/hlink @ERROR: {($ERROR ||= SuikaWiki::Plugin->module_package ('Error'))} @LINK_TO_RESOURCE: {($LINK_TO_RESOURCE||=SuikaWiki::Plugin->formatter ('link_to_resource'))} @WIKIRESOURCE: {($WIKIRESOURCE ||= SuikaWiki::Plugin->module_package ('WikiResource'))} FormattingRule: @Category[list]: view view-resource form-input page-link link-to-resource @Name: link-to-wikipage @Description: @@@: Creating "from" anchor field of a link whose "to" is a WikiPage @@lang: en @Parameter: @@Name: base-page @@Type: WikiName @@Default: (current) @@Description: @@@@:Base WikiName (Relative WikiName is resolved with) @@@lang:en @Parameter: @@Name: hreflang @@Type: HTML4:LanguageCode @@Default:(none) @@Description: @@@@:(Human) language the linked WikiPage written in @@@lang:en @Parameter: @@Name: hreftype @@Type: HTML4:ContentType @@Default:(none) @@Description: @@@@:Media type the linked WikiPage provided with @@@lang:en @Parameter: @@Name:label @@Type:CDATA @@Default:(auto) @@Description: @@@@:Source anchor label @@@lang:en @Parameter: @@Name: mode @@Type: WikiMode @@Default:(default) @@Description: @@@@:Mode of the Wiki linked to @@@lang:en @Parameter: @@Name: page @@Type: WikiName @@Default: (current) @@Description: @@@@:WikiPage linked to @@@lang:en @Parameter: @@Name: page-anchor-name @@Type: XML:ID @@Default: (none) @@Description: @@@@:Identifier in the WikiPage linked to @@@lang:en @Parameter: @@Name: page-anchor-no @@Type: SGML:NUMBER @@Default: (none) @@Description: @@@@:Numeral anchor index in the WikiPage linked to @@@lang:en @Parameter: @@Name: page-title @@Type:CDATA @@Default:(auto) @@Description: @@@@:Title of the WikiPage linked to @@@lang:en @Parameter: @@Name: rel @@Type: HTML4:LinkTypes @@Default:(none) @@Description: @@@@:Link relationships @@@lang:en @Parameter: @@Name: rev @@Type: HTML4:LinkTypes @@Default:(none) @@Description: @@@@:Link relationship (reverse) @@@lang:en @Parameter: @@Name: up-to-date @@Type: boolean @@Default: "0" @@Description: @@@@:Appends random "up-to-date" parameter to the URI reference @@@lang:en @Parameter: @@Name: with-lm @@Type: boolean @@Default:"0" @@Description: @@@@:Appends "last-modified" parameter to the URI reference @@@lang:en @Formatting: __ATTRNODE:%page_title__; __ATTRTEXT:%class__; __ATTRTEXT:%label__; __ATTRTEXT:%page__;__ATTRTEXT:%base_page__;__ATTRTEXT:%page_anchor_no__; __ATTRTEXT:%with_lm__;__ATTRTEXT:%up_to_date__; __ATTRTEXT:%page_anchor_name__; __ATTRTEXT:%hreflang__;__ATTRTEXT:%hreftype__; __ATTRTEXT:%mode__; __ATTRTEXT:%rel__;__ATTRTEXT:%rev__; __FUNCPACK__->to_wikipage_in_html ({ label => $p->{label}, } => { base => $o->{wiki}->name ($p->{base_page} || $o->{wiki}->{var}->{page}), page_name_relative => $o->{wiki}->name ($p->{page} || $o->{wiki}->{var}->{page}), page_anchor_no => $p->{page_anchor_no}, page_anchor_name => $p->{page_anchor_name}, page_title => $p->{page_title}, wiki_mode => $p->{mode}, _with_lm => $p->{with_lm}, _up_to_date => $p->{up_to_date}, -hreflang => $p->{hreflang}, -hreftype => $p->{type}, }, { o => $o, parent => $p->{-parent}, -rel => $p->{rel}, -rev => $p->{rev}, }); FormattingRule: @Category[list]: view view-resource form-input page-link link-to-resource @Name: link-to-resource @Description: @@@: Creating source anchor field of a link whose destination is a resource @@lang: en @Parameter @@Name: hreflang @@Type: HTML4:LanguageCode @@Default:(none) @@Description: @@@@:(Human) language the linked WikiPage written in (advisory) @@@lang:en @Parameter: @@Name: hreftype @@Type: HTML4:ContentType @@Default:(none) @@Description: @@@@:Media type the linked WikiPage provided with (advisory) @@@lang:en @Parameter: @@Name:label @@Type:CDATA @@Default:(auto) @@Description: @@@@:Source anchor label @@@lang:en @Parameter: @@Name: rel @@Type: HTML4:LinkTypes @@Default:(none) @@Description: @@@@:Link relationships @@@lang:en @Parameter: @@Name: rev @@Type: HTML4:LinkTypes @@Default:(none) @@Description: @@@@:Link relationship (reverse) @@@lang:en @Parameter: @@Name: uri @@Type: HTML4:URI @@Default:(required) @@Description: @@@@:URI reference of the resoruce referred to @@@lang:en @Formatting: __ATTRTEXT:%class__; __ATTRTEXT:%label__; __ATTRTEXT:%hreflang__;__ATTRTEXT:%hreftype__; __ATTRTEXT:%rel__;__ATTRTEXT:%rev__; __ATTRTEXT:%uri__; my $src = { label => $p->{label}, }; my $dest = { -hreflang => $p->{hreflang}, -hreftype => $p->{type}, }; my $opt = { o => $o, parent => $p->{-parent}, -rel => $p->{rel}, -rev => $p->{rev}, }; if (length $p->{uri}) { $dest->{uri} = $p->{uri}; } else { __ATTRTEXT:%iw_name__; if ($p->{iw_name}) { __ATTRTEXT:%iw_parameter__; $dest->{resource_scheme} = 'IW'; $dest->{resource_parameter} = undef; $dest->{-iw__name} = $p->{iw_name}; $dest->{-iw__parameter} = $p->{iw_parameter}; __FUNCPACK__->to_resource_in_html ($src => $dest, $opt); return; } else { $dest->{uri} = q<>; } } __FUNCPACK__->to_resource_by_uri_in_html ($src => $dest, $opt); FormattingRule: @Category[list]: page-link link-to-resource @Name: link-to-it @Description: @@@: Source anchor @@lang: en @Parameter: @@Name: class @@Type: HTML4:class @@Default: (none) @@Description: @@@@: Class names @@@lang:en @Parameter: @@Name: description @@Type: CDATA @@Default: (none) @@Description: @@@@: Description of the anchor or link @@@lang:en @Parameter: @@Name: label @@Type: CDATA @@Default: "" @@Description: @@@@: Source anchor label (content) @@@lang:en @Formatting: __ATTRTEXT:%class__; my $A = $p->{-parent}->append_new_node (type => '#element', namespace_uri => $NS_XHTML1, local_name => 'a'); $A->set_attribute (href => $o->{link}->{dest}->{uri}); __ATTRNODE:%label->{$A}__; if (length $p->{description}) { __ATTRTEXT:%description__; } else { if ($f->{-category_name} eq 'page_link') { $p->{description} = $WIKIRESOURCE->get (name => 'WikiLinking:LinkToIt:ToWikiPage:Description', o => $o, wiki => $o->{wiki}, formatter_context => $f->{-category_name}, formatter_option => {param => $o})->inner_text; } else { $p->{description} = $WIKIRESOURCE->get (name => 'WikiLinking:LinkToIt:ToResource:Description', o => $o, wiki => $o->{wiki}, formatter_context => $f->{-category_name}, formatter_option => {param => $o})->inner_text; } } $A->set_attribute (title => $p->{description}) if $p->{description}; my @class = split /\s+/, $p->{class}; if ($o->{wiki}->uri_is_part_of_wiki ($o->{link}->{dest}->{absolute_uri} or $o->{link}->{dest}->{uri})) { push @class, 'wiki'; ## Link to the page within the Wiki } $A->set_attribute (class => join ' ', @class) if @class; $A->set_attribute (rel => $o->{link}->{option}->{-rel}) if $o->{link}->{option}->{-rel}; $A->set_attribute (rev => $o->{link}->{option}->{-rev}) if $o->{link}->{option}->{-rev}; $A->set_attribute (hreflang => $o->{link}->{dest}->{-lang}) if $o->{link}->{dest}->{-lang}; $A->set_attribute (type => $o->{link}->{dest}->{-type}) if $o->{link}->{dest}->{-type}; FormattingRule: @Category[list]: page-link link-to-resource @Name: uri-reference @Description: @@@: URI Reference of destination anchor @@lang:en @Formatting: $p->{-parent}->append_text ($o->{link}->{dest}->{absolute_uri} or $o->{link}->{dest}->{uri}); FormattingRule: @Category[list]: link-to-resource @Name: link-resource-scheme @Description: @@@: Linking scheme (defined as ReferenceScheme in SuikaWiki/0.9 syntax) @@lang:en @Formatting: $p->{-parent}->append_text ($o->{link}->{dest}->{resource_scheme}); FormattingRule: @Category[list]: link-to-resource @Name: link-resource-parameters @Description: @@@: Linking parameters (defined as ReferenceParameter in SuikaWiki/0.9 syntax) @@lang:en @Formatting: $p->{-parent}->append_text ($o->{link}->{dest}->{resource_parameter}); FormattingRule: @Category[list]: page-link @Name: link-base-page-name @Description: @@@: Base WikiPage name @@lang: en @Formatting: $p->{-parent}->append_text ($o->{link}->{dest}->{base}->stringify (wiki => $o->{wiki})); FormattingRule: @Category[list]: page-link @Name: link-dest-anchor-no @Description: @@@: Anchor number in the WikiPage linked to, if specified @@lang: en @Formatting: $p->{-parent}->append_text ($o->{link}->{dest}->{page_anchor_no}); FormattingRule: @Category[list]: link-to-resource @Name: if-link-resource-scheme @Description: @@@: If or if not resource pointing scheme matches to @@lang:en @Parameter: @@Name: name @@Type: SW09:name @@Default:(required) @@Description: @@@@: Scheme name @@@lang:en @Formatting: __ATTRTEXT:%name__; my $rule; if ($o->{link}->{dest}->{resource_scheme} eq $p->{name}) { $rule = __ATTRTEXT:%true__; } else { $rule = __ATTRTEXT:%false__; } SuikaWiki::Plugin->formatter ($f->{-category_name}) ->replace ($rule, param => $o, -parent => $p->{-parent}); FormattingRule: @Category[list]: link-to-resource @Name: select-link-resource-scheme @Description: @@@: Selecting template by resource pointing scheme matches to @@lang:en @Parameter: @@Name: SCHEMENAME @@Type: template @@Default:(none) @@Description: @@@@: Template used when scheme name is SCHEMENAME @@@lang:en @Parameter: @@Name: otherwise @@Type: template @@Default:(none) @@Description: @@@@: Template used when no SCHEMENAME parameter matches @@@lang:en @Formatting: my $rule; if (defined $p->{$o->{link}->{dest}->{resource_scheme}}) { $rule = __ATTRTEXT:%{$o->{link}->{dest}->{resource_scheme}}__; } else { $rule = __ATTRTEXT:%otherwise__; } try { $f->replace ($rule, param => $o, -parent => $p->{-parent}); } catch Message::Util::Formatter::error with { my $err = shift; if ($err->{-object}->{-category_name} eq $f->{-category_name}) { my $wiki = $err->{option}->{param}->{wiki}; __FUNCPACK{Error}__->reporting_formatting_template_error ($err, $wiki, template => $rule); } else { $err->throw; } }; FormattingRule: @Category[list]: page-link @Name: if-linked-wikipage-exist @Description: @@@: If or if not linked WikiPage exists, then @@lang: en @Formatting: my $page = $o->{link}->{dest}->{page_name}; my $rule; my $exists = 0; if ($o->{wiki}->{db}) { try { $exists = $o->{wiki}->{db}->exist (content => $page); } catch SuikaWiki::DB::Util::Error with { my $err = shift; $err->throw if $err->{-type} eq 'ERROR_REPORTED'; }; }else {CORE::die Carp::longmess} if ($exists) { $rule = __ATTRTEXT:%true__; } else { $rule = __ATTRTEXT:%false__; } SuikaWiki::Plugin->formatter ('page_link') ->replace ($rule, param => $o, -parent => $p->{-parent}); FormattingRule: @Category[list]: page-link @Name: if-link-has-dest-anchor-no @Description: @@@: If or if the link has destination numeral anchor @@lang: en @Formatting: my $rule; if ($o->{link}->{dest}->{page_anchor_no}) { $rule = __ATTRTEXT:%true__; } else { $rule = __ATTRTEXT:%false__; } SuikaWiki::Plugin->formatter ('page-link') ->replace ($rule, param => $o, -parent => $p->{-parent}); FormattingRule: @Category[list]: page-link link-to-resource @Name:-bare-text @Formatting: $p->{-parent}->append_text ($p->{-bare_text}); Function: @Name: to_resource_in_html @Description: @@@Make a link to the resource (outputted in HTML) @@lang:en @Main: my (undef, $src => $dest, $opt) = @_; local $opt->{o}->{iwc__param}; ## For InterWikiCore module if ($dest->{resource_scheme} eq 'URI' or $dest->{resource_scheme} eq 'URL') { $dest->{uri} = URI->new ($dest->{resource_parameter}); } elsif ($dest->{resource_scheme} eq 'IW') { $dest->{uri} = __FUNCPACK{InterWikiCore}__ ->interwikireference_to_urireference (packed => $dest->{resource_parameter}, name => $dest->{-iw__name}, param => $dest->{-iw__parameter}, o => $opt->{o}, wiki => $opt->{o}->{wiki}) || URI->new (q<#err--error>); $src->{} = __FUNCPACK{InterWikiCore}__ ->interwikireference_to_sourcelabel (packed => $dest->{resource_parameter}, name => $dest->{-iw__name}, param => $dest->{-iw__parameter}, o => $opt->{o}, wiki => $opt->{o}->{wiki}); } elsif ($dest->{resource_scheme} eq 'MAIL') { $dest->{uri} = 'mailto:'.$dest->{resource_parameter}; } else { $ERROR->report_error_simple ($opt->{o}->{wiki}, $WIKIRESOURCE->get_op ('Error:Condition', $opt->{o}) => $WIKIRESOURCE->get_op ('WikiLinking:ResourceScheme:Unknown:Description', $opt->{o}), $WIKIRESOURCE->get_op ('WikiLinking:ResourceScheme', $opt->{o}) => $dest->{resource_scheme}, $WIKIRESOURCE->get_op ('WikiLinking:ResourceParameter', $opt->{o}) => $dest->{resource_parameter}, ); $dest->{uri} = URI->new (q<#err--error>); } __FUNCPACK__->to_resource_by_uri_in_html ($src => $dest, $opt); Function: @Name: to_resource_by_uri_in_html @Description: @@@:Make a link to the resource by URI reference (outputted in HTML) @@lang:en @Main: my (undef, $src => $dest, $opt) = @_; local $NestLevel = $NestLevel + 1; if (100 < $NestLevel) { $opt->{parent}->append_new_node (type => '#comment', value => $src->{label}); $ERROR->report_error_simple ($opt->{o}->{wiki}, $WIKIRESOURCE->get_op ('Error:Condition', $opt->{o}) => $WIKIRESOURCE->get_op ('WikiLinking:Error:TooDeep', $opt->{o}), $WIKIRESOURCE->get_op ('Error:Formatter:Template', $opt->{o}) => $src->{label}, -trace => 1, ); return; } local $opt->{o}->{link} = { src => $src, dest => $dest, option => $opt, }; $dest->{uri} = ref $dest->{uri} ? $dest->{uri}->canonical : URI->new ($dest->{uri})->canonical; $src->{label} ||= $WIKIRESOURCE->get_text (name => 'Link:toResource:SourceLabel', param => $opt->{o}, wiki => $opt->{o}->{wiki}); try { $LINK_TO_RESOURCE ->replace ($src->{label}, param => $opt->{o}, -parent => $opt->{parent}); } catch Message::Util::Formatter::error with { my $err = shift; if ($err->{-object}->{-category_name} eq 'link_to_resource') { my $wiki = $err->{option}->{param}->{wiki}; __FUNCPACK{Error}__->reporting_formatting_template_error ($err, $wiki, template => $src->{label}); undef; } else { $err->throw; } }; Function: @Name: to_wikipage_in_html @Description: @@@:Make a link to the WikiPage (outputed in HTML) @@lang:en @Main: my (undef, $src => $dest, $opt) = @_; local $NestLevel = $NestLevel + 1; if (100 < $NestLevel) { $opt->{parent}->append_new_node (type => '#comment', value => $src->{label}); __FUNCPACK{Error}__->report_error_simple ($opt->{o}->{wiki}, __FUNCPACK{WikiResource}__ ->get_op ('Error:Condition', $opt->{o}) => __FUNCPACK{WikiResource}__->get_op ('WikiLinking:Error:TooDeep', $opt->{o}), __FUNCPACK{WikiResource}__ ->get_op ('Error:Formatter:Template', $opt->{o}) => $src->{label}, -trace => 1, ); return; } $dest->{page_name} ||= $dest->{page_name_relative}->absolute (base => $dest->{base}, wiki => $opt->{o}->{wiki}); ($dest->{uri}, $dest->{absolute_uri}) = $opt->{o}->{wiki}->uri_reference (page => $dest->{page_name}, mode => $dest->{wiki_mode}, anchor_no => $dest->{page_anchor_no}, up_to_date => $dest->{_up_to_date}, with_lm => $dest->{_with_lm}, param => $dest->{param} || {}, fragment => $dest->{page_anchor_name}, base => $dest->{-use_absolute_uri} ? undef: ($src->{base_uri} || 1)); local $opt->{o}->{link} = { src => $src, dest => $dest, option => $opt, }; $src->{label} ||= SuikaWiki::Plugin->module_package ('WikiResource') ->get_text (name => 'Link:toWikiPage:SourceLabel', param => $opt->{o}, wiki => $opt->{o}->{wiki}); try { SuikaWiki::Plugin->formatter ('page_link') ->replace ($src->{label}, param => $opt->{o}, -parent => $opt->{parent}); } catch Message::Util::Formatter::error with { my $err = shift; if ($err->{-object}->{-category_name} eq 'page_link') { my $wiki = $err->{option}->{param}->{wiki}; SuikaWiki::Plugin->module_package ('Error') ->reporting_formatting_template_error ($err, $wiki, template => $src->{label}); undef; } else { $err->throw; } }; PluginCategory: @Name: page-link @Description: @@@: Source anchor label of link whose destination is a WikiPage @@lang:en PluginCategory: @Name: link-to-resource @Description: @@@: Source anchor label of link whose destination is a resource @@lang:en Resource: @Link:toResource:SourceLabel: @@@: %select-link-resource-scheme ( URI => {<%link-to-it( label => {%uri-reference;}p, );>}, IW => {%iw--source-label (default => {<%link-to-it ( label => {%link-resource-scheme;:%link-resource-parameters;}p, );});}, MAIL => {<%link-to-it( label => {%link-resource-parameters;}p, description => {%res (name=>{Link:MailAddress=});<%link-resource-parameters;>}p, );>}, otherwise => {<%link-to-it( label => {%link-resource-scheme;:%link-resource-parameters;}p, );>}, ); @Link:toWikiPage:NotExist:Mark: @@@: ? @Link:toWikiPage:SourceLabel: @@@: %link-to-it( label=>{%page-title (relative);%if-linked-wikipage-exist( true=>{%if-link-has-dest-anchor-no(true=>{>>%link-dest-anchor-no;});}, false=>{%res(name=>{Link:toWikiPage:NotExist:Mark});} );}p, class=>{%if-linked-wikipage-exist(false=>{not-exist});}p, ); @Link:MailAddress=: @@@: Internet Mail Address: @@lang:en @Link:URIReference=: @@@: URI Reference: @@lang:en @WikiLinking:Error:TooDeep: @@@: Link nesting too deep. @@lang: en @WikiLinking:LinkToIt:ToResource:Description: %res (name=>{Link:URIReference=});<%uri-reference;> @WikiLinking:LinkToIt:ToWikiPage:Description: %page-name(absolute);; %if-linked-wikipage-exist( true=>{%page-headline;}, false=>{(%res(name=>{Link:toWikiPage:NotExist:Description});)}, ); @WikiLinking:ResourceParameter: @@@: Resource identification parameter @@lang: en @WikiLinking:ResourceScheme: @@@: Resource identification scheme @@lang: en @WikiLinking:ResourceScheme:Unknown:Description: @@@: Unknown resource identification scheme specified. @@lang: en