summaryrefslogtreecommitdiffstats
path: root/roles/wiki/files/var
diff options
context:
space:
mode:
Diffstat (limited to 'roles/wiki/files/var')
-rw-r--r--roles/wiki/files/var/lib/ikiwiki/IkiWiki/Plugin/pandoc.pm55
-rw-r--r--roles/wiki/files/var/lib/ikiwiki/fripost-wiki.setup3
2 files changed, 47 insertions, 11 deletions
diff --git a/roles/wiki/files/var/lib/ikiwiki/IkiWiki/Plugin/pandoc.pm b/roles/wiki/files/var/lib/ikiwiki/IkiWiki/Plugin/pandoc.pm
index 25081ef..34bdd89 100644
--- a/roles/wiki/files/var/lib/ikiwiki/IkiWiki/Plugin/pandoc.pm
+++ b/roles/wiki/files/var/lib/ikiwiki/IkiWiki/Plugin/pandoc.pm
@@ -4,40 +4,57 @@ package IkiWiki::Plugin::pandoc;
use warnings;
use strict;
use IkiWiki;
use FileHandle;
use IPC::Open2;
use File::Path qw/make_path/;
use JSON;
# activate with 'generate_$format' in meta; turn on all with 'generate_all_formats'.
my %extra_formats = (
pdf => { ext=>'pdf', label=>'PDF', format=>'latex', extra=>[], order=>1 },
docx => { ext=>'docx', label=>'DOCX', format=>'docx', extra=>[], order=>2 },
odt => { ext=>'odt', label=>'ODT', format=>'odt', extra=>[], order=>3 },
beamer => { ext=>'beamer.pdf', label=>'Beamer', format=>'beamer', extra=>[], order=>4 },
revealjs => { ext=>'revealjs.html', label=>'RevealJS', format=>'revealjs', extra=>['--self-contained'], order=>5 },
epub => { ext=>'epub', label=>'EPUB', format=>'epub3', extra=>[], order=>6 },
latex => { ext=>'tex', label=>'LaTeX', format=>'latex', extra=>['--standalone'], order=>7 },
);
+my @scalar_meta_keys = qw/
+ title date bibliography csl subtitle abstract summary description
+ version lang locale titlesort tag fripost_debug_inner
+ /;
+
+my @list_meta_keys = qw/
+ author
+ /;
+
+my @hash_meta_keys = qw/
+ experiment
+ /;
+
+my @list_hash_meta_keys = qw/
+ references
+ /;
+
sub import {
my $markdown_ext = $config{pandoc_markdown_ext} || "mdwn";
# May be both a string with a single value, a string containing commas or an arrayref
if ($markdown_ext =~ /,/) {
$markdown_ext = [split /\s*,\s*/, $markdown_ext];
}
hook(type => "getsetup", id => "pandoc", call => \&getsetup);
hook(type => "pagetemplate", id => "pandoc", call => \&pagetemplate);
hook(type => "pageactions", id => "pandoc", call => \&pageactions);
if (ref $markdown_ext eq 'ARRAY') {
foreach my $mde (@$markdown_ext) {
hook(type => 'htmlize', id => $mde,
call => sub{ htmlize("markdown", @_) });
}
} else {
hook(type => "htmlize", id => $markdown_ext,
call => sub { htmlize("markdown", @_) });
@@ -79,40 +96,47 @@ sub getsetup () {
type => "string",
example => "/usr/local/bin/pandoc",
description => "Path to pandoc executable",
safe => 1,
rebuild => 0,
},
pandoc_citeproc => {
type => "string",
example => "/usr/local/bin/pandoc-citeproc",
description => "Path to pandoc-citeproc executable",
safe => 1,
rebuild => 0,
},
pandoc_markdown_ext => {
type => "string",
example => "mdwn,md,markdown",
description => "File extension(s) for Markdown files handled by Pandoc",
safe => 1,
rebuild => 1,
},
+ pandoc_markdown_fmt => {
+ type => "string",
+ example => "markdown",
+ description => "Format string to use when processing files handled by Pandoc.",
+ safe => 1,
+ rebuild => 1,
+ },
pandoc_latex => {
type => "boolean",
example => 0,
description => "Enable Pandoc processing of LaTeX documents (extension=tex)",
safe => 1,
rebuild => 1,
},
pandoc_rst => {
type => "boolean",
example => 0,
description => "Enable Pandoc processing of reStructuredText documents (extension=rst)",
safe => 1,
rebuild => 1,
},
pandoc_textile => {
type => "boolean",
example => 0,
description => "Enable Pandoc processing of Textile documents (extension=textile)",
safe => 1,
rebuild => 1,
@@ -392,115 +416,116 @@ sub htmlize ($@) {
foreach my $k (%{ $pagestate{$page}{meta} }) {
push @delkeys, $k if $k =~ /^pandoc_/;
}
delete $pagestate{$page}{meta}{$_} for @delkeys;
}
if ($mathopt && $mathconf{$mathopt}) {
if ($with_urls{$mathopt} && $custom_js) {
# In these cases, the 'custom js' is a misnomer: actually a server-side script
push @args, $mathconf{$mathopt} ."=". $custom_js;
} else {
push @args, $mathconf{$mathopt};
}
$pagestate{$page}{meta}{"pandoc_math"} = $mathopt;
$pagestate{$page}{meta}{"pandoc_math_$mathopt"} = 1;
$pagestate{$page}{meta}{"pandoc_math_custom_js"} = $custom_js if $custom_js;
}
# Convert to intermediate JSON format so that the title block
# can be parsed out
# We must omit the 'bibliography' parameter here, otherwise the list of
# references will be doubled.
+ my $markdown_fmt = $config{pandoc_markdown_fmt} || 'markdown';
my $to_json_pid = open2(*JSON_OUT, *PANDOC_OUT, $command,
- '-f', $format,
+ '-f', $markdown_fmt,
'-t', 'json',
- @args, '--normalize');
+ @args);
error("Unable to open $command") unless $to_json_pid;
# Workaround for perl bug (#376329)
require Encode;
my $content = Encode::encode_utf8($params{content});
# Protect inline plugin placeholders from being mangled by pandoc:
$content =~ s{<div class="inline" id="(\d+)"></div>}
{::INLINE::PLACEHOLDER::$1::}g;
print PANDOC_OUT $content;
close PANDOC_OUT;
my $json_content = <JSON_OUT>;
close JSON_OUT;
waitpid $to_json_pid, 0;
# Parse the title block out of the JSON and set the meta values
my $meta = undef;
my $decoded_json = decode_json($json_content);
# The representation of the meta block changed in pandoc version 1.18
- if (ref $decoded_json eq 'HASH' && $decoded_json->{'Meta'}) {
- $meta = $decoded_json->{'Meta'} || {}; # post-1.18 version
+ if (ref $decoded_json eq 'HASH' && $decoded_json->{'meta'}) {
+ $meta = $decoded_json->{'meta'} || {}; # post-1.18 version
} elsif (ref $decoded_json eq 'ARRAY') {
$meta = $decoded_json->[0]->{'unMeta'} || {}; # pre-1.18 version
}
unless ($meta) {
warn "WARNING: Unexpected format for meta block. Incompatible version of Pandoc?\n";
}
# Get some selected meta attributes, more specifically:
# (title date bibliography csl subtitle abstract summary description
# version lang locale references author [+ num_authors primary_author]),
# as well as some configuration options (generate_*, *_extra_options, *_template).
my @format_keys = grep { $_ ne 'pdf' } keys %extra_formats;
- my %scalar_meta = map { ($_=>undef) } qw(
- title date bibliography csl subtitle abstract summary
- description version lang locale);
+ my %scalar_meta = map { ($_=>undef) } @scalar_meta_keys;
$scalar_meta{$_.'_template'} = undef for @format_keys;
my %bool_meta = map { ("generate_$_"=>0) } keys %extra_formats;
- my %list_meta = map { ($_=>[]) } qw/author references/;
+ my %list_meta = map { ($_=>[]) } (
+ @list_meta_keys, @list_hash_meta_keys, @hash_meta_keys);
$list_meta{$_.'_extra_options'} = [] for @format_keys;
my $have_bibl = 0;
foreach my $k (keys %scalar_meta) {
next unless $meta->{$k};
$scalar_meta{$k} = compile_string($meta->{$k}->{c});
# NB! Note that this is potentially risky, since pagestate is sticky, and
# we only cleanup the pandoc_* values in {meta}.
$pagestate{$page}{meta}{$k} = $scalar_meta{$k};
$pagestate{$page}{meta}{"pandoc_$k"} = $pagestate{$page}{meta}{$k};
}
foreach my $k (keys %bool_meta) {
my $gen_all = $meta->{generate_all_formats} || {};
next unless $meta->{$k} || $gen_all->{c};
my $val = $meta->{$k} ? $meta->{$k}->{c} : $gen_all->{c};
# simplifies matters with JSON::(PP::)Boolean objects
$val = 1 if $val == 1 || $val eq 'true';
if (ref $val || $val =~ /^\s*(?:off|no|false|0)\s*$/i) {
$bool_meta{$k} = 0;
} else {
$bool_meta{$k} = 1;
$pagestate{$page}{meta}{"pandoc_$k"} = 1;
}
}
foreach my $k (keys %list_meta) {
next unless $meta->{$k};
$list_meta{$k} = unwrap_c($meta->{$k});
$list_meta{$k} = [$list_meta{$k}] unless ref $list_meta{$k} eq 'ARRAY';
$have_bibl = 1 if $k eq 'references';
+ $pagestate{$page}{meta}{$k} = $list_meta{$k};
$pagestate{$page}{meta}{"pandoc_$k"} = $list_meta{$k};
}
# Try to add other keys as scalars, with pandoc_ prefix only.
foreach my $k (keys %$meta) {
next if exists $scalar_meta{$k} || exists $list_meta{$k};
eval {
$pagestate{$page}{meta}{"pandoc_$k"} = compile_string($meta->{$k}->{c});
};
}
my $num_authors = scalar @{ $list_meta{author} };
$scalar_meta{num_authors} = $num_authors;
$pagestate{$page}{meta}{num_authors} = $num_authors;
if ($num_authors) {
$scalar_meta{primary_author} = $list_meta{author}->[0];
$pagestate{$page}{meta}{author} = join(', ', @{$list_meta{author}});
$pagestate{$page}{meta}{pandoc_primary_author} = $scalar_meta{primary_author}
}
# The bibliography may be set in a Meta block in the page or in the .setup file.
# If both are present, the Meta block has precedence.
@@ -579,43 +604,48 @@ sub htmlize ($@) {
my @html = <PANDOC_IN>;
close PANDOC_IN;
waitpid $to_html_pid, 0;
$content = Encode::decode_utf8(join('', @html));
# Reinstate placeholders for inline plugin:
$content =~ s{::INLINE::PLACEHOLDER::(\d+)::}
{<div class="inline" id="$1"></div>}g;
return $content;
}
sub pagetemplate (@) {
my %params = @_;
my $page = $params{page};
my $template = $params{template};
foreach my $k (keys %{$pagestate{$page}{meta}}) {
- next unless $k =~ /^pandoc_/;
+ next unless
+ (grep {/^$k$/} (
+ @scalar_meta_keys, @list_meta_keys,
+ @hash_meta_keys, @list_hash_meta_keys)) ||
+ ($k =~ /^(pandoc_)/);
$template->param($k => $pagestate{$page}{meta}{$k});
}
+ return $template;
}
sub pageactions {
my %args = @_;
my $page = $args{page};
my @links = ();
return unless $pagestate{$page}{pandoc_extra_formats};
my @exts = sort {
$extra_formats{$a}->{order} <=> $extra_formats{$b}->{order}
} keys %{ $pagestate{$page}{pandoc_extra_formats} };
foreach my $ext (@exts) {
my $url = $pagestate{$page}{pandoc_extra_formats}{$ext};
next unless $url;
my $label = $extra_formats{$ext}->{label} || $ext;
push @links, qq[
<a href="$url"
class="extra-format-link"
title="Download $label version of this page"
target="_blank">$label</a>
];
@@ -740,42 +770,49 @@ sub _export_file_path_and_url {
sub compile_string {
# Partially represents an item from the data structure in meta as a string.
my @uncompiled = @_;
return $uncompiled[0] if @uncompiled==1 && !ref($uncompiled[0]);
@uncompiled = @{$uncompiled[0]} if @uncompiled==1 && ref $uncompiled[0] eq 'ARRAY';
my $compiled_string = '';
foreach my $word_or_space (@uncompiled) {
next unless ref $word_or_space eq 'HASH';
my $type = $word_or_space->{'t'} || '';
$compiled_string .= compile_string(@{ $word_or_space->{c} }) if $type eq 'MetaInlines';
next unless $type eq 'Str' || $type eq 'Space' || $type eq 'MetaString';
$compiled_string .= $type eq 'Space' ? ' ' : $word_or_space->{c};
}
return $compiled_string;
}
sub unwrap_c {
# Unwrap pandoc's MetaLists, MetaInlines, etc.
# Finds the deepest-level scalar value for 'c' in the data structure.
# Lists with one element are replaced with the scalar, lists with more
# than one element are returned as an arrayref containing scalars.
+ #
+ # Elements containing hash as keys are unwrapped. That is to
+ # support *MetaList* containing *MetaMap* with keys pointing to
+ # *MetaInlines*. Reference are examples of that structure. (hash unwrap)
+ #
my $container = shift;
if (ref $container eq 'ARRAY' && @$container > 1) {
if (ref $container->[0] eq 'HASH' && $container->[0]->{t} =~ /^(?:Str|Space)$/) {
# handles scalar author fields
return join('', map { compile_string($_) } @$container);
} else {
return [map {unwrap_c($_)} @$container];
}
} elsif (ref $container eq 'ARRAY' && @$container) {
return unwrap_c($container->[0]);
} elsif (ref $container eq 'ARRAY') {
return;
} elsif (ref $container eq 'HASH' && $container->{c}) {
return unwrap_c($container->{c});
+ } elsif (ref $container eq 'HASH' && keys $container->%*) { # (hash unwrap)
+ return {map { $_ => unwrap_c($container->{$_}) } keys $container->%*};
} elsif (ref $container) {
return;
} else {
return $container;
}
}
1;
diff --git a/roles/wiki/files/var/lib/ikiwiki/fripost-wiki.setup b/roles/wiki/files/var/lib/ikiwiki/fripost-wiki.setup
index 4353965..4af3d59 100644
--- a/roles/wiki/files/var/lib/ikiwiki/fripost-wiki.setup
+++ b/roles/wiki/files/var/lib/ikiwiki/fripost-wiki.setup
@@ -14,41 +14,41 @@ adminemail: admin@fripost.org
# users who are wiki admins
adminuser:
- gustaveek
- Grégoire
- moza
# users who are banned from the wiki
banned_users: []
# where the source of the wiki is located
srcdir: /var/lib/ikiwiki/fripost-wiki
# where to build the wiki
destdir: /var/lib/ikiwiki/public_html/fripost-wiki
# base url to the wiki
url: https://wiki.fripost.org
# url to the ikiwiki.cgi
cgiurl: https://wiki.fripost.org/ikiwiki.cgi
# do not adjust cgiurl if CGI is accessed via different URL
reverse_proxy: 0
# filename of cgi wrapper to generate
cgi_wrapper: /var/lib/ikiwiki/public_html/ikiwiki.cgi
# mode for cgi_wrapper (can safely be made suid)
-cgi_wrappermode: 06755
+cgi_wrappermode: 0755
# number of seconds to delay CGI requests when overloaded
cgi_overload_delay: ''
# message to display when overloaded (may contain html)
cgi_overload_message: ''
# enable optimization of only refreshing committed changes?
only_committed_changes: 0
# rcs backend to use
rcs: git
# plugins to add to the default configuration
add_plugins:
- goodstuff
- websetup
- 404
- remove
- attachment
- highlight
- toc
- htmlbalance
- comments
- notifyemail
@@ -399,22 +399,21 @@ getsource_mimetype: text/plain; charset=utf-8
# number of changes to track
#recentchangesnum: 100
# rsync plugin
# command to run to sync updated pages
#rsync_command: rsync -qa --delete . user@host:/path/to/docroot/
# sidebar plugin
# show sidebar page on all pages?
#global_sidebars: 1
# tag plugin
# parent page tags are located under
#tagbase: tag
# autocreate new tag pages?
#tag_autocreate: 1
# commit autocreated tag pages
#tag_autocreate_commit: 1
# pandoc plugin
-pandoc_smart: 1
pandoc_html5: 1