Notepad/enter/.obsidian/plugins/obsidian-extract-pdf-annota.../main.js

355 lines
12 KiB
JavaScript

/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
*/
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
var __export = (target, all) => {
__markAsModule(target);
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
var __async = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
// main.ts
__export(exports, {
default: () => PDFAnnotationPlugin
});
var import_obsidian = __toModule(require("obsidian"));
// extractHighlight.ts
var SUPPORTED_ANNOTS = ["Text", "Highlight", "Underline"];
function searchQuad(minx, maxx, miny, maxy, items) {
const mycontent = items.reduce(function(txt, x) {
if (x.width == 0)
return txt;
if (!(miny <= x.transform[5] && x.transform[5] <= maxy))
return txt;
if (x.transform[4] + x.width < minx)
return txt;
if (x.transform[4] > maxx)
return txt;
const start = x.transform[4] >= minx ? 0 : Math.floor(x.str.length * (minx - x.transform[4]) / x.width);
if (x.transform[4] + x.width <= maxx) {
return txt + x.str.substr(start);
} else {
const lenc = Math.floor(x.str.length * (maxx - x.transform[4]) / x.width) - start;
return txt + x.str.substr(start, lenc);
}
}, "");
return mycontent.trim();
}
function extractHighlight(annot, items) {
const highlight = annot.quadPoints.reduce((txt, quad) => {
const minx = quad.reduce((prev, curr) => Math.min(prev, curr.x), quad[0].x);
const maxx = quad.reduce((prev, curr) => Math.max(prev, curr.x), quad[0].x);
const miny = quad.reduce((prev, curr) => Math.min(prev, curr.y), quad[0].y);
const maxy = quad.reduce((prev, curr) => Math.max(prev, curr.y), quad[0].y);
const res = searchQuad(minx, maxx, miny, maxy, items);
if (txt.substring(txt.length - 1) != "-") {
return txt + " " + res;
} else if (txt.substring(txt.length - 2).toLowerCase() == txt.substring(txt.length - 2) && res.substring(0, 1).toLowerCase() == res.substring(0, 1)) {
return txt.substring(0, txt.length - 1) + res;
} else {
return txt + res;
}
}, "");
return highlight;
}
function loadPage(page, pagenum, file, containingFolder, total) {
return __async(this, null, function* () {
let annotations = yield page.getAnnotations();
annotations = annotations.filter(function(anno) {
return SUPPORTED_ANNOTS.indexOf(anno.subtype) >= 0;
});
const content = yield page.getTextContent({ normalizeWhitespace: true });
content.items.sort(function(a1, a2) {
if (a1.transform[5] > a2.transform[5])
return -1;
if (a1.transform[5] < a2.transform[5])
return 1;
if (a1.transform[4] > a2.transform[4])
return 1;
if (a1.transform[4] < a2.transform[4])
return -1;
return 0;
});
annotations.map(function(anno) {
return __async(this, null, function* () {
if (anno.subtype == "Highlight" || anno.subtype == "Underline") {
anno.highlightedText = extractHighlight(anno, content.items);
}
anno.folder = containingFolder;
anno.file = file;
anno.filepath = file.path;
anno.pageNumber = pagenum;
anno.author = anno.titleObj.str;
anno.body = anno.contentsObj.str;
total.push(anno);
});
});
});
}
function loadPDFFile(file, pdfjsLib, containingFolder, total) {
return __async(this, null, function* () {
const content = yield this.app.vault.readBinary(file);
const pdf = yield pdfjsLib.getDocument(content).promise;
for (let i = 1; i <= pdf.numPages; i++) {
const page = yield pdf.getPage(i);
yield loadPage(page, i, file, containingFolder, total);
}
});
}
// main.ts
function template(strings, ...keys) {
return function(...values) {
const dict = values[values.length - 1] || {};
const result = [strings[0]];
keys.forEach(function(key, i) {
const value = Number.isInteger(key) ? values[key] : dict[key];
result.push(value, strings[i + 1]);
});
return result.join("");
};
}
var highlighted = template`> ${"highlightedText"}
${"body"}
* *highlighted by ${"author"} at page ${"pageNumber"} on [[${"filepath"}]]*
`;
var note = template`${"body"}
* *noted by ${"author"} at page ${"pageNumber"} on [[${"filepath"}]]*
`;
var PDFAnnotationPlugin = class extends import_obsidian.Plugin {
sort(grandtotal) {
const settings = this.settings;
if (settings.sortByTopic) {
grandtotal.forEach((anno) => {
const lines = anno.body.split(/\r\n|\n\r|\n|\r/);
anno.topic = lines[0];
anno.body = lines.slice(1).join("\r\n");
});
}
grandtotal.sort(function(a1, a2) {
if (settings.sortByTopic) {
if (a1.topic > a2.topic)
return 1;
if (a1.topic < a2.topic)
return -1;
}
if (settings.useFolderNames) {
if (a1.folder > a2.folder)
return 1;
if (a1.folder < a2.folder)
return -1;
}
if (a1.file.name > a2.file.name)
return 1;
if (a1.file.name < a2.file.name)
return -1;
if (a1.pageNumber > a2.pageNumber)
return 1;
if (a1.pageNumber < a2.pageNumber)
return -1;
if (a1.rect[1] > a2.rect[1])
return -1;
if (a1.rect[1] < a2.rect[1])
return 1;
return 0;
});
}
format(grandtotal) {
let text = "";
let topic = "";
let currentFolder = "";
grandtotal.forEach((a) => {
if (this.settings.sortByTopic) {
if (topic != a.topic) {
topic = a.topic;
currentFolder = "";
text += `# ${topic}
`;
}
}
if (this.settings.useFolderNames) {
if (currentFolder != a.folder) {
currentFolder = a.folder;
text += `## ${currentFolder}
`;
}
} else {
if (currentFolder != a.file.name) {
currentFolder = a.file.name;
text += `## ${currentFolder}
`;
}
}
if (a.subtype == "Text") {
text += note(a);
} else {
text += highlighted(a);
}
});
if (grandtotal.length == 0)
return "*No Annotations*";
else
return text;
}
loadSinglePDFFile(file) {
return __async(this, null, function* () {
const pdfjsLib = yield (0, import_obsidian.loadPdfJs)();
const containingFolder = file.parent.name;
const grandtotal = [];
console.log("loading from file ", file);
yield loadPDFFile(file, pdfjsLib, containingFolder, grandtotal);
this.sort(grandtotal);
const finalMarkdown = this.format(grandtotal);
let filePath = file.name.replace(".pdf", ".md");
filePath = "Annotations for " + filePath;
yield this.saveHighlightsToFile(filePath, finalMarkdown);
yield this.app.workspace.openLinkText(filePath, "", true);
});
}
onload() {
return __async(this, null, function* () {
this.loadSettings();
this.addSettingTab(new PDFAnnotationPluginSettingTab(this.app, this));
this.addCommand({
id: "extract-annotations-single",
name: "Extract PDF Annotations on single file",
checkCallback: (checking) => {
const file = this.app.workspace.getActiveFile();
if (file != null && file.extension === "pdf") {
if (!checking) {
this.loadSinglePDFFile(file);
}
return true;
} else {
return false;
}
}
});
this.addCommand({
id: "extract-annotations",
name: "Extract PDF Annotations",
editorCallback: (editor, view) => __async(this, null, function* () {
const file = this.app.workspace.getActiveFile();
if (file == null)
return;
const folder = file.parent;
const grandtotal = [];
const pdfjsLib = yield (0, import_obsidian.loadPdfJs)();
editor.replaceSelection("Extracting PDF Comments from " + folder.name + "\n");
const promises = [];
import_obsidian.Vault.recurseChildren(folder, (file2) => __async(this, null, function* () {
if (file2 instanceof import_obsidian.TFile) {
if (file2.extension === "pdf") {
promises.push(loadPDFFile(file2, pdfjsLib, file2.parent.name, grandtotal));
}
}
}));
yield Promise.all(promises);
this.sort(grandtotal);
editor.replaceSelection(this.format(grandtotal));
})
});
});
}
loadSettings() {
this.settings = new PDFAnnotationPluginSetting();
(() => __async(this, null, function* () {
const loadedSettings = yield this.loadData();
if (loadedSettings) {
this.settings.useFolderNames = loadedSettings.useFolderNames;
this.settings.sortByTopic = loadedSettings.sortByTopic;
}
}))();
}
onunload() {
}
saveHighlightsToFile(filePath, mdString) {
return __async(this, null, function* () {
const fileExists = yield this.app.vault.adapter.exists(filePath);
if (fileExists) {
yield this.appendHighlightsToFile(filePath, mdString);
} else {
yield this.app.vault.create(filePath, mdString);
}
});
}
appendHighlightsToFile(filePath, note2) {
return __async(this, null, function* () {
let existingContent = yield this.app.vault.adapter.read(filePath);
if (existingContent.length > 0) {
existingContent = existingContent + "\r\r";
}
yield this.app.vault.adapter.write(filePath, existingContent + note2);
});
}
};
var PDFAnnotationPluginSetting = class {
constructor() {
this.useFolderNames = true;
this.sortByTopic = true;
}
};
var PDFAnnotationPluginSettingTab = class extends import_obsidian.PluginSettingTab {
constructor(app, plugin) {
super(app, plugin);
this.plugin = plugin;
}
display() {
const { containerEl } = this;
containerEl.empty();
new import_obsidian.Setting(containerEl).setName("Use Folder Name").setDesc("If enabled, uses the PDF's folder name (instead of the PDF-Filename) for sorting").addToggle((toggle) => toggle.setValue(this.plugin.settings.useFolderNames).onChange((value) => {
this.plugin.settings.useFolderNames = value;
this.plugin.saveData(this.plugin.settings);
}));
new import_obsidian.Setting(containerEl).setName("Sort by Topic").setDesc("If enabled, uses the notes first line as Topic for primary sorting").addToggle((toggle) => toggle.setValue(this.plugin.settings.sortByTopic).onChange((value) => {
this.plugin.settings.sortByTopic = value;
this.plugin.saveData(this.plugin.settings);
}));
}
};