+my $scrubber;
+my $stemmer;
+sub index (@) { #{{{
+ my %params=@_;
+
+ return $params{content} if $IkiWiki::preprocessing{$params{destpage}};
+
+ setupfiles();
+
+ # A unique pageterm is used to identify the document for a page.
+ my $pageterm=pageterm($params{page});
+ return $params{content} unless defined $pageterm;
+
+ my $db=xapiandb();
+ my $doc=Search::Xapian::Document->new();
+ my $caption=IkiWiki::pagetitle($params{page});
+ my $title;
+ if (exists $pagestate{$params{page}}{meta} &&
+ exists $pagestate{$params{page}}{meta}{title}) {
+ $title=$pagestate{$params{page}}{meta}{title};
+ }
+ else {
+ $title=$caption;
+ }
+
+ # Remove html from text to be indexed.
+ if (! defined $scrubber) {
+ eval q{use HTML::Scrubber};
+ if (! $@) {
+ $scrubber=HTML::Scrubber->new(allow => []);
+ }
+ }
+ my $toindex = defined $scrubber ? $scrubber->scrub($params{content}) : $params{content};
+
+ # Take 512 characters for a sample, then extend it out
+ # if it stopped in the middle of a word.
+ my $size=512;
+ my ($sample)=substr($toindex, 0, $size);
+ if (length($sample) == $size) {
+ my $max=length($toindex);
+ my $next;
+ while ($size < $max &&
+ ($next=substr($toindex, $size++, 1)) !~ /\s/) {
+ $sample.=$next;
+ }
+ }
+ $sample=~s/\n/ /g;
+
+ # data used by omega
+ # Decode html entities in it, since omega re-encodes them.
+ eval q{use HTML::Entities};
+ $doc->set_data(
+ "url=".urlto($params{page}, "")."\n".
+ "sample=".decode_entities($sample)."\n".
+ "caption=".decode_entities($caption)."\n".
+ "modtime=$IkiWiki::pagemtime{$params{page}}\n".
+ "size=".length($params{content})."\n"
+ );
+
+ # Index document and add terms for other metadata.
+ my $tg = Search::Xapian::TermGenerator->new();
+ if (! $stemmer) {
+ my $langcode=$ENV{LANG} || "en";
+ $langcode=~s/_.*//;
+
+ # This whitelist is here to work around a xapian bug (#486138)
+ my @whitelist=qw{da de en es fi fr hu it no pt ru ro sv tr};
+
+ if (grep { $_ eq $langcode } @whitelist) {
+ $stemmer=Search::Xapian::Stem->new($langcode);
+ }
+ else {
+ $stemmer=Search::Xapian::Stem->new("english");
+ }
+ }
+ $tg->set_stemmer($stemmer);
+ $tg->set_document($doc);
+ $tg->index_text($params{page}, 2);
+ $tg->index_text($caption, 2);
+ $tg->index_text($title, 2) if $title ne $caption;
+ $tg->index_text($toindex);
+ $tg->index_text(lc($title), 1, "ZS"); # for title:foo
+ foreach my $link (@{$links{$params{page}}}) {
+ $tg->index_text(lc($link), 1, "ZLINK"); # for link:bar
+ }
+
+ $doc->add_term($pageterm);
+ $db->replace_document_by_term($pageterm, $doc);
+
+ return $params{content};