Skip to content

Commit

Permalink
fix: embed link mode loss citation items data
Browse files Browse the repository at this point in the history
  • Loading branch information
windingwind committed Dec 2, 2023
1 parent 85339a0 commit eb5c5d9
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 21 deletions.
48 changes: 46 additions & 2 deletions src/modules/export/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
} from "../../utils/link";
import { getString } from "../../utils/locale";
import { getLinesInNote } from "../../utils/note";
import { formatPath, jointPath } from "../../utils/str";
import { formatPath, jointPath, tryDecodeParse } from "../../utils/str";

export { exportNotes };

Expand Down Expand Up @@ -214,6 +214,8 @@ async function toFreeMind(noteItem: Zotero.Item) {
async function embedLinkedNotes(noteItem: Zotero.Item): Promise<string> {
const parser = ztoolkit.getDOMParser();

const globalCitationData = getNoteCitationData(noteItem as Zotero.Item);

const newLines: string[] = [];
const noteLines = getLinesInNote(noteItem);
for (const i in noteLines) {
Expand All @@ -230,7 +232,49 @@ async function embedLinkedNotes(noteItem: Zotero.Item): Promise<string> {
[linkParam.link, noteItem],
);
newLines.push(html);
const citationData = getNoteCitationData(
linkParam.noteItem as Zotero.Item,
);
globalCitationData.items.push(...citationData.items);
}
}
// Clean up globalCitationItems
const seenCitationItemIDs = [] as string[];
const finalCitationItems = [];
for (const citationItem of globalCitationData.items) {
const currentID = citationItem.uris[0];
if (!(currentID in seenCitationItemIDs)) {
finalCitationItems.push(citationItem);
seenCitationItemIDs.push(currentID);
}
}
return newLines.join("\n");
return `<div data-schema-version="${
globalCitationData.schemaVersion
}" data-citation-items="${encodeURIComponent(
JSON.stringify(finalCitationItems),
)}">${newLines.join("\n")}</div>`;
}

function getNoteCitationData(noteItem: Zotero.Item) {
const parser = new DOMParser();
const doc = parser.parseFromString(noteItem.getNote(), "text/html");
const citationItems = tryDecodeParse(
doc
.querySelector("div[data-citation-items]")
?.getAttribute("data-citation-items") || "[]",
) as unknown as Array<{
uris: string[];
itemData: Record<string, any>;
schemaVersion: string;
}>;

const citationData = {
items: citationItems,
schemaVersion:
doc
.querySelector("div[data-schema-version]")
?.getAttribute("data-schema-version") || "",
};

return citationData;
}
23 changes: 4 additions & 19 deletions src/modules/export/docx.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { showHintWithLink } from "../../utils/hint";
import { renderNoteHTML } from "../../utils/note";
import { randomString } from "../../utils/str";
import { htmlEscape, randomString, tryDecodeParse } from "../../utils/str";
import { waitUtilAsync } from "../../utils/wait";
import { config } from "../../../package.json";

Expand Down Expand Up @@ -76,10 +76,10 @@ function parseDocxCitationFields(html: string) {
}
]
*/
const globalCitationItems = tryParse(
const globalCitationItems = tryDecodeParse(
doc
.querySelector("div[data-citation-items]")
?.getAttribute("data-citation-items") || "{}",
?.getAttribute("data-citation-items") || "[]",
);
const citationElements = Array.from(
doc.querySelectorAll(".citation[data-citation]"),
Expand All @@ -95,7 +95,7 @@ function parseDocxCitationFields(html: string) {
"properties": {}
}
*/
const citation = tryParse(elem.getAttribute("data-citation") || "{}");
const citation = tryDecodeParse(elem.getAttribute("data-citation") || "{}");
const citationItems = [];
for (const citationItem of citation.citationItems) {
const item = globalCitationItems.find(
Expand Down Expand Up @@ -205,21 +205,6 @@ function getCitationID(citationCache: CitationCache) {
return citationID;
}

function tryParse(s: string) {
try {
return JSON.parse(decodeURIComponent(s));
} catch (e) {
return null;
}
}

function htmlEscape(doc: Document, str: string) {
const div = doc.createElement("div");
const text = doc.createTextNode(str);
div.appendChild(text);
return div.innerHTML.replace(/"/g, "&quot;").replace(/'/g, "&#39;");
}

function generateDocxField(fieldCode: string, text: string) {
return `<!--[if supportFields]>
<span style='mso-element:field-begin'></span>
Expand Down
15 changes: 15 additions & 0 deletions src/utils/str.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,18 @@ export function jointPath(...paths: string[]) {
return "";
}
}

export function tryDecodeParse(s: string) {
try {
return JSON.parse(decodeURIComponent(s));
} catch (e) {
return null;
}
}

export function htmlEscape(doc: Document, str: string) {
const div = doc.createElement("div");
const text = doc.createTextNode(str);
div.appendChild(text);
return div.innerHTML.replace(/"/g, "&quot;").replace(/'/g, "&#39;");
}

0 comments on commit eb5c5d9

Please sign in to comment.