From 73f4a8835876c8cb07808367cd72d9ae972893e8 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sat, 9 Jan 2010 22:54:34 +0100 Subject: po: inject custom isselflink to fix selflink detection on translation pages --- IkiWiki/Plugin/po.pm | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'IkiWiki') diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 02fc4a89e..bbbb3b870 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -63,6 +63,8 @@ sub import { inject(name => "IkiWiki::cgiurl", call => \&mycgiurl); $origsubs{'rootpage'}=\&IkiWiki::rootpage; inject(name => "IkiWiki::rootpage", call => \&myrootpage); + $origsubs{'isselflink'}=\&IkiWiki::isselflink; + inject(name => "IkiWiki::isselflink", call => \&myisselflink); } @@ -671,6 +673,17 @@ sub myrootpage (@) { return $rootpage; } +sub myisselflink ($$) { + my $page=shift; + my $link=shift; + + return 1 if $origsubs{'isselflink'}->($page, $link); + if (istranslation($page)) { + return $origsubs{'isselflink'}->(masterpage($page), $link); + } + return; +} + # ,---- # | Blackboxes for private data # `---- -- cgit v1.2.3 From d877b9644bcfbbfc5eaf3f7fc13cb96ecda946c9 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Fri, 25 Jun 2010 17:14:13 +0200 Subject: po: fix bug with translated pages including templates The protection against processing loops (i.e. the alreadyfiltered stuff) was playing against us: the template plugin triggered a filter hooks run with the very same ($page, $destpage) arguments pair that we use to identify a already filtered page. Processing an included template could then mark the whole translation page as already filtered, which prevented po_to_markup to be called on the PO content. This commit only runs the whole PO filter logic when our filter hook is run by IkiWiki::render, which only happens when the full page needs to be filtered. --- IkiWiki/Plugin/po.pm | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'IkiWiki') diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 3023fd7f9..0b48726ea 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -243,6 +243,10 @@ sub filter (@) { my $page = $params{page}; my $destpage = $params{destpage}; my $content = $params{content}; + + my @caller = caller(4); + return $content unless $caller[3] ne "IkiWiki::render"; + if (istranslation($page) && ! alreadyfiltered($page, $destpage)) { $content = po_to_markup($page, $content); setalreadyfiltered($page, $destpage); -- cgit v1.2.3 From d4136aea8aa8968d2cd87b40e8d85301a3549323 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Fri, 25 Jun 2010 17:43:25 +0200 Subject: po: also filter sidebar translation pages --- IkiWiki/Plugin/po.pm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'IkiWiki') diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 0b48726ea..6bf09b6d6 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -245,7 +245,10 @@ sub filter (@) { my $content = $params{content}; my @caller = caller(4); - return $content unless $caller[3] ne "IkiWiki::render"; + unless ($caller[3] eq "IkiWiki::render" || + $caller[3] eq 'IkiWiki::Plugin::sidebar::sidebar_content') { + return $content; + } if (istranslation($page) && ! alreadyfiltered($page, $destpage)) { $content = po_to_markup($page, $content); -- cgit v1.2.3 From 903a71c1b9d71bcd10442bee695da6efd4ec953d Mon Sep 17 00:00:00 2001 From: intrigeri Date: Fri, 25 Jun 2010 17:45:08 +0200 Subject: TODO++ --- IkiWiki/Plugin/po.pm | 1 + 1 file changed, 1 insertion(+) (limited to 'IkiWiki') diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 6bf09b6d6..10a5ba467 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -245,6 +245,7 @@ sub filter (@) { my $content = $params{content}; my @caller = caller(4); + # FIXME: need to whitelist inline as well? unless ($caller[3] eq "IkiWiki::render" || $caller[3] eq 'IkiWiki::Plugin::sidebar::sidebar_content') { return $content; -- cgit v1.2.3 From a128c256a51392fcf752bf612d83a90e8c68027e Mon Sep 17 00:00:00 2001 From: intrigeri Date: Fri, 25 Jun 2010 23:18:34 +0200 Subject: po: added support for html pagetype ... after having audited the po4a Xml and Xhtml modules for security issues. Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 47 +++++++++++++++++++++++++++++++++--------- doc/plugins/po.mdwn | 10 ++++----- doc/plugins/po/discussion.mdwn | 17 +++++++++++++++ 3 files changed, 59 insertions(+), 15 deletions(-) (limited to 'IkiWiki') diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 10a5ba467..ab1cc7ae6 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -869,8 +869,8 @@ sub refreshpot ($) { my $masterfile=shift; my $potfile=potfile($masterfile); - my %options = ("markdown" => (pagetype($masterfile) eq 'mdwn') ? 1 : 0); - my $doc=Locale::Po4a::Chooser::new('text',%options); + my $doc=Locale::Po4a::Chooser::new(po4a_type($masterfile), + po4a_options($masterfile)); $doc->{TT}{utf_mode} = 1; $doc->{TT}{file_in_charset} = 'utf-8'; $doc->{TT}{file_out_charset} = 'utf-8'; @@ -961,10 +961,8 @@ sub percenttranslated ($) { return gettext("N/A") unless istranslation($page); my $file=srcfile($pagesources{$page}); my $masterfile = srcfile($pagesources{masterpage($page)}); - my %options = ( - "markdown" => (pagetype($masterfile) eq 'mdwn') ? 1 : 0, - ); - my $doc=Locale::Po4a::Chooser::new('text',%options); + my $doc=Locale::Po4a::Chooser::new(po4a_type($masterfile), + po4a_options($masterfile)); $doc->process( 'po_in_name' => [ $file ], 'file_in_name' => [ $masterfile ], @@ -1115,10 +1113,8 @@ sub po_to_markup ($$) { or return $fail->(sprintf(gettext("failed to write %s"), $infile)); my $masterfile = srcfile($pagesources{masterpage($page)}); - my %options = ( - "markdown" => (pagetype($masterfile) eq 'mdwn') ? 1 : 0, - ); - my $doc=Locale::Po4a::Chooser::new('text',%options); + my $doc=Locale::Po4a::Chooser::new(po4a_type($masterfile), + po4a_options($masterfile)); $doc->process( 'po_in_name' => [ $infile ], 'file_in_name' => [ $masterfile ], @@ -1181,6 +1177,37 @@ sub isvalidpo ($) { "to previous page to continue edit")); } +sub po4a_type ($) { + my $file = shift; + + my $pagetype = pagetype($file); + if ($pagetype eq 'html') { + return 'xhtml'; + } + return 'text'; +} + +sub po4a_options($) { + my $file = shift; + + my %options; + my $pagetype = pagetype($file); + + if ($pagetype eq 'html') { + # how to disable options is not consistent across po4a modules + $options{includessi} = ''; + $options{includeexternal} = 0; + } + elsif ($pagetype eq 'mdwn') { + $options{markdown} = 1; + } + else { + $options{markdown} = 0; + } + + return %options; +} + # ,---- # | PageSpecs # `---- diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index 576d36ec1..585e14383 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -213,16 +213,16 @@ preferred `$EDITOR`, without needing to be online. Markup languages support ------------------------ -[[Markdown|mdwn]] is well supported. Some other markup languages supported -by ikiwiki mostly work, but some pieces of syntax are not rendered -correctly on the slave pages: +[[Markdown|mdwn]] and [[html]] are well supported. Some other markup +languages supported by ikiwiki mostly work, but some pieces of syntax +are not rendered correctly on the slave pages: * [[reStructuredText|rst]]: anonymous hyperlinks and internal cross-references * [[wikitext]]: conversion of newlines to paragraphs * [[creole]]: verbatim text is wrapped, tables are broken -* [[html]] and LaTeX: not supported yet; the dedicated po4a modules - could be used to support them, but they would need a security audit +* LaTeX: not supported yet; the dedicated po4a module + could be used to support it, but it would need a security audit * other markup languages have not been tested. Security diff --git a/doc/plugins/po/discussion.mdwn b/doc/plugins/po/discussion.mdwn index 27683f1ea..73858c818 100644 --- a/doc/plugins/po/discussion.mdwn +++ b/doc/plugins/po/discussion.mdwn @@ -150,6 +150,23 @@ The following analysis was done with his help. variables; according to [[Joey]], this is "Freaky code, but seems ok due to use of `quotementa`". +##### Locale::Po4a::Xhtml + +* does not run any external program +* does not build regexp's from untrusted variables + +=> Seems safe as far as the `includessi` option is disabled; the po +plugin explicitly disables it. + +Relies on Locale::Po4a::Xml` to do most of the work. + +##### Locale::Po4a::Xml + +* does not run any external program +* the `includeexternal` option makes it able to read external files; + the po plugin explicitly disables it +* untrusted variables are escaped when used to build regexp's + ##### Text::WrapI18N `Text::WrapI18N` can cause DoS -- cgit v1.2.3 From 4cf185e781a5f94373b30ec9a0e10dfb626b6d86 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sat, 26 Jun 2010 00:56:06 +0200 Subject: po_slave_languages can now be a hash, if order matters. --- IkiWiki/Plugin/po.pm | 95 +++++++++++++++++++++++++++++++++------------------- doc/plugins/po.mdwn | 13 ++----- 2 files changed, 62 insertions(+), 46 deletions(-) (limited to 'IkiWiki') diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index ab1cc7ae6..7d5dfee03 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -28,6 +28,7 @@ use UNIVERSAL; my %translations; my @origneedsbuild; my %origsubs; +my @slavelanguages; # orderer as in config po_slave_languages memoize("istranslatable"); memoize("_istranslation"); @@ -104,11 +105,11 @@ sub getsetup () { }, po_slave_languages => { type => "string", - example => { + example => [ 'fr' => 'Français', 'es' => 'Español', 'de' => 'Deutsch' - }, + ], description => "slave languages (PO files)", safe => 1, rebuild => 1, @@ -137,6 +138,21 @@ sub checkconfig () { $field, 'po')); } } + + if (ref $config{po_slave_languages} eq 'ARRAY') { + my %slaves; + for (my $i=0; $i<@{$config{po_slave_languages}}; $i = $i + 2) { + $slaves{$config{po_slave_languages}->[$i]} = $config{po_slave_languages}->[$i + 1]; + push @slavelanguages, $config{po_slave_languages}->[$i]; + } + $config{po_slave_languages} = \%slaves; + } + elsif (ref $config{po_slave_languages} eq 'HASH') { + @slavelanguages = sort { + $config{po_slave_languages}->{$a} cmp $config{po_slave_languages}->{$b}; + } keys %{$config{po_slave_languages}}; + } + delete $config{po_slave_languages}{$config{po_master_language}{code}};; map { @@ -197,7 +213,7 @@ sub needsbuild () { # make existing translations depend on the corresponding master page foreach my $master (keys %translations) { - map add_depends($_, $master), values %{otherlanguages($master)}; + map add_depends($_, $master), values %{otherlanguages_pages($master)}; } } @@ -229,7 +245,7 @@ sub scan (@) { # make sure any destpage's translations has # $page in its backlinks push @{$links{$page}}, - values %{otherlanguages($destpage)}; + values %{otherlanguages_pages($destpage)}; } } } @@ -295,7 +311,7 @@ sub pagetemplate (@) { } if ($template->query(name => "otherlanguages")) { $template->param(otherlanguages => [otherlanguagesloop($page)]); - map add_depends($page, $_), (values %{otherlanguages($page)}); + map add_depends($page, $_), (values %{otherlanguages_pages($page)}); } if ($config{discussion} && istranslation($page)) { if ($page !~ /.*\/\Q$config{discussionpage}\E$/i && @@ -348,12 +364,12 @@ sub renamepages (@) { return () unless istranslatable($torename{src}); my @ret; - my %otherpages=%{otherlanguages($torename{src})}; + my %otherpages=%{otherlanguages_pages($torename{src})}; while (my ($lang, $otherpage) = each %otherpages) { push @ret, { src => $otherpage, srcfile => $pagesources{$otherpage}, - dest => otherlanguage($torename{dest}, $lang), + dest => otherlanguage_page($torename{dest}, $lang), destfile => $torename{dest}.".".$lang.".po", required => 0, }; @@ -820,7 +836,7 @@ sub islanguagecode ($) { return $code =~ /^[a-z]{2}$/; } -sub otherlanguage ($$) { +sub otherlanguage_page ($$) { my $page=shift; my $code=shift; @@ -828,17 +844,31 @@ sub otherlanguage ($$) { return masterpage($page) . '.' . $code; } -sub otherlanguages ($) { +# Returns the list of other languages codes: the master language comes first, +# then the codes are ordered the same way as in po_slave_languages, if it is +# an array, or in the language name lexical order, if it is a hash. +sub otherlanguages_codes ($) { my $page=shift; - my %ret; - return \%ret unless istranslation($page) || istranslatable($page); + my @ret; + return \@ret unless istranslation($page) || istranslatable($page); my $curlang=lang($page); foreach my $lang - ($config{po_master_language}{code}, keys %{$config{po_slave_languages}}) { + ($config{po_master_language}{code}, @slavelanguages) { next if $lang eq $curlang; - $ret{$lang}=otherlanguage($page, $lang); + push @ret, $lang; } + return \@ret; +} + +sub otherlanguages_pages ($) { + my $page=shift; + + my %ret; + map { + $ret{$_} = otherlanguage_page($page, $_) + } otherlanguages_codes($page); + return \%ret; } @@ -989,30 +1019,25 @@ sub otherlanguagesloop ($) { my $page=shift; my @ret; - my %otherpages=%{otherlanguages($page)}; - while (my ($lang, $otherpage) = each %otherpages) { - if (istranslation($page) && masterpage($page) eq $otherpage) { - push @ret, { - url => urlto_with_orig_beautiful_urlpath($otherpage, $page), - code => $lang, - language => languagename($lang), - master => 1, - }; - } - elsif (istranslation($otherpage)) { - push @ret, { - url => urlto_with_orig_beautiful_urlpath($otherpage, $page), - code => $lang, - language => languagename($lang), - percent => percenttranslated($otherpage), - } + if (istranslation($page)) { + push @ret, { + url => urlto_with_orig_beautiful_urlpath(masterpage($page), $page), + code => $config{po_master_language}{code}, + language => $config{po_master_language}{name}, + master => 1, + }; + } + foreach my $lang (@{otherlanguages_codes($page)}) { + next if $lang eq $config{po_master_language}{code}; + my $otherpage = otherlanguage_page($page, $lang); + push @ret, { + url => urlto_with_orig_beautiful_urlpath($otherpage, $page), + code => $lang, + language => languagename($lang), + percent => percenttranslated($otherpage), } } - return sort { - return -1 if $a->{code} eq $config{po_master_language}{code}; - return 1 if $b->{code} eq $config{po_master_language}{code}; - return $a->{language} cmp $b->{language}; - } @ret; + return @ret; } sub homepageurl (;$) { diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index 585e14383..6b2a30786 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -54,10 +54,10 @@ Supported languages `po_slave_languages` is used to set the list of supported "slave" languages, such as: - po_slave_languages => { 'fr' => 'Français', + po_slave_languages => [ 'fr' => 'Français', 'es' => 'Español', 'de' => 'Deutsch', - } + ] Decide which pages are translatable ----------------------------------- @@ -254,15 +254,6 @@ once [[intrigeri]]'s `meta` branch is merged. An integration branch, called `meta-po`, merges [[intrigeri]]'s `po` and `meta` branches, and thus has this additional features. -Language display order ----------------------- - -Jonas pointed out that one might want to control the order that links to -other languages are listed, for various reasons. Currently, there is no -order, as `po_slave_languages` is a hash. It would need to be converted -to an array to support this. (If twere done, twere best done quickly.) ---[[Joey]] - Pagespecs --------- -- cgit v1.2.3 From 4f44534d72c9a9a947bc38a3cb4987705c25bea5 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sat, 26 Jun 2010 01:16:56 +0200 Subject: po: s/utf-8/UTF-8, to solve part of the double commit bug. --- IkiWiki/Plugin/po.pm | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'IkiWiki') diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 7d5dfee03..ac4401e48 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -902,15 +902,15 @@ sub refreshpot ($) { my $doc=Locale::Po4a::Chooser::new(po4a_type($masterfile), po4a_options($masterfile)); $doc->{TT}{utf_mode} = 1; - $doc->{TT}{file_in_charset} = 'utf-8'; - $doc->{TT}{file_out_charset} = 'utf-8'; + $doc->{TT}{file_in_charset} = 'UTF-8'; + $doc->{TT}{file_out_charset} = 'UTF-8'; $doc->read($masterfile); # let's cheat a bit to force porefs option to be passed to # Locale::Po4a::Po; this is undocument use of internal # Locale::Po4a::TransTractor's data, compulsory since this module # prevents us from using the porefs option. $doc->{TT}{po_out}=Locale::Po4a::Po->new({ 'porefs' => 'none' }); - $doc->{TT}{po_out}->set_charset('utf-8'); + $doc->{TT}{po_out}->set_charset('UTF-8'); # do the actual work $doc->parse; IkiWiki::prep_writefile(basename($potfile),dirname($potfile)); @@ -996,8 +996,8 @@ sub percenttranslated ($) { $doc->process( 'po_in_name' => [ $file ], 'file_in_name' => [ $masterfile ], - 'file_in_charset' => 'utf-8', - 'file_out_charset' => 'utf-8', + 'file_in_charset' => 'UTF-8', + 'file_out_charset' => 'UTF-8', ) or error("po(percenttranslated) ". sprintf(gettext("failed to translate %s"), $page)); my ($percent,$hit,$queries) = $doc->stats(); @@ -1143,8 +1143,8 @@ sub po_to_markup ($$) { $doc->process( 'po_in_name' => [ $infile ], 'file_in_name' => [ $masterfile ], - 'file_in_charset' => 'utf-8', - 'file_out_charset' => 'utf-8', + 'file_in_charset' => 'UTF-8', + 'file_out_charset' => 'UTF-8', ) or return $fail->(gettext("failed to translate")); $doc->write($outfile) or return $fail->(sprintf(gettext("failed to write %s"), $outfile)); -- cgit v1.2.3 From dcd57dd5c9f3265bb7a78a5696b90976698c43aa Mon Sep 17 00:00:00 2001 From: intrigeri Date: Tue, 29 Jun 2010 15:13:23 +0200 Subject: Add a fullpage arg to filter. Set it to true every time IkiWiki::filter is called on a full page's content. This is a much nicer solution, for the po plugin, than previous whitelisting using caller(). --- IkiWiki.pm | 6 ++++-- IkiWiki/Plugin/editpage.pm | 2 +- IkiWiki/Plugin/inline.pm | 4 ++-- IkiWiki/Plugin/po.pm | 6 ++---- IkiWiki/Plugin/sidebar.pm | 2 +- IkiWiki/Render.pm | 4 ++-- doc/plugins/write.mdwn | 4 +++- 7 files changed, 15 insertions(+), 13 deletions(-) (limited to 'IkiWiki') diff --git a/IkiWiki.pm b/IkiWiki.pm index 0457a6c61..7b5fd283d 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -1396,14 +1396,16 @@ sub preprocess ($$$;$$) { return $content; } -sub filter ($$$) { +sub filter ($$$;$) { my $page=shift; my $destpage=shift; my $content=shift; + my $fullpage=shift; + $fullpage = 0 unless defined $fullpage; run_hooks(filter => sub { $content=shift->(page => $page, destpage => $destpage, - content => $content); + content => $content, fullpage => $fullpage); }); return $content; diff --git a/IkiWiki/Plugin/editpage.pm b/IkiWiki/Plugin/editpage.pm index 1a04a72b5..706630203 100644 --- a/IkiWiki/Plugin/editpage.pm +++ b/IkiWiki/Plugin/editpage.pm @@ -187,7 +187,7 @@ sub cgi_editpage ($$) { my $preview=htmlize($page, $page, $type, linkify($page, $page, preprocess($page, $page, - filter($page, $page, $content), 0, 1))); + filter($page, $page, $content, 'fullpage'), 0, 1))); run_hooks(format => sub { $preview=shift->( page => $page, diff --git a/IkiWiki/Plugin/inline.pm b/IkiWiki/Plugin/inline.pm index 715a3d652..a04dd6630 100644 --- a/IkiWiki/Plugin/inline.pm +++ b/IkiWiki/Plugin/inline.pm @@ -403,7 +403,7 @@ sub preprocess_inline (@) { linkify($page, $params{destpage}, preprocess($page, $params{destpage}, filter($page, $params{destpage}, - readfile(srcfile($file))))); + readfile(srcfile($file)), 'fullpage'))); } else { $ret.="\n". @@ -474,7 +474,7 @@ sub get_inline_content ($$) { linkify($page, $destpage, preprocess($page, $destpage, filter($page, $destpage, - readfile(srcfile($file)))))); + readfile(srcfile($file)), 'fullpage')))); $nested--; if (isinternal($page)) { # make inlined text of internal pages searchable diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index ac4401e48..93cf6bbdf 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -259,11 +259,9 @@ sub filter (@) { my $page = $params{page}; my $destpage = $params{destpage}; my $content = $params{content}; + my $fullpage = $params{fullpage}; - my @caller = caller(4); - # FIXME: need to whitelist inline as well? - unless ($caller[3] eq "IkiWiki::render" || - $caller[3] eq 'IkiWiki::Plugin::sidebar::sidebar_content') { + unless ($fullpage) { return $content; } diff --git a/IkiWiki/Plugin/sidebar.pm b/IkiWiki/Plugin/sidebar.pm index 2d495db2c..100015cee 100644 --- a/IkiWiki/Plugin/sidebar.pm +++ b/IkiWiki/Plugin/sidebar.pm @@ -89,7 +89,7 @@ sub sidebar_content ($) { return IkiWiki::htmlize($sidebar_page, $page, $sidebar_type, IkiWiki::linkify($sidebar_page, $page, IkiWiki::preprocess($sidebar_page, $page, - IkiWiki::filter($sidebar_page, $page, $content)))); + IkiWiki::filter($sidebar_page, $page, $content, 'fullpage')))); } } diff --git a/IkiWiki/Render.pm b/IkiWiki/Render.pm index a653ab2da..233d093ed 100644 --- a/IkiWiki/Render.pm +++ b/IkiWiki/Render.pm @@ -232,7 +232,7 @@ sub render ($$) { linkify($page, $page, preprocess($page, $page, filter($page, $page, - readfile($srcfile))))); + readfile($srcfile), 'fullpage')))); my $output=htmlpage($page); writefile($output, $config{destdir}, genpage($page, $content)); @@ -837,7 +837,7 @@ sub commandline_render () { my $content=readfile($srcfile); my $page=pagename($file); $pagesources{$page}=$file; - $content=filter($page, $page, $content); + $content=filter($page, $page, $content, 'fullpage'); $content=preprocess($page, $page, $content); $content=linkify($page, $page, $content); $content=htmlize($page, $page, $type, $content); diff --git a/doc/plugins/write.mdwn b/doc/plugins/write.mdwn index a921b9a02..15ed08d82 100644 --- a/doc/plugins/write.mdwn +++ b/doc/plugins/write.mdwn @@ -200,7 +200,9 @@ value is ignored. Runs on the raw source of a page, before anything else touches it, and can make arbitrary changes. The function is passed named parameters "page", -"destpage", and "content". It should return the filtered content. +"destpage", "content" and "fullpage". "fullpage" is a true value if, +and only if, a full page's content is being filtered, e.g. as opposed +to a directive parameter. It should return the filtered content. ### preprocess -- cgit v1.2.3 From b225fdc44d4b3d2853db622d59aed7b59788aeec Mon Sep 17 00:00:00 2001 From: intrigeri Date: Tue, 29 Jun 2010 15:45:34 +0200 Subject: po: added a needstranslation() pagespec --- IkiWiki/Plugin/po.pm | 15 +++++++++++++++ doc/ikiwiki/pagespec/po.mdwn | 2 ++ 2 files changed, 17 insertions(+) (limited to 'IkiWiki') diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 93cf6bbdf..552b6b51b 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -1291,4 +1291,19 @@ sub match_currentlang ($$;@) { } } +sub match_needstranslation ($$;@) { + my $page=shift; + + my $percenttranslated=IkiWiki::Plugin::po::percenttranslated($page); + if ($percenttranslated eq 'N/A') { + return IkiWiki::FailReason->new("file is not a translation page"); + } + elsif ($percenttranslated < 100) { + return IkiWiki::SuccessReason->new("file has $percenttranslated translated"); + } + else { + return IkiWiki::FailReason->new("file is fully translated"); + } +} + 1 diff --git a/doc/ikiwiki/pagespec/po.mdwn b/doc/ikiwiki/pagespec/po.mdwn index 40ed9efb6..f8b398575 100644 --- a/doc/ikiwiki/pagespec/po.mdwn +++ b/doc/ikiwiki/pagespec/po.mdwn @@ -11,6 +11,8 @@ wiki: specified as a ISO639-1 (two-letter) language code. * "`currentlang()`" - tests whether a page is written in the same language as the current page. +* "`needstranslation()`" - tests whether a page needs translation + work. Only slave pages match this PageSpec. Note that every non-po page is considered to be written in `po_master_language`, as specified in `ikiwiki.setup`. -- cgit v1.2.3 From c9b1a4dd7d826b5e8e2d0a757ba5ecbba8d832b2 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Fri, 2 Jul 2010 11:46:49 +0200 Subject: bugfix --- IkiWiki/Plugin/po.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'IkiWiki') diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 552b6b51b..29945da33 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -865,7 +865,7 @@ sub otherlanguages_pages ($) { my %ret; map { $ret{$_} = otherlanguage_page($page, $_) - } otherlanguages_codes($page); + } @{otherlanguages_codes($page)}; return \%ret; } -- cgit v1.2.3 From 4a1cb092baabda6182fd291dfc9810f6c8efb17e Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sun, 11 Jul 2010 11:00:43 +0200 Subject: Revert po vs. template kludges. This reverts commits dcd57dd5c9f3265bb7a78a5696b90976698c43aa, d4136aea8aa8968d2cd87b40e8d85301a3549323 and d877b9644bcfbbfc5eaf3f7fc13cb96ecda946c9. --- IkiWiki.pm | 6 ++---- IkiWiki/Plugin/editpage.pm | 2 +- IkiWiki/Plugin/inline.pm | 4 ++-- IkiWiki/Plugin/po.pm | 6 ------ IkiWiki/Plugin/sidebar.pm | 2 +- IkiWiki/Render.pm | 4 ++-- doc/plugins/write.mdwn | 4 +--- 7 files changed, 9 insertions(+), 19 deletions(-) (limited to 'IkiWiki') diff --git a/IkiWiki.pm b/IkiWiki.pm index f9a30a202..cd9c40795 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -1403,16 +1403,14 @@ sub preprocess ($$$;$$) { return $content; } -sub filter ($$$;$) { +sub filter ($$$) { my $page=shift; my $destpage=shift; my $content=shift; - my $fullpage=shift; - $fullpage = 0 unless defined $fullpage; run_hooks(filter => sub { $content=shift->(page => $page, destpage => $destpage, - content => $content, fullpage => $fullpage); + content => $content); }); return $content; diff --git a/IkiWiki/Plugin/editpage.pm b/IkiWiki/Plugin/editpage.pm index 706630203..1a04a72b5 100644 --- a/IkiWiki/Plugin/editpage.pm +++ b/IkiWiki/Plugin/editpage.pm @@ -187,7 +187,7 @@ sub cgi_editpage ($$) { my $preview=htmlize($page, $page, $type, linkify($page, $page, preprocess($page, $page, - filter($page, $page, $content, 'fullpage'), 0, 1))); + filter($page, $page, $content), 0, 1))); run_hooks(format => sub { $preview=shift->( page => $page, diff --git a/IkiWiki/Plugin/inline.pm b/IkiWiki/Plugin/inline.pm index a04dd6630..715a3d652 100644 --- a/IkiWiki/Plugin/inline.pm +++ b/IkiWiki/Plugin/inline.pm @@ -403,7 +403,7 @@ sub preprocess_inline (@) { linkify($page, $params{destpage}, preprocess($page, $params{destpage}, filter($page, $params{destpage}, - readfile(srcfile($file)), 'fullpage'))); + readfile(srcfile($file))))); } else { $ret.="\n". @@ -474,7 +474,7 @@ sub get_inline_content ($$) { linkify($page, $destpage, preprocess($page, $destpage, filter($page, $destpage, - readfile(srcfile($file)), 'fullpage')))); + readfile(srcfile($file)))))); $nested--; if (isinternal($page)) { # make inlined text of internal pages searchable diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index cadc13ba1..ecfbb6f78 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -259,12 +259,6 @@ sub filter (@) { my $page = $params{page}; my $destpage = $params{destpage}; my $content = $params{content}; - my $fullpage = $params{fullpage}; - - unless ($fullpage) { - return $content; - } - if (istranslation($page) && ! alreadyfiltered($page, $destpage)) { $content = po_to_markup($page, $content); setalreadyfiltered($page, $destpage); diff --git a/IkiWiki/Plugin/sidebar.pm b/IkiWiki/Plugin/sidebar.pm index 100015cee..2d495db2c 100644 --- a/IkiWiki/Plugin/sidebar.pm +++ b/IkiWiki/Plugin/sidebar.pm @@ -89,7 +89,7 @@ sub sidebar_content ($) { return IkiWiki::htmlize($sidebar_page, $page, $sidebar_type, IkiWiki::linkify($sidebar_page, $page, IkiWiki::preprocess($sidebar_page, $page, - IkiWiki::filter($sidebar_page, $page, $content, 'fullpage')))); + IkiWiki::filter($sidebar_page, $page, $content)))); } } diff --git a/IkiWiki/Render.pm b/IkiWiki/Render.pm index 233d093ed..a653ab2da 100644 --- a/IkiWiki/Render.pm +++ b/IkiWiki/Render.pm @@ -232,7 +232,7 @@ sub render ($$) { linkify($page, $page, preprocess($page, $page, filter($page, $page, - readfile($srcfile), 'fullpage')))); + readfile($srcfile))))); my $output=htmlpage($page); writefile($output, $config{destdir}, genpage($page, $content)); @@ -837,7 +837,7 @@ sub commandline_render () { my $content=readfile($srcfile); my $page=pagename($file); $pagesources{$page}=$file; - $content=filter($page, $page, $content, 'fullpage'); + $content=filter($page, $page, $content); $content=preprocess($page, $page, $content); $content=linkify($page, $page, $content); $content=htmlize($page, $page, $type, $content); diff --git a/doc/plugins/write.mdwn b/doc/plugins/write.mdwn index 8071f323e..bb8012342 100644 --- a/doc/plugins/write.mdwn +++ b/doc/plugins/write.mdwn @@ -200,9 +200,7 @@ value is ignored. Runs on the raw source of a page, before anything else touches it, and can make arbitrary changes. The function is passed named parameters "page", -"destpage", "content" and "fullpage". "fullpage" is a true value if, -and only if, a full page's content is being filtered, e.g. as opposed -to a directive parameter. It should return the filtered content. +"destpage", and "content". It should return the filtered content. ### preprocess -- cgit v1.2.3 From 98cc9460ac67fee606437712882cfa1e5d259729 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sun, 11 Jul 2010 11:58:09 +0200 Subject: po: added an optional target percentage to needstranslation --- IkiWiki/Plugin/po.pm | 17 +++++++++++++++-- doc/ikiwiki/pagespec/po.mdwn | 5 ++++- 2 files changed, 19 insertions(+), 3 deletions(-) (limited to 'IkiWiki') diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index ecfbb6f78..9cb047992 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -1287,16 +1287,29 @@ sub match_currentlang ($$;@) { sub match_needstranslation ($$;@) { my $page=shift; + my $wanted=shift; + + if (defined $wanted && $wanted ne "") { + if ($wanted !~ /^\d+$/) { + return IkiWiki::FailReason->new("parameter is not an integer"); + } + elsif ($wanted > 100) { + return IkiWiki::FailReason->new("parameter is greater than 100"); + } + } + else { + $wanted=100; + } my $percenttranslated=IkiWiki::Plugin::po::percenttranslated($page); if ($percenttranslated eq 'N/A') { return IkiWiki::FailReason->new("file is not a translatable page"); } - elsif ($percenttranslated < 100) { + elsif ($percenttranslated < $wanted) { return IkiWiki::SuccessReason->new("file has $percenttranslated translated"); } else { - return IkiWiki::FailReason->new("file is fully translated"); + return IkiWiki::FailReason->new("file is translated enough"); } } diff --git a/doc/ikiwiki/pagespec/po.mdwn b/doc/ikiwiki/pagespec/po.mdwn index f8b398575..f9956404c 100644 --- a/doc/ikiwiki/pagespec/po.mdwn +++ b/doc/ikiwiki/pagespec/po.mdwn @@ -12,7 +12,10 @@ wiki: * "`currentlang()`" - tests whether a page is written in the same language as the current page. * "`needstranslation()`" - tests whether a page needs translation - work. Only slave pages match this PageSpec. + work. Only slave pages match this PageSpec. A minimum target + translation percentage can optionally be passed as an integer + parameter: "`needstranslation(50)`" matches only pages less than 50% + translated. Note that every non-po page is considered to be written in `po_master_language`, as specified in `ikiwiki.setup`. -- cgit v1.2.3 From 4449a70214b561da14f8e566f2747517c941cb40 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sun, 11 Jul 2010 12:28:02 +0200 Subject: po: check validity of po_slave_languages array. --- IkiWiki/Plugin/po.pm | 3 +++ 1 file changed, 3 insertions(+) (limited to 'IkiWiki') diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 9cb047992..43804a8f2 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -141,6 +141,9 @@ sub checkconfig () { if (ref $config{po_slave_languages} eq 'ARRAY') { my %slaves; + if (@{$config{po_slave_languages}} % 2 != 0) { + error(sprintf(gettext("The %s field is invalid."), 'po_slave_languages')); + } for (my $i=0; $i<@{$config{po_slave_languages}}; $i = $i + 2) { $slaves{$config{po_slave_languages}->[$i]} = $config{po_slave_languages}->[$i + 1]; push @slavelanguages, $config{po_slave_languages}->[$i]; -- cgit v1.2.3 From bfd896f5e59d7ac1e81e7ef315552273681c8bb4 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sun, 18 Jul 2010 19:37:14 -0400 Subject: typo --- IkiWiki/Plugin/po.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'IkiWiki') diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 43804a8f2..dc73c73c3 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -28,7 +28,7 @@ use UNIVERSAL; my %translations; my @origneedsbuild; my %origsubs; -my @slavelanguages; # orderer as in config po_slave_languages +my @slavelanguages; # ordered as in config po_slave_languages memoize("istranslatable"); memoize("_istranslation"); -- cgit v1.2.3 From 35c9956df0cb92a1088d763a45e863079bfd8e50 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sun, 18 Jul 2010 20:03:04 -0400 Subject: Revert "po_slave_languages can now be a hash, if order matters." This reverts commit 4cf185e781a5f94373b30ec9a0e10dfb626b6d86. That commit broke t/po.t (probably the test case only is testing too close the the old implementation and needs correcting). Also, we have not decided how to want to represent it yet, so I'm not ready for this change. Conflicts: IkiWiki/Plugin/po.pm doc/plugins/po.mdwn --- IkiWiki/Plugin/po.pm | 98 +++++++++++++++++++--------------------------------- doc/plugins/po.mdwn | 4 +-- 2 files changed, 37 insertions(+), 65 deletions(-) (limited to 'IkiWiki') diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index dc73c73c3..224412676 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -28,7 +28,6 @@ use UNIVERSAL; my %translations; my @origneedsbuild; my %origsubs; -my @slavelanguages; # ordered as in config po_slave_languages memoize("istranslatable"); memoize("_istranslation"); @@ -105,11 +104,11 @@ sub getsetup () { }, po_slave_languages => { type => "string", - example => [ + example => { 'fr' => 'Français', 'es' => 'Español', 'de' => 'Deutsch' - ], + }, description => "slave languages (PO files)", safe => 1, rebuild => 1, @@ -138,24 +137,6 @@ sub checkconfig () { $field, 'po')); } } - - if (ref $config{po_slave_languages} eq 'ARRAY') { - my %slaves; - if (@{$config{po_slave_languages}} % 2 != 0) { - error(sprintf(gettext("The %s field is invalid."), 'po_slave_languages')); - } - for (my $i=0; $i<@{$config{po_slave_languages}}; $i = $i + 2) { - $slaves{$config{po_slave_languages}->[$i]} = $config{po_slave_languages}->[$i + 1]; - push @slavelanguages, $config{po_slave_languages}->[$i]; - } - $config{po_slave_languages} = \%slaves; - } - elsif (ref $config{po_slave_languages} eq 'HASH') { - @slavelanguages = sort { - $config{po_slave_languages}->{$a} cmp $config{po_slave_languages}->{$b}; - } keys %{$config{po_slave_languages}}; - } - delete $config{po_slave_languages}{$config{po_master_language}{code}};; map { @@ -216,7 +197,7 @@ sub needsbuild () { # make existing translations depend on the corresponding master page foreach my $master (keys %translations) { - map add_depends($_, $master), values %{otherlanguages_pages($master)}; + map add_depends($_, $master), values %{otherlanguages($master)}; } } @@ -248,7 +229,7 @@ sub scan (@) { # make sure any destpage's translations has # $page in its backlinks push @{$links{$page}}, - values %{otherlanguages_pages($destpage)}; + values %{otherlanguages($destpage)}; } } } @@ -306,7 +287,7 @@ sub pagetemplate (@) { } if ($template->query(name => "otherlanguages")) { $template->param(otherlanguages => [otherlanguagesloop($page)]); - map add_depends($page, $_), (values %{otherlanguages_pages($page)}); + map add_depends($page, $_), (values %{otherlanguages($page)}); } if ($config{discussion} && istranslation($page)) { if ($page !~ /.*\/\Q$config{discussionpage}\E$/i && @@ -359,12 +340,12 @@ sub renamepages (@) { return () unless istranslatable($torename{src}); my @ret; - my %otherpages=%{otherlanguages_pages($torename{src})}; + my %otherpages=%{otherlanguages($torename{src})}; while (my ($lang, $otherpage) = each %otherpages) { push @ret, { src => $otherpage, srcfile => $pagesources{$otherpage}, - dest => otherlanguage_page($torename{dest}, $lang), + dest => otherlanguage($torename{dest}, $lang), destfile => $torename{dest}.".".$lang.".po", required => 0, }; @@ -831,7 +812,7 @@ sub islanguagecode ($) { return $code =~ /^[a-z]{2}$/; } -sub otherlanguage_page ($$) { +sub otherlanguage ($$) { my $page=shift; my $code=shift; @@ -839,31 +820,17 @@ sub otherlanguage_page ($$) { return masterpage($page) . '.' . $code; } -# Returns the list of other languages codes: the master language comes first, -# then the codes are ordered the same way as in po_slave_languages, if it is -# an array, or in the language name lexical order, if it is a hash. -sub otherlanguages_codes ($) { +sub otherlanguages ($) { my $page=shift; - my @ret; - return \@ret unless istranslation($page) || istranslatable($page); + my %ret; + return \%ret unless istranslation($page) || istranslatable($page); my $curlang=lang($page); foreach my $lang - ($config{po_master_language}{code}, @slavelanguages) { + ($config{po_master_language}{code}, keys %{$config{po_slave_languages}}) { next if $lang eq $curlang; - push @ret, $lang; + $ret{$lang}=otherlanguage($page, $lang); } - return \@ret; -} - -sub otherlanguages_pages ($) { - my $page=shift; - - my %ret; - map { - $ret{$_} = otherlanguage_page($page, $_) - } @{otherlanguages_codes($page)}; - return \%ret; } @@ -1014,25 +981,30 @@ sub otherlanguagesloop ($) { my $page=shift; my @ret; - if (istranslation($page)) { - push @ret, { - url => urlto_with_orig_beautiful_urlpath(masterpage($page), $page), - code => $config{po_master_language}{code}, - language => $config{po_master_language}{name}, - master => 1, - }; - } - foreach my $lang (@{otherlanguages_codes($page)}) { - next if $lang eq $config{po_master_language}{code}; - my $otherpage = otherlanguage_page($page, $lang); - push @ret, { - url => urlto_with_orig_beautiful_urlpath($otherpage, $page), - code => $lang, - language => languagename($lang), - percent => percenttranslated($otherpage), + my %otherpages=%{otherlanguages($page)}; + while (my ($lang, $otherpage) = each %otherpages) { + if (istranslation($page) && masterpage($page) eq $otherpage) { + push @ret, { + url => urlto_with_orig_beautiful_urlpath($otherpage, $page), + code => $lang, + language => languagename($lang), + master => 1, + }; + } + elsif (istranslation($otherpage)) { + push @ret, { + url => urlto_with_orig_beautiful_urlpath($otherpage, $page), + code => $lang, + language => languagename($lang), + percent => percenttranslated($otherpage), + } } } - return @ret; + return sort { + return -1 if $a->{code} eq $config{po_master_language}{code}; + return 1 if $b->{code} eq $config{po_master_language}{code}; + return $a->{language} cmp $b->{language}; + } @ret; } sub homepageurl (;$) { diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index d6f82912c..53327c1da 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -54,10 +54,10 @@ Supported languages `po_slave_languages` is used to set the list of supported "slave" languages, such as: - po_slave_languages => [ 'fr' => 'Français', + po_slave_languages => { 'fr' => 'Français', 'es' => 'Español', 'de' => 'Deutsch', - ] + } Decide which pages are translatable ----------------------------------- -- cgit v1.2.3