From 3d846b2d27e80386e058b0ca9ef2739674ef7736 Mon Sep 17 00:00:00 2001 From: Thomas Schwinge Date: Thu, 9 Sep 2010 14:06:35 +0200 Subject: Add (part of) YAML field infrastructure. New files copied from a2482475a7ed0b6f54df10a87a8665e2361f3598 of by Kathryn Andersen . --- .library/IkiWiki/Plugin/getfield.pm | 123 ++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 .library/IkiWiki/Plugin/getfield.pm (limited to '.library/IkiWiki/Plugin/getfield.pm') diff --git a/.library/IkiWiki/Plugin/getfield.pm b/.library/IkiWiki/Plugin/getfield.pm new file mode 100644 index 00000000..3a967d8e --- /dev/null +++ b/.library/IkiWiki/Plugin/getfield.pm @@ -0,0 +1,123 @@ +#!/usr/bin/perl +# Ikiwiki getfield plugin. +# Substitute field values in the content of the page. +# See plugin/contrib/getfield for documentation. +package IkiWiki::Plugin::getfield; +use strict; +=head1 NAME + +IkiWiki::Plugin::getfield - query the values of fields + +=head1 VERSION + +This describes version B<0.02> of IkiWiki::Plugin::getfield + +=cut + +our $VERSION = '0.02'; + +=head1 PREREQUISITES + + IkiWiki + IkiWiki::Plugin::field + +=head1 AUTHOR + + Kathryn Andersen (RUBYKAT) + http://github.com/rubykat + +=head1 COPYRIGHT + +Copyright (c) 2009 Kathryn Andersen + +This program is free software; you can redistribute it and/or +modify it under the same terms as Perl itself. + +=cut + +use IkiWiki 3.00; + +sub import { + hook(type => "getsetup", id => "getfield", call => \&getsetup); + hook(type => "filter", id => "getfield", call => \&do_filter, last=>1); + + IkiWiki::loadplugin("field"); +} + +#--------------------------------------------------------------- +# Hooks +# -------------------------------- + +sub getsetup () { + return + plugin => { + safe => 1, + rebuild => undef, + }, +} + +sub do_filter (@) { + my %params=@_; + my $page = $params{page}; + my $destpage = ($params{destpage} ? $params{destpage} : $params{page}); + + my $page_file=$pagesources{$page}; + my $page_type=pagetype($page_file); + if (defined $page_type) + { + while ($params{content} =~ /{{\$([-\w\/]+#)?[-\w]+}}/) + { + # substitute {{$var}} variables (source-page) + $params{content} =~ s/{{\$([-\w]+)}}/get_field_value($1,$page)/eg; + + # substitute {{$page#var}} variables (source-page) + $params{content} =~ s/{{\$([-\w\/]+)#([-\w]+)}}/get_other_page_field_value($2,$page,$1)/eg; + } + } + + $page_file=$pagesources{$destpage}; + $page_type=pagetype($page_file); + if (defined $page_type) + { + while ($params{content} =~ /{{\+\$([-\w\/]+#)?[-\w]+\+}}/) + { + # substitute {{+$var+}} variables (dest-page) + $params{content} =~ s/{{\+\$([-\w]+)\+}}/get_field_value($1,$destpage)/eg; + # substitute {{+$page#var+}} variables (source-page) + $params{content} =~ s/{{\+\$([-\w\/]+)#([-\w]+)\+}}/get_other_page_field_value($2,$destpage,$1)/eg; + } + } + + return $params{content}; +} # do_filter + +#--------------------------------------------------------------- +# Private functions +# -------------------------------- +sub get_other_page_field_value ($$$) { + my $field = shift; + my $page = shift; + my $other_page = shift; + + my $use_page = bestlink($page, $other_page); + my $val = get_field_value($field, $use_page); + if ($val eq $field) + { + return "${other_page}#$field"; + } + return $val; + +} # get_other_page_field_value + +sub get_field_value ($$) { + my $field = shift; + my $page = shift; + + my $value = IkiWiki::Plugin::field::field_get_value($field,$page); + return $value if defined $value; + + # if there is no value, return the field name. + return $field; +} # get_field_value + +1; -- cgit v1.2.3 From 5197f363475e6218c56b1629d6509fd4fcc61cda Mon Sep 17 00:00:00 2001 From: Thomas Schwinge Date: Thu, 9 Sep 2010 14:09:12 +0200 Subject: .library/IkiWiki/Plugin/getfield.pm (get_other_page_field_value): Add a dependency for the page from which we get the value. --- .library/IkiWiki/Plugin/getfield.pm | 3 +++ 1 file changed, 3 insertions(+) (limited to '.library/IkiWiki/Plugin/getfield.pm') diff --git a/.library/IkiWiki/Plugin/getfield.pm b/.library/IkiWiki/Plugin/getfield.pm index 3a967d8e..d6564eaf 100644 --- a/.library/IkiWiki/Plugin/getfield.pm +++ b/.library/IkiWiki/Plugin/getfield.pm @@ -100,6 +100,9 @@ sub get_other_page_field_value ($$$) { my $other_page = shift; my $use_page = bestlink($page, $other_page); + # add a dependency for the page from which we get the value + add_depends($page, $other_page); + my $val = get_field_value($field, $use_page); if ($val eq $field) { -- cgit v1.2.3 From 3a2cf01b8d9adcd2628dcf7af371264f6b9841bb Mon Sep 17 00:00:00 2001 From: Thomas Schwinge Date: Fri, 17 Sep 2010 12:06:31 +0200 Subject: .library/IkiWiki/Plugin/getfield.pm (get_other_page_field_value): Depend on use_page, not other_page. --- .library/IkiWiki/Plugin/getfield.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to '.library/IkiWiki/Plugin/getfield.pm') diff --git a/.library/IkiWiki/Plugin/getfield.pm b/.library/IkiWiki/Plugin/getfield.pm index d6564eaf..ecdd4672 100644 --- a/.library/IkiWiki/Plugin/getfield.pm +++ b/.library/IkiWiki/Plugin/getfield.pm @@ -101,7 +101,7 @@ sub get_other_page_field_value ($$$) { my $use_page = bestlink($page, $other_page); # add a dependency for the page from which we get the value - add_depends($page, $other_page); + add_depends($page, $use_page); my $val = get_field_value($field, $use_page); if ($val eq $field) -- cgit v1.2.3 From fe368cda90cd374c68780c238481b1208056655f Mon Sep 17 00:00:00 2001 From: Thomas Schwinge Date: Thu, 25 Nov 2010 14:18:54 +0100 Subject: Update to b329454a41390ca8b3f31215d62542a27e6a8b80 of . --- .library/IkiWiki/Plugin/field.pm | 261 ++++++++++++++++++++++-------------- .library/IkiWiki/Plugin/getfield.pm | 4 +- .library/IkiWiki/Plugin/ymlfront.pm | 52 +++---- 3 files changed, 189 insertions(+), 128 deletions(-) (limited to '.library/IkiWiki/Plugin/getfield.pm') diff --git a/.library/IkiWiki/Plugin/field.pm b/.library/IkiWiki/Plugin/field.pm index 77247ad4..d77e7282 100644 --- a/.library/IkiWiki/Plugin/field.pm +++ b/.library/IkiWiki/Plugin/field.pm @@ -10,11 +10,11 @@ IkiWiki::Plugin::field - front-end for per-page record fields. =head1 VERSION -This describes version B<0.05> of IkiWiki::Plugin::field +This describes version B<1.20101101> of IkiWiki::Plugin::field =cut -our $VERSION = '0.05'; +our $VERSION = '1.20101115'; =head1 PREREQUISITES @@ -133,7 +133,7 @@ sub scan (@) { # scan for tag fields if ($config{field_tags}) { - foreach my $field (sort keys %{$config{field_tags}}) + foreach my $field (keys %{$config{field_tags}}) { my @values = field_get_value($field, $page); if (@values) @@ -177,28 +177,9 @@ sub field_register (%) { return 0; } - $Fields{$param{id}} = \%param; - if (!exists $param{call}) - { - # closure to get the data from the pagestate hash - $Fields{$param{id}}->{call} = sub { - my $field_name = shift; - my $page = shift; - if (exists $pagestate{$page}{$param{id}}{$field_name}) - { - return (wantarray - ? ($pagestate{$page}{$param{id}}{$field_name}) - : $pagestate{$page}{$param{id}}{$field_name}); - } - elsif (exists $pagestate{$page}{$param{id}}{lc($field_name)}) - { - return (wantarray - ? ($pagestate{$page}{$param{id}}{lc($field_name)}) - : $pagestate{$page}{$param{id}}{lc($field_name)}); - } - return undef; - }; - } + my $id = $param{id}; + $Fields{$id} = \%param; + # add this to the ordering hash # first, last, order; by default, middle my $when = ($param{first} @@ -219,7 +200,7 @@ sub field_register (%) { : '_middle' ) )); - add_lookup_order($param{id}, $when); + add_lookup_order($id, $when); return 1; } # field_register @@ -238,100 +219,105 @@ sub field_get_value ($$) { # any field that happens to be defined in a YAML page file, which # could be anything! - my $value = undef; - my @array_value = undef; - # check the cache first - if (exists $Cache{$page}{$field_name} - and defined $Cache{$page}{$field_name}) + my $lc_field_name = lc($field_name); + if (wantarray) + { + if (exists $Cache{$page}{$lc_field_name}{array} + and defined $Cache{$page}{$lc_field_name}{array}) + { + return @{$Cache{$page}{$lc_field_name}{array}}; + } + } + else { - return (wantarray - ? @{$Cache{$page}{$field_name}{array}} - : $Cache{$page}{$field_name}{scalar}); + if (exists $Cache{$page}{$lc_field_name}{scalar} + and defined $Cache{$page}{$lc_field_name}{scalar}) + { + return $Cache{$page}{$lc_field_name}{scalar}; + } } if (!@FieldsLookupOrder) { build_fields_lookup_order(); } - foreach my $id (@FieldsLookupOrder) - { - $value = $Fields{$id}{call}->($field_name, $page); - @array_value = $Fields{$id}{call}->($field_name, $page); - if (defined $value) - { - last; - } - } - # extra definitions - if (!defined $value) + # Get either the scalar or the array value depending + # on what is requested - don't get both because it wastes time. + if (wantarray) { - # Exception for titles - # If the title hasn't been found, construct it - if ($field_name eq 'title') - { - $value = pagetitle(IkiWiki::basename($page)); - } - # and set "page" if desired - elsif ($field_name eq 'page') + my @array_value = undef; + foreach my $id (@FieldsLookupOrder) { - $value = $page; - } - # the page above this page; aka the current directory - elsif ($field_name eq 'parent_page') - { - if ($page =~ m{^(.*)/[-\.\w]+$}) + # get the data from the pagestate hash if it's there + if (exists $pagestate{$page}{$id}{$field_name} + and defined $pagestate{$page}{$id}{$field_name}) + { + @array_value = (ref $pagestate{$page}{$id}{$field_name} + ? @{$pagestate{$page}{$id}{$field_name}} + : ($pagestate{$page}{$id}{$field_name})); + } + elsif (exists $pagestate{$page}{$id}{$lc_field_name} + and defined $pagestate{$page}{$id}{$lc_field_name}) + { + @array_value = (ref $pagestate{$page}{$id}{$lc_field_name} + ? @{$pagestate{$page}{$id}{$lc_field_name}} + : ($pagestate{$page}{$id}{$lc_field_name})); + } + elsif (exists $Fields{$id}{call}) { - $value = $1; + @array_value = $Fields{$id}{call}->($field_name, $page); + } + if (@array_value and $array_value[0]) + { + last; } } - elsif ($field_name eq 'basename') + if (!@array_value) { - $value = IkiWiki::basename($page); + @array_value = field_calculated_values($field_name, $page); } - elsif ($config{field_allow_config} - and $field_name =~ /^config-(.*)$/i) + # cache the value + $Cache{$page}{$lc_field_name}{array} = \@array_value; + return @array_value; + } + else # scalar + { + my $value = undef; + foreach my $id (@FieldsLookupOrder) { - my $cfield = $1; - if (exists $config{$cfield}) + # get the data from the pagestate hash if it's there + # but only if it's already a scalar + if (exists $pagestate{$page}{$id}{$field_name} + and !ref $pagestate{$page}{$id}{$field_name}) { - $value = $config{$cfield}; + $value = $pagestate{$page}{$id}{$field_name}; } - } - elsif ($field_name =~ /^(.*)-tagpage$/) - { - my $real_fn = $1; - if (exists $config{field_tags}{$real_fn} - and defined $config{field_tags}{$real_fn}) + elsif (exists $pagestate{$page}{$id}{$lc_field_name} + and !ref $pagestate{$page}{$id}{$lc_field_name}) { - my @values = field_get_value($real_fn, $page); - if (@values) - { - foreach my $tag (@values) - { - if ($tag) - { - my $link = $config{field_tags}{$real_fn} . '/' . $tag; - push @array_value, $link; - } - } - $value = join(",", @array_value); - } + $value = $pagestate{$page}{$id}{$lc_field_name}; + } + elsif (exists $Fields{$id}{call}) + { + $value = $Fields{$id}{call}->($field_name, $page); + } + if (defined $value) + { + last; } } - } - if (defined $value) - { - if (!@array_value) + if (!defined $value) { - @array_value = ($value); + $value = field_calculated_values($field_name, $page); } # cache the value - $Cache{$page}{$field_name}{scalar} = $value; - $Cache{$page}{$field_name}{array} = \@array_value; + $Cache{$page}{$lc_field_name}{scalar} = $value; + return $value; } - return (wantarray ? @array_value : $value); + + return undef; } # field_get_value # set the values for the given HTML::Template template @@ -356,11 +342,11 @@ sub field_set_template_values ($$;@) { my @parameter_names = $template->param(); foreach my $field (@parameter_names) { - # Don't redefine if the field already has a value. + # Don't redefine if the field already has a value set. next if ($template->param($field)); my $type = $template->query(name => $field); - if ($type eq 'LOOP' and $field =~ /_LOOP$/i) + if ($type eq 'LOOP' and $field =~ /_LOOP$/oi) { # Loop fields want arrays. # Figure out what field names to look for: @@ -371,7 +357,7 @@ sub field_set_template_values ($$;@) { my %loop_field_arrays = (); foreach my $fn (@loop_fields) { - if ($fn !~ /^__/) # not a special loop variable + if ($fn !~ /^__/o) # not a special loop variable { my @ival_array = $get_value_fn->($fn, $page); if (@ival_array) @@ -418,7 +404,7 @@ sub add_lookup_order { my $when = shift; # may have given an explicit ordering - if ($when =~ /^[A-Z][A-Z]$/) + if ($when =~ /^[A-Z][A-Z]$/o) { $Fields{$id}{seq} = $when; } @@ -426,7 +412,7 @@ sub add_lookup_order { { my $cmp = '='; my $seq_field = $when; - if ($when =~ /^([<>])(.+)$/) + if ($when =~ /^([<>])(.+)$/o) { $cmp = $1; $seq_field = $2; @@ -479,6 +465,77 @@ sub build_fields_lookup_order { } } # build_fields_lookup_order +# standard values deduced from other values +sub field_calculated_values { + my $field_name = shift; + my $page = shift; + + my $value = undef; + + # Exception for titles + # If the title hasn't been found, construct it + if ($field_name eq 'title') + { + $value = pagetitle(IkiWiki::basename($page)); + } + # and set "page" if desired + elsif ($field_name eq 'page') + { + $value = $page; + } + # the page above this page; aka the current directory + elsif ($field_name eq 'parent_page') + { + if ($page =~ m{^(.*)/[-\.\w]+$}o) + { + $value = $1; + } + } + elsif ($field_name eq 'basename') + { + $value = IkiWiki::basename($page); + } + elsif ($config{field_allow_config} + and $field_name =~ /^config-(.*)$/oi) + { + my $cfield = $1; + if (exists $config{$cfield}) + { + $value = $config{$cfield}; + } + } + elsif ($field_name =~ /^(.*)-tagpage$/o) + { + my @array_value = undef; + my $real_fn = $1; + if (exists $config{field_tags}{$real_fn} + and defined $config{field_tags}{$real_fn}) + { + my @values = field_get_value($real_fn, $page); + if (@values) + { + foreach my $tag (@values) + { + if ($tag) + { + my $link = $config{field_tags}{$real_fn} . '/' . $tag; + push @array_value, $link; + } + } + if (wantarray) + { + return @array_value; + } + else + { + $value = join(",", @array_value) if $array_value[0]; + } + } + } + } + return (wantarray ? ($value) : $value); +} # field_calculated_values + # match field funcs # page-to-check, wanted sub match_a_field ($$) { @@ -488,7 +545,7 @@ sub match_a_field ($$) { # The field name is first; the rest is the match my $field_name; my $glob; - if ($wanted =~ /^(\w+)\s+(.*)$/) + if ($wanted =~ /^(\w+)\s+(.*)$/o) { $field_name = $1; $glob = $2; @@ -526,7 +583,7 @@ sub match_a_field_item ($$) { # The field name is first; the rest is the match my $field_name; my $glob; - if ($wanted =~ /^(\w+)\s+(.*)$/) + if ($wanted =~ /^(\w+)\s+(.*)$/o) { $field_name = $1; $glob = $2; @@ -607,7 +664,7 @@ sub match_field_tagged ($$;@) { # The field name is first; the rest is the match my $field_name; my $glob; - if ($wanted =~ /^(\w+)\s+(.*)$/) + if ($wanted =~ /^(\w+)\s+(.*)$/o) { $field_name = $1; $glob = $2; diff --git a/.library/IkiWiki/Plugin/getfield.pm b/.library/IkiWiki/Plugin/getfield.pm index ecdd4672..971e7ecb 100644 --- a/.library/IkiWiki/Plugin/getfield.pm +++ b/.library/IkiWiki/Plugin/getfield.pm @@ -10,11 +10,11 @@ IkiWiki::Plugin::getfield - query the values of fields =head1 VERSION -This describes version B<0.02> of IkiWiki::Plugin::getfield +This describes version B<1.20101101> of IkiWiki::Plugin::getfield =cut -our $VERSION = '0.02'; +our $VERSION = '1.20101101'; =head1 PREREQUISITES diff --git a/.library/IkiWiki/Plugin/ymlfront.pm b/.library/IkiWiki/Plugin/ymlfront.pm index 3811591b..6af4e5d6 100644 --- a/.library/IkiWiki/Plugin/ymlfront.pm +++ b/.library/IkiWiki/Plugin/ymlfront.pm @@ -10,11 +10,11 @@ IkiWiki::Plugin::ymlfront - add YAML-format data to a page =head1 VERSION -This describes version B<0.03> of IkiWiki::Plugin::ymlfront +This describes version B<1.20100808> of IkiWiki::Plugin::ymlfront =cut -our $VERSION = '0.03'; +our $VERSION = '1.20101116'; =head1 PREREQUISITES @@ -51,6 +51,31 @@ sub import { first=>1); } +# ------------------------------------------------------------ +# Package Vars +# -------------------------------- +my $ymlfront_regex = qr{ + (\\?) # 1: escape? + \[\[(!) # directive open; 2: prefix + (ymlfront) # 3: command + ( # 4: the parameters.. + \s+ # Must have space if parameters present + (?: + (?:[-\w]+=)? # named parameter key? + (?: + """.*?""" # triple-quoted value + | + "[^"]*?" # single-quoted value + | + [^"\s\]]+ # unquoted value + ) + \s* # whitespace or end + # of directive + ) + *)? # 0 or more parameters + \]\] # directive closed + }sx; + # ------------------------------------------------------------ # Hooks # -------------------------------- @@ -300,27 +325,6 @@ sub parse_yml { } elsif ($content) { - my $regex = qr{ - (\\?) # 1: escape? - \[\[(!) # directive open; 2: prefix - (ymlfront) # 3: command - ( # 4: the parameters.. - \s+ # Must have space if parameters present - (?: - (?:[-\w]+=)? # named parameter key? - (?: - """.*?""" # triple-quoted value - | - "[^"]*?" # single-quoted value - | - [^"\s\]]+ # unquoted value - ) - \s* # whitespace or end - # of directive - ) - *)? # 0 or more parameters - \]\] # directive closed - }sx; my $ystart = $config{ymlfront_delim}[0]; my $yend = $config{ymlfront_delim}[1]; if ($ystart eq '---' @@ -335,7 +339,7 @@ sub parse_yml { $yml_str = $2; $rest_of_content = $1 . $3; } - elsif ($content =~ /$regex/) + elsif ($content =~ $ymlfront_regex) { my $escape=$1; my $prefix=$2; -- cgit v1.2.3