Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor to use paragraph formatters #43

Merged
merged 6 commits into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @kkartch0
21 changes: 21 additions & 0 deletions src/models/ParagraphFormatter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { GospelStudyPluginSettings } from "./GospelStudyPluginSettings";

/**
* Represents a paragraph formatter.
*/
export interface ParagraphFormatter {

/**
* Determines if the formatter is enabled based on the settings.
* @param settings - The plugin settings.
* @returns A boolean indicating if the formatter is enabled.
*/
isEnabled(settings: GospelStudyPluginSettings): boolean;

/**
* Formats the paragraph.
* @param paragraph - The paragraph to be formatted.
* @returns The formatted paragraph.
*/
format(paragraph: string): string;
}
127 changes: 0 additions & 127 deletions src/paragraphFormatting.ts

This file was deleted.

24 changes: 24 additions & 0 deletions src/paragraphFormatting/fullyQualifyStudyLinksFormatter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { ParagraphFormatter } from "src/models/ParagraphFormatter";

/**
* Replaces all occurrences of "/study/" in the given text with "https://www.churchofjesuschrist.org/study/".
*
* @param text - The input text to be processed.
* @returns The modified text with fully qualified study links.
* @example
* const inputText = "This is a paragraph with <a href='/study/scriptures/bofm/1-ne/1.1'>study link</a> and <a href='/study/scriptures/bofm/1-ne/2.1'>another study link</a>.";
* const modifiedText = fullyQualifyStudyLinks(inputText);
* console.log(modifiedText);
* // Output: "This is a paragraph with <a href='https://www.churchofjesuschrist.org/study/scriptures/bofm/1-ne/1.1'>study link</a> and <a href='https://www.churchofjesuschrist.org/study/scriptures/bofm/1-ne/2.1'>another study link</a>."
*/
export const fullyQualifyStudyLinksFormatter: ParagraphFormatter = {
isEnabled(): boolean {
return true;
},

format(paragraph: string): string {
return paragraph.replace(/"\/study\//g, "\"https://www.churchofjesuschrist.org/study/");
}
};

export default fullyQualifyStudyLinksFormatter;
44 changes: 44 additions & 0 deletions src/paragraphFormatting/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { ParagraphFormatter } from "src/models/ParagraphFormatter";
import { GospelStudyPluginSettings } from "src/models/GospelStudyPluginSettings";
import { registeredFormatters } from "./registeredFormatters";
/**
* Retrieves the paragraphs with the specified ids from the document, formats, and then returns them.
*
* @param document - The document object representing the HTML document.
* @param paragraphIds - An array of active paragraph IDs.
* @returns An array of formatted paragraphs.
*/
export function getFormattedParagraphs(document: Document, paragraphIds: string[], pluginSettings: GospelStudyPluginSettings): string[] {
const paragraphs: string[] = [];
const enabledFormatters = registeredFormatters.filter((formatter: ParagraphFormatter) => formatter.isEnabled(pluginSettings));

paragraphIds.forEach((id) => {
if (id === "-") { // Hyphen indicates that the next paragraph is not contiguous with the previous one, so we add an ellipsis.
paragraphs.push("…");
return;
}
const paragraphElement = document.getElementById(id);
if (!paragraphElement) return;

const formattedParagraph = formatParagraph(paragraphElement.innerHTML, enabledFormatters);

paragraphs.push(formattedParagraph);
});
return paragraphs;
}


/**
* Formats a paragraph by applying various transformations based on the plugin settings.
*
* @param paragraph- The HTML content of the paragraph.
* @param pluginSettings - The settings of the Gospel Study plugin.
* @returns The formatted paragraph HTML.
*/
export function formatParagraph(paragraph: string, enabledFormatters: ParagraphFormatter[]): string {
enabledFormatters.forEach((formatter) => {
paragraph = formatter.format(paragraph);
});

return paragraph;
}
24 changes: 24 additions & 0 deletions src/paragraphFormatting/registeredFormatters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { ParagraphFormatter } from "src/models/ParagraphFormatter";
import fs from 'fs';

export let registeredFormatters: ParagraphFormatter[] = [];

/**
* Imports all formatters (i.e. files that end with "Formatter.ts") and assigns them to registeredFormatters.
*
* @param pluginSettings - The settings of the Gospel Study plugin.
* @returns An array of enabled formatters.
*/
async function loadInAllFormatters() {
const files = fs.readdirSync('src/paragraphFormatting');
const formatterPromises = files.filter(file => file.endsWith('Formatter.ts')).map(async file => {
const module = await import(`./${file}`);
const formatter = module.default as ParagraphFormatter;
return formatter;
});

registeredFormatters = await Promise.all(formatterPromises);
}


loadInAllFormatters();
30 changes: 30 additions & 0 deletions src/paragraphFormatting/remoteFootnotesFormatter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { ParagraphFormatter } from "src/models/ParagraphFormatter";

/**
* Removes footnotes from a paragraph of text.
*
* @param text - The input text containing footnotes.
* @returns The modified text with footnotes removed.
*
* @example
* const inputText = "This is a paragraph with a <a class='study-note-ref' href='#note1'><sup class='marker'>1</sup>footnote</a>."
* const modifiedText = removeFootnotesFromParagraph(inputText);
* console.log(modifiedText);
* // Output: "This is a paragraph with a footnote."
*/
export const footnotesFormatter: ParagraphFormatter = {
isEnabled(): boolean {
return true;
},

format(paragraph: string) {
paragraph = paragraph.replace(
/<a class="study-note-ref" href="[^>]*"><sup class="marker">[^<]*<\/sup>([^<]*)<\/a>/g,
"$1"
);

return paragraph;
}
}

export default footnotesFormatter;
31 changes: 31 additions & 0 deletions src/paragraphFormatting/removeNonUsefulTagsFormatter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { ParagraphFormatter } from "src/models/ParagraphFormatter";

/**
* Removes tags that are not useful/functional in the Obsidian context such as associated content, page breaks, and note references.
*
* @param text - The input text containing HTML tags.
* @returns The modified text with non-useful tags removed.
*/
export const removeNonUsefulTagsFormatter: ParagraphFormatter = {
isEnabled(): boolean {
return true;
},

format(paragraph: string): string {
const parser = new DOMParser();
const doc = parser.parseFromString(paragraph, 'text/html');

const tagsToRemove = ['span.page-break', 'span[title="Associated Content"]', 'a.note-ref'];

tagsToRemove.forEach((tag) => {
const elements = doc.querySelectorAll(tag);
elements.forEach((element) => {
element.remove();
});
});

return doc.body.innerHTML;
}
};

export default removeNonUsefulTagsFormatter;
35 changes: 35 additions & 0 deletions src/paragraphFormatting/removeScriptureReferenceLinksFormatter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { GospelStudyPluginSettings } from "src/models/GospelStudyPluginSettings";
import { ParagraphFormatter } from "src/models/ParagraphFormatter";

/**
* Removes scripture reference links (e.g. <a class="scripture-ref">Some Reference</a>) from the given paragraph by replacing them with their text content.
*
* @param paragraphHTML - The HTML string representing the paragraph.
* @returns The modified paragraph HTML with scripture reference links removed.
* @example
* const inputText = "This is a paragraph with a <a class='scripture-ref'>scripture reference</a>."
* const modifiedText = removeScriptureReferenceLinks(inputText);
* console.log(modifiedText);
* // Output: "This is a paragraph with a scripture reference."
*/
export const removeScriptureReferenceLinksFormatter: ParagraphFormatter = {
isEnabled(settings: GospelStudyPluginSettings): boolean {
return !settings.retainScriptureReferenceLinks;
},

format(paragraph: string): string {

const parser = new DOMParser();
const doc = parser.parseFromString(paragraph, 'text/html');

const referenceLinks = doc.querySelectorAll('a.scripture-ref');
referenceLinks.forEach((element): void => {
// Replace the scripture reference link with the text content of the link.
element.replaceWith(element.textContent || '');
});
paragraph = doc.body.innerHTML;
return paragraph;
}
}

export default removeScriptureReferenceLinksFormatter;
Loading
Loading