Juris-M / citeproc-js

A JavaScript implementation of the Citation Style Language (CSL) https://citeproc-js.readthedocs.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Italics aren't applied for second instance in field if "and" is present

dstillman opened this issue · comments

Weird one!

https://forums.zotero.org/discussion/comment/363829/#Comment_363829

Testing with chicago-author-date

Placing this in the Volume field of an empty item results in FooBar an Baz in italics:

<i>Foo</i><i>Bar an Baz</i>

Title. Vol. Foo**Bar an Baz.

But if "and" is present in the second string, the second string isn't italicized:

<i>Foo</i><i>Bar and Baz</i>

Title. 2023. Vol. Foo<i>Bar and Baz</i>.

Reproducible with this fixture where the CSL style is simplified.

I also test the content in fields title, edition, and page other than volume and it seems this bug only happens in number fields. I suspect it's related to citeproc-js parsing embedded locators in number fields (see test-suite/processor-tests/humans/number_OrdinalSpacing.txt).

BTW, since volume-title is available now, perhaps we can solve the original problem with it?

Number fields are split here:

// Split chunks and collate delimiters.
var elems = [];
var m = mystr.match(jmrex);
if (m) {
var lst = mystr.split(jsrex);
for (var i=0, ilen=m.length; i<ilen; i++) {
if (m[i].match(andRex)) {
if (lst[i].match(/[a-zA-Z]$/) && lst[i].match(/^[a-zA-Z]/)) {
m[i] = localeAmpersand;
} else {
m[i] = " " + localeAmpersand + " ";
}
}
}
var recombine = false;
for (var i in lst) {
if (("" + lst[i]).replace(/^[a-z]\.\s+/, "").match(/[^\s0-9ivxlcmIVXLCM]/)) {
//recombine = true;
break;
}
}
if (recombine) {
elems = [mystr];
} else {
for (var i=0,ilen=lst.length-1; i<ilen; i++) {
elems.push(lst[i]);
elems.push(m[i]);
}
elems.push(lst[lst.length-1]);
//print("ELEMS: "+elems);
elems = fixupSubsections(elems);
//print(" fixup: "+elems);
}
} else {
var elems = [mystr];
}

They're then appended to the output queue here:

state.output.append(num.particle + num.value, numStyling);

This then applies the formatting here:

this.state.fun.flipflopper.processTags(blob);

Since the parts are still being processed separately the "stray" tags are "neutralized", here:

// Stray tags are neutralized here
for (var i=_nestingState.length-1;i>-1;i--) {
var tagPos = _nestingState[i].pos;
var tag = doppel.tags[tagPos];
if (tag === " \'" || tag === "\'") {
doppel.strings[tagPos+1] = " \u2019" + doppel.strings[tagPos+1];
} else {
doppel.strings[tagPos+1] = doppel.tags[tagPos] + doppel.strings[tagPos+1];
}
doppel.tags[tagPos] = "";
_nestingState.pop();
}
for (var i=doppel.tags.length-1;i>-1;i--) {
if (!doppel.tags[i]) {
doppel.tags = doppel.tags.slice(0,i).concat(doppel.tags.slice(i+1));
doppel.strings[i] = doppel.strings[i] + doppel.strings[i+1];
doppel.strings = doppel.strings.slice(0,i+1).concat(doppel.strings.slice(i+2));
}
}