Skip to content

Commit

Permalink
Implement #251
Browse files Browse the repository at this point in the history
  • Loading branch information
plk committed Jan 29, 2019
1 parent b54ac2b commit c0083b9
Show file tree
Hide file tree
Showing 11 changed files with 68 additions and 19 deletions.
1 change: 1 addition & 0 deletions data/schemata/bcf.rnc
Expand Up @@ -845,6 +845,7 @@ map =
attribute map_field_set { xsd:string {minLength="1"} }?,
attribute map_entry_null { "1" }?,
attribute map_append { "1" }?,
attribute map_appendstrict { "1" }?,
attribute map_final { "1" }?,
attribute map_match { xsd:string {minLength="1"} }?,
attribute map_matchi { xsd:string {minLength="1"} }?,
Expand Down
5 changes: 5 additions & 0 deletions data/schemata/bcf.rng
Expand Up @@ -2187,6 +2187,11 @@
<value>1</value>
</attribute>
</optional>
<optional>
<attribute name="map_appendstrict">
<value>1</value>
</attribute>
</optional>
<optional>
<attribute name="map_final">
<value>1</value>
Expand Down
1 change: 1 addition & 0 deletions data/schemata/config.rnc
Expand Up @@ -324,6 +324,7 @@ map =
attribute map_field_set { xsd:string {minLength="1"} }?,
attribute map_entry_null { "1" }?,
attribute map_append { "1" }?,
attribute map_appendstrict { "1" }?,
attribute map_final { "1" }?,
attribute map_match { xsd:string {minLength="1"} }?,
attribute map_matchi { xsd:string {minLength="1"} }?,
Expand Down
5 changes: 5 additions & 0 deletions data/schemata/config.rng
Expand Up @@ -1094,6 +1094,11 @@
<value>1</value>
</attribute>
</optional>
<optional>
<attribute name="map_appendstrict">
<value>1</value>
</attribute>
</optional>
<optional>
<attribute name="map_final">
<value>1</value>
Expand Down
8 changes: 5 additions & 3 deletions doc/biber.tex
Expand Up @@ -827,6 +827,7 @@ \subsubsection{The \texttt{sourcemap} option}\label{ref:map}
+\textcolor{blue}{map\_entry\_newtype="\textcolor{red}{newentrykeytype}"}+
+\textcolor{blue}{map\_entry\_entrytarget="\textcolor{red}{newentrykey}"}+
+\textcolor{blue}{map\_append="1"}+
+\textcolor{blue}{map\_appendstrict="1"}+
+\textcolor{blue}{map\_null="1"}+
+\textcolor{blue}{map\_entry\_null="1"}+
+\textcolor{blue}{map\_entry\_clone="\textcolor{red}{clonekey}"}+
Expand Down Expand Up @@ -938,9 +939,10 @@ \subsubsection{The \texttt{sourcemap} option}\label{ref:map}
\textcolor{blue}{\texttt{map\_final}} is also set on this step, then
processing of the parent map stops at this point. If
\textcolor{blue}{\texttt{map\_append}} is set, then the value to set is
appended to the current value of \textcolor{red}{\texttt{set-field}}. The
value to set is specified by a mandatory one and only one of the
following attributes:
appended to the current value of \textcolor{red}{\texttt{set-field}}.
\textcolor{blue}{\texttt{map\_appendstrict}} appends only if the
\textcolor{red}{\texttt{set-field}} is not empty. The value to set is
specified by a mandatory one and only one of the following attributes:
\begin{itemize}
\item \textcolor{blue}{\texttt{map\_field\_value}} --- The
\textcolor{red}{\texttt{set-field}} is set to
Expand Down
16 changes: 10 additions & 6 deletions lib/Biber/Input/file/biblatexml.pm
Expand Up @@ -627,16 +627,20 @@ sub create_entry {
}
}

# If append is set, keep the original value and append the new
my $orig = $step->{map_append} ? $etarget->findvalue($xp_node) : '';
my $orig = '';
# If append or appendstrict is set, keep the original value
# and append the new.
if ($step->{map_append} or $step->{map_appendstrict}) {
$orig = $etarget->findvalue($xp_node) || '';
}

if ($step->{map_origentrytype}) {
next unless $last_type;
if ($logger->is_debug()) {# performance tune
$logger->debug("Source mapping (type=$level, key=$etargetkey): Setting xpath '$xp_node_s' to '${orig}${last_type}'");
}

unless (_changenode($etarget, $xp_node_s, $orig . $last_type, \$cnerror)) {
unless (_changenode($etarget, $xp_node_s, appendstrict_check($step, $orig, $last_type), \$cnerror)) {
biber_warn("Source mapping (type=$level, key=$key): $cnerror");
}
}
Expand All @@ -645,7 +649,7 @@ sub create_entry {
if ($logger->is_debug()) {# performance tune
$logger->debug("Source mapping (type=$level, key=$etargetkey): Setting field xpath '$xp_node_s' to '${orig}${last_fieldval}'");
}
unless (_changenode($etarget, $xp_node_s, $orig . $last_fieldval, \$cnerror)) {
unless (_changenode($etarget, $xp_node_s, appendstrict_check($step, $orig, $last_fieldval), \$cnerror)) {
biber_warn("Source mapping (type=$level, key=$etargetkey): $cnerror");
}
}
Expand All @@ -654,7 +658,7 @@ sub create_entry {
if ($logger->is_debug()) {# performance tune
$logger->debug("Source mapping (type=$level, key=$etargetkey): Setting field xpath '$xp_node_s' to '${orig}${last_field}'");
}
unless (_changenode($etarget, $xp_node_s, $orig . $last_field, \$cnerror)) {
unless (_changenode($etarget, $xp_node_s, appendstrict_check($step, $orig, $last_field), \$cnerror)) {
biber_warn("Source mapping (type=$level, key=$etargetkey): $cnerror");
}
}
Expand All @@ -667,7 +671,7 @@ sub create_entry {
if ($logger->is_debug()) {# performance tune
$logger->debug("Source mapping (type=$level, key=$etargetkey): Setting field xpath '$xp_node_s' to '${orig}${fv}'");
}
unless (_changenode($etarget, $xp_node_s, $orig . $fv, \$cnerror)) {
unless (_changenode($etarget, $xp_node_s, appendstrict_check($step, $orig, $fv), \$cnerror)) {
biber_warn("Source mapping (type=$level, key=$key): $cnerror");
}
}
Expand Down
16 changes: 10 additions & 6 deletions lib/Biber/Input/file/bibtex.pm
Expand Up @@ -708,29 +708,33 @@ sub create_entry {
}
}

# If append is set, keep the original value and append the new
my $orig = $step->{map_append} ? $etarget->get($field) : '';
my $orig = '';
# If append or appendstrict is set, keep the original value
# and append the new.
if ($step->{map_append} or $step->{map_appendstrict}) {
$orig = $etarget->get($field) || '';
}

if ($step->{map_origentrytype}) {
next unless $last_type;
if ($logger->is_debug()) { # performance tune
$logger->debug("Source mapping (type=$level, key=$etargetkey): Setting field '$field' to '${orig}${last_type}'");
}
$etarget->set($field, encode('UTF-8', NFC($orig . $last_type)));
$etarget->set($field, encode('UTF-8', NFC(appendstrict_check($step, $orig,$last_type))));
}
elsif ($step->{map_origfieldval}) {
next unless $last_fieldval;
if ($logger->is_debug()) { # performance tune
$logger->debug("Source mapping (type=$level, key=$etargetkey): Setting field '$field' to '${orig}${last_fieldval}'");
}
$etarget->set($field, encode('UTF-8', NFC($orig . $last_fieldval)));
$etarget->set($field, encode('UTF-8', NFC(appendstrict_check($step, $orig, $last_fieldval))));
}
elsif ($step->{map_origfield}) {
next unless $last_field;
if ($logger->is_debug()) { # performance tune
$logger->debug("Source mapping (type=$level, key=$etargetkey): Setting field '$field' to '${orig}${last_field}'");
}
$etarget->set($field, encode('UTF-8', NFC($orig . $last_field)));
$etarget->set($field, encode('UTF-8', NFC(appendstrict_check($step, $orig, $last_field))));
}
else {
my $fv = maploopreplace($step->{map_field_value}, $maploop);
Expand All @@ -741,7 +745,7 @@ sub create_entry {
if ($logger->is_debug()) { # performance tune
$logger->debug("Source mapping (type=$level, key=$etargetkey): Setting field '$field' to '${orig}${fv}'");
}
$etarget->set($field, encode('UTF-8', NFC($orig . $fv)));
$etarget->set($field, encode('UTF-8', NFC(appendstrict_check($step, $orig, $fv))));
}
}
}
Expand Down
20 changes: 19 additions & 1 deletion lib/Biber/Utils.pm
Expand Up @@ -55,7 +55,7 @@ our @EXPORT = qw{ glob_data_file locate_data_file makenamesid makenameid stringi
bcp472locale rangelen match_indices process_comment map_boolean
parse_range parse_range_alt maploopreplace get_transliterator
call_transliterator normalise_string_bblxml gen_initials join_name_parts
split_xsv date_monthday tzformat expand_option strip_annotation};
split_xsv date_monthday tzformat expand_option strip_annotation appendstrict_check};

=head1 FUNCTIONS
Expand Down Expand Up @@ -1657,6 +1657,24 @@ sub tzformat {
}
}

# Wrapper to enforce map_appendstrict
sub appendstrict_check {
my ($step, $orig, $val) = @_;
# Strict append?
if ($step->{map_appendstrict}) {
if ($orig) {
return $orig . $val;
}
else { # orig is empty, don't append
return '';
}
}
# Normal append, don't care if orig is empty
else {
return $orig . $val;
}
}

1;

__END__
Expand Down
5 changes: 4 additions & 1 deletion t/bibtex-aliases.t
Expand Up @@ -4,7 +4,7 @@ use warnings;
use utf8;
no warnings 'utf8';

use Test::More tests => 24;
use Test::More tests => 25;
use Test::Differences;
unified_diff;

Expand Down Expand Up @@ -92,3 +92,6 @@ is_deeply($bibentries->entry('alias7')->get_field('lista'), ['listaval'], 'Alias
# Testing append overwrites
eq_or_diff($bibentries->entry('alias7')->get_field('verbb'), 'val2val1', 'Alias - 23' );
eq_or_diff($bibentries->entry('alias7')->get_field('verbc'), 'val3val2val1', 'Alias - 24' );

# Testing appendstrict
ok(is_undef($bibentries->entry('alias8')->get_field('verbc')), 'Alias - 25' );
3 changes: 2 additions & 1 deletion t/tdata/bibtex-aliases.bcf
Expand Up @@ -551,7 +551,7 @@
<bcf:map_step map_field_set="VERBB" map_origfieldval="1"
map_append="1"/>
<bcf:map_step map_field_source="VERBB" map_final="1"/>
<bcf:map_step map_field_set="VERBC" map_origfieldval="1" map_append="1"/>
<bcf:map_step map_field_set="VERBC" map_origfieldval="1" map_appendstrict="1"/>
</bcf:map>
<bcf:map>
<bcf:map_step map_field_source="LISTB" map_match="\A(\S{2})" map_replace="REP$1CED"/>
Expand Down Expand Up @@ -1936,6 +1936,7 @@
<bcf:citekey order="5">alias5</bcf:citekey>
<bcf:citekey order="6">alias6</bcf:citekey>
<bcf:citekey order="7">alias7</bcf:citekey>
<bcf:citekey order="8">alias8</bcf:citekey>
</bcf:section>
<!-- SORTING SCHEME -->
<bcf:sortingtemplate name="nty">
Expand Down
7 changes: 6 additions & 1 deletion t/tdata/bibtex-aliases.bib
Expand Up @@ -55,5 +55,10 @@ @REPORT{alias7
LISTA = {listaval},
VERBA = {val1},
VERBB = {val2},
VERBC = {val3},
VERBC = {val3}
}

@REPORT{alias8,
VERBA = {val2},
VERBB = {val2}
}

0 comments on commit c0083b9

Please sign in to comment.