Skip to content

Instantly share code, notes, and snippets.

@uroybd
Last active October 5, 2023 03:27
Show Gist options
  • Save uroybd/cbfce7135b8efa61964f89234e52f39d to your computer and use it in GitHub Desktop.
Save uroybd/cbfce7135b8efa61964f89234e52f39d to your computer and use it in GitHub Desktop.
Obsidian Boox Highlight formatter
<%*
// Note style prefixes we will map to callouts.
// It will suffice to put just this character to change the callout style.
// If additional notes are required, we will use a space after the prefix,
// and then continue to our usual note.
// Customize this as you see fit. With types from: https://help.obsidian.md/Editing+and+formatting/Callouts#Supported+types
const NOTE_STYLES = {
"!": {
type: "important",
title: "Striking/Intense",
},
"@": {
type: "danger",
title: "In Discord",
},
"?": {
type: "question",
title: "Thought Provoking",
},
}
const NOTE_STYLE_KEYS = Object.keys(NOTE_STYLES);
// Default note style, if any prefix is not present.
const DEFAULT_NOTE_STYLE = {
type: "quote",
title: "Quotable/Concept/General Idea"
}
function parseNoteFormat(note) {
let data = {...DEFAULT_NOTE_STYLE, note};
for (let i = 0; i < NOTE_STYLE_KEYS.length; i++) {
let key = NOTE_STYLE_KEYS[i];
if (note.startsWith(key)) {
data = {...NOTE_STYLES[key], note: note.substr(key.length + 1)};
break;
}
}
return data
}
function getTitleAndAuthor(l) {
l = l.replace("Reading Notes | <<", "").split(">>");
return {
title: l[0],
authors: l[1]
}
}
function parseNote(note) {
let lines = note.split("\n");
lines.reverse();
let content = {
section: "",
timestamp: "",
page: "",
highlight: "",
note: "",
continued: false
}
for (let i = 0; i < lines.length; i++) {
let l = lines[i];
if (l.includes("【Note】")) {
const noteContent = l.replace('【Note】', "");
if (noteContent.startsWith(">")) {
content.note = {...DEFAULT_NOTE_STYLE,
note: noteContent.substr(2)
}
content.continued = true;
} else {
content.note = parseNoteFormat(noteContent);
}
} else if (l.includes("  |  Page No.: ")) {
let meta = l.split("  |  Page No.: ");
content.timestamp = window.moment(meta[0]).format("DD MMM YYYY hh:mm:ss A")
content.page = meta[1]
} else if (i == lines.length - 1) {
content.section = l;
} else {
content.highlight = content.highlight ? `${l}\n${content.highlight}` : l;
}
}
if (!content.note) {
content.note = {...DEFAULT_NOTE_STYLE, note: ""}
}
return content
}
function format_percentages(page, total) {
if (page && total) {
return `${((page / total) * 100).toFixed(2)}%`;
}
return "";
}
let file = app.workspace.getActiveFile()
const content = await tp.system.prompt("Paste the JSON content", null, true, true);
let total_pages = await tp.system.prompt("Number of total pages");
total_pages = parseInt(total_pages);
let lines = content.split("\n");
let titleAndAuthor = getTitleAndAuthor(lines.shift())
const notes = (lines.join("\n") + "\n").split("-------------------\n").map(n => {
let v = n.trim("\n");
if (v.length) {
return parseNote(v);
}
return null;
}).filter(n => n !== null);
let output = `# ${titleAndAuthor.title}\n##### ${titleAndAuthor.authors}\n\n`;
let currentSection = null;
let prevNoteHeader = null;
for (let i = 0; i < notes.length; i++) {
let noteData = notes[i]
if (!noteData.continued) {
if (noteData.section && (currentSection != noteData.section)) {
output += `## ${noteData.section}\n`;
currentSection = noteData.section;
}
let noteHeader = `Page: ${noteData.page} (${format_percentages(noteData.page, total_pages)}) @ ${noteData.timestamp}\n`;
if (prevNoteHeader && prevNoteHeader.split(" / ")[0] == noteHeader) {
noteHeader += " / " + ((parseInt(prevNoteHeader.split(" /")[1]) || 1) + 1)
}
prevNoteHeader = noteHeader
let highlight = noteData.highlight;
for (let j = i + 1; j < notes.length; j++) {
if (!notes[j].continued) {
break;
}
highlight += " " + notes[j].highlight;
}
output += `### ${noteHeader}\n${highlight}\n\n`;
output += `> [!${noteData.note.type}] ${noteData.note.title}`;
if (noteData.note.note) {
if (noteData.note.note.length > 50) {
output += `\n> ${noteData.note.note}`
} else {
output += `: ${noteData.note.note}`;
}
output += "\n";
}
output += "\n\n"
}
}
await app.vault.modify(file, output)
%>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment