#!/usr/bin/perl use warnings; use strict; use feature qw(switch); no if $] >= 5.018, warnings => "experimental::smartmatch"; use Pandoc::Filter 0.05; use Pandoc::Elements; use Text::BibTeX::Entry; use Path::Tiny; use List::Util qw(pairmap); use DateTime::Format::Flexible; my $bibfilename = $ENV{'PANDOC_CITEPROC_FILE'} || 'bibliography.bib'; my $bibfile = path($bibfilename); my $bibdata = new Text::BibTeX::Entry; my (@a, $i); pandoc_filter sub { my $self = shift; return unless ($self->name eq 'RawInline' and $self->format eq 'mediawiki'); given ($self->content) { when (/^\{\{cite\s+(\w+)\s*\|(.*)\}\}$/) { my $id = 'ref'.++$i; my @data = pairmap { $b =~ s/"/\\"/g; "$a=\"$b\"" } map { /^\s*(\w+)\s*=\s*"?(.*?)"?\s*$/ } split( /\|/, $2 ); $bibdata->parse_s (join ",\n", '@'.$1.'{'.$id, @data, '}'); if ( ! $bibdata->get('author') ) { my @authors; for ( my $i = 1;; $i++ ) { my ( $first, $last ); if ( $i == 1 and $bibdata->get('first') ) { $first = $bibdata->get('first'); $bibdata->delete('first'); } elsif ( $bibdata->get("first$i") ) { $first = $bibdata->get("first$i"); $bibdata->delete("first$i"); } if ( $i == 1 and $bibdata->get('last') ) { $last = $bibdata->get('last'); $bibdata->delete('last'); } elsif ( $bibdata->get("last$i") ) { $last = $bibdata->get("last$i"); $bibdata->delete("last$i"); } if ( $first and $last ) { push @authors, "$first {$last}"; } elsif ($first) { push @authors, $first; } elsif ($last) { push @authors, $last; } else { last; } } if ( @authors > 0 ) { $bibdata->set( 'author', join ( ' and ', @authors ) ); }; }; if ( $bibdata->type =~ /web/i ) { $bibdata->set_type('online'); if ( my $urldate = $bibdata->get('accessdate') ) { my $dt = DateTime::Format::Flexible->parse_datetime($urldate); $bibdata->set( 'urldate', $dt->format_cldr('yyyy-MM-dd') ); $bibdata->delete('accessdate'); }; }; $bibfile->spew( '' ) if ( $i <= 1 ); $bibfile->append( $bibdata->print_s ); return Cite( [{ 'citationId' => $id, 'citationPrefix' => [], 'citationSuffix' => [], 'citationMode' => { t => 'NormalCitation', c => [], }, 'citationNoteNum' => 0, 'citationHash' => 0, }], [ Str $id ], ); } when (/^\{\{citation needed\}\}$/) { say STDERR "WARNING: Mediawiki citation needed."; return [ Str "citation", Space, Str "needed", ]; } default { say STDERR "WARNING: Mediawiki unknown data skipped: " . '"' . $_ . '"'; return Str ""; } } };