Add CSL 1.0.2 locators and switch to CSL locales for localization

And move Page to middle of list, while still selecting by default

https://forums.zotero.org/discussion/comment/396602/#Comment_396602
This commit is contained in:
Dan Stillman 2022-07-09 01:00:07 -04:00
parent fea99bf8f8
commit 387e4dd958
7 changed files with 129 additions and 31 deletions

View file

@ -48,7 +48,7 @@ function AnnotationBox({ data }) {
<div className="title">{Zotero.getString('itemTypes.annotation')}</div>
<div className="container">
<div className="header">
<div>{Zotero.getString('citation.locator.page')} {data.pageLabel}</div>
<div>{Zotero.Cite.getLocatorString('page')} {data.pageLabel}</div>
</div>
{data.text !== undefined
? <div className="text" style={textStyle}>{data.text}</div>

View file

@ -113,9 +113,10 @@ var Zotero_Citation_Dialog = new function () {
var menu = document.getElementById("label");
var label_list = document.getElementById("locator-type-popup");
var i = 0;
var pageLocatorIndex;
for(var value in locators) {
var locator = locators[value];
var locatorLabel = Zotero.getString('citation.locator.'+locator.replace(/\s/g,''));
let locatorLabel = Zotero.Cite.getLocatorString(locator);
// add to list of labels
var child = document.createXULElement("menuitem");
child.setAttribute("value", value);
@ -124,9 +125,12 @@ var Zotero_Citation_Dialog = new function () {
// add to array
_locatorIndexArray[locator] = i;
_locatorNameArray[i] = locator;
if (locator == 'page') {
pageLocatorIndex = i;
}
i++;
}
menu.selectedIndex = 0;
menu.selectedIndex = pageLocatorIndex;
// load (from selectItemsDialog.js)
yield doLoad();

View file

@ -116,10 +116,9 @@ var Zotero_QuickFormat = new function () {
// add labels to popup
var locators = Zotero.Cite.labels;
var menu = document.getElementById("locator-label");
var labelList = document.getElementById("locator-label-popup");
for(var locator of locators) {
var locatorLabel = Zotero.getString('citation.locator.'+locator.replace(/\s/g,''));
let locatorLabel = Zotero.Cite.getLocatorString(locator);
// add to list of labels
var child = document.createXULElement("menuitem");
@ -127,7 +126,6 @@ var Zotero_QuickFormat = new function () {
child.setAttribute("label", locatorLabel);
labelList.appendChild(child);
}
menu.selectedIndex = 0;
}
@ -1090,15 +1088,16 @@ var Zotero_QuickFormat = new function () {
let citationItem = JSON.parse(target.dataset.citationItem);
panelPrefix.value = citationItem["prefix"] ? citationItem["prefix"] : "";
panelSuffix.value = citationItem["suffix"] ? citationItem["suffix"] : "";
var pageOption = panelLocatorLabel.getElementsByAttribute("value", "page")[0];
if(citationItem["label"]) {
var option = panelLocatorLabel.getElementsByAttribute("value", citationItem["label"]);
if(option.length) {
panelLocatorLabel.selectedItem = option[0];
} else {
panelLocatorLabel.selectedIndex = 0;
panelLocatorLabel.selectedItem = pageOption;
}
} else {
panelLocatorLabel.selectedIndex = 0;
panelLocatorLabel.selectedItem = pageOption;
}
panelLocator.value = citationItem["locator"] ? citationItem["locator"] : "";
panelSuppressAuthor.checked = !!citationItem["suppress-author"];

View file

@ -56,10 +56,8 @@ var Zotero_CSL_Editor = new function() {
var pageList = document.getElementById('zotero-csl-page-type');
var locators = Zotero.Cite.labels;
for (let type of locators) {
var locator = type;
locator = Zotero.getString('citation.locator.'+locator.replace(/\s/g,''));
pageList.appendItem(locator, type);
for (let locator of locators) {
pageList.appendItem(Zotero.Cite.getLocatorString(locator), locator);
}
pageList.selectedIndex = 0;

View file

@ -8,9 +8,105 @@ Zotero.Cite = {
/**
* Locator labels
*/
"labels":["page", "book", "chapter", "column", "figure", "folio",
"issue", "line", "note", "opus", "paragraph", "part", "section", "sub verbo",
"volume", "verse"],
"labels": [
"act",
"appendix",
"article-locator",
"book",
"canon",
"chapter",
"column",
"elocation",
"equation",
"figure",
"folio",
"issue",
"line",
"note",
"opus",
"page",
"paragraph",
"part",
"rule",
"scene",
"section",
"sub-verbo",
"table",
//"timestamp",
"title-locator",
"verse",
"volume"
],
_locatorStrings: new Map(),
/**
* Get localized string for locator
*
* @param {String} locator - Locator name (e.g., 'book')
* @return {String} - Localized string (e.g., 'Livre')
*/
getLocatorString: function (locator) {
// Get the best CSL locale for the current Zotero locale
var cslLocale = Zotero.Utilities.Internal.resolveLocale(
Zotero.locale,
Object.keys(Zotero.Styles.locales)
);
// If locator strings are already cached for the current locale, use that
if (this._locatorStrings.has(cslLocale)) {
return this._locatorStrings.get(cslLocale).get(locator);
}
var map = new Map();
this._locatorStrings.set(cslLocale, map);
var localeXML = Zotero.Cite.Locale.get(cslLocale);
var parser;
if (Zotero.platformMajorVersion > 60) {
parser = new DOMParser();
}
else {
parser = Components.classes["@mozilla.org/xmlextras/domparser;1"]
.createInstance(Components.interfaces.nsIDOMParser);
}
var doc = parser.parseFromString(localeXML, 'text/xml');
var englishDoc;
// Cache all locators for the current locale
for (let locator of this.labels) {
let elem = doc.querySelector(`term[name="${locator}"]:not([form="short"]) > single`);
if (!elem) {
// If locator not found, get from the U.S. English locale
if (cslLocale != 'en-US') {
Zotero.logError(`Locator '${locator}' not found in ${cslLocale} locale -- trying en-US`);
if (!englishDoc) {
englishDoc = parser.parseFromString(Zotero.Cite.Locale.get('en-US'), 'text/xml');
}
elem = englishDoc.querySelector(`term[name="${locator}"]:not([form="short"]) > single`);
if (!elem) {
Zotero.logError(`Locator '${locator}' not found in en-US locale -- using name`);
}
}
else {
Zotero.logError(`Locator '${locator}' not found in en-US locale -- using name`);
}
// If still not found, use the locator name directly
if (!elem) {
map.set(locator, Zotero.Utilities.capitalize(locator));
continue;
}
}
// If <single> is empty, use the locator name directly
let str = elem.textContent;
if (!str) {
Zotero.logError(`Locator '${locator}' is empty in ${cslLocale} locale -- using name`);
map.set(locator, Zotero.Utilities.capitalize(locator));
continue;
}
map.set(locator, Zotero.Utilities.capitalize(str));
}
return map.get(locator);
},
/**
* Remove specified item IDs in-place from a citeproc-js bibliography object returned

View file

@ -861,22 +861,6 @@ citation.showEditor = Show Editor…
citation.hideEditor = Hide Editor…
citation.citations = Citations
citation.notes = Notes
citation.locator.page = Page
citation.locator.book = Book
citation.locator.chapter = Chapter
citation.locator.column = Column
citation.locator.figure = Figure
citation.locator.folio = Folio
citation.locator.issue = Issue
citation.locator.line = Line
citation.locator.note = Note
citation.locator.opus = Opus
citation.locator.paragraph = Paragraph
citation.locator.part = Part
citation.locator.section = Section
citation.locator.subverbo = Sub verbo
citation.locator.volume = Volume
citation.locator.verse = Verse
report.title.default = Zotero Report
report.parentItem = Parent Item:

View file

@ -1,4 +1,21 @@
describe("Zotero.Cite", function () {
describe("#getLocatorString()", function () {
it("should get 'book' in en-US", function () {
Zotero.locale = 'en-US';
assert.equal(Zotero.Cite.getLocatorString('book'), 'Book');
});
it("should get 'sub-verbo' in en-US", function () {
Zotero.locale = 'en-US';
assert.equal(Zotero.Cite.getLocatorString('sub-verbo'), 'Sub verbo');
});
it("should get 'book' in fr-FR", function () {
Zotero.locale = 'fr-FR';
assert.equal(Zotero.Cite.getLocatorString('book'), 'Livre');
});
});
describe("#extraToCSL()", function () {
it("should convert Extra field values to the more restrictive citeproc-js cheater syntax", function () {
var str1 = 'Original Date: 2017\n' // uppercase/spaces converted to lowercase/hyphens