mirror of
https://github.com/gosticks/flashcards-obsidian.git
synced 2025-10-16 12:05:33 +00:00
Add eslint and apply quick fixes
This commit is contained in:
parent
1940e78eda
commit
81a15ade41
20
.eslintrc.json
Normal file
20
.eslintrc.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es2021": true
|
||||
},
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended"
|
||||
],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 13,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"plugins": [
|
||||
"@typescript-eslint"
|
||||
],
|
||||
"rules": {
|
||||
}
|
||||
}
|
||||
@ -15,6 +15,9 @@
|
||||
"@rollup/plugin-node-resolve": "^9.0.0",
|
||||
"@rollup/plugin-typescript": "^6.0.0",
|
||||
"@types/node": "^14.17.4",
|
||||
"@typescript-eslint/eslint-plugin": "^5.7.0",
|
||||
"@typescript-eslint/parser": "^5.7.0",
|
||||
"eslint": "^8.4.1",
|
||||
"obsidian": "https://github.com/obsidianmd/obsidian-api/tarball/master",
|
||||
"rollup": "^2.52.2",
|
||||
"ts-node": "^9.1.0",
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -16,7 +16,7 @@ export abstract class Card {
|
||||
containsCode: boolean
|
||||
modelName: string
|
||||
|
||||
constructor(id: number, deckName: string, initialContent: string, fields: Record<string, string>, reversed: boolean, endOffset: number, tags: string[], inserted: boolean, mediaNames: string[], containsCode: boolean = false) {
|
||||
constructor(id: number, deckName: string, initialContent: string, fields: Record<string, string>, reversed: boolean, endOffset: number, tags: string[], inserted: boolean, mediaNames: string[], containsCode = false) {
|
||||
this.id = id
|
||||
this.deckName = deckName
|
||||
this.initialContent = initialContent
|
||||
@ -43,14 +43,14 @@ export abstract class Card {
|
||||
// return false
|
||||
// }
|
||||
|
||||
let fields = Object.entries(card.fields)
|
||||
const fields = Object.entries(card.fields)
|
||||
// This is the case of a switch from a model to another one. It cannot be handeled
|
||||
if (fields.length !== Object.entries(this.fields).length) {
|
||||
return true
|
||||
}
|
||||
|
||||
for (let field of fields) {
|
||||
let fieldName = field[0]
|
||||
for (const field of fields) {
|
||||
const fieldName = field[0]
|
||||
if (field[1].value !== this.fields[fieldName]) {
|
||||
return false
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ import { codeDeckExtension, sourceDeckExtension } from 'src/constants';
|
||||
import { Card } from "src/entities/card";
|
||||
|
||||
export class Flashcard extends Card {
|
||||
constructor(id: number = -1, deckName: string, initialContent: string, fields: Record<string, string>, reversed: boolean, endOffset: number, tags: string[] = [], inserted: boolean = false, mediaNames: string[], containsCode: boolean) {
|
||||
constructor(id = -1, deckName: string, initialContent: string, fields: Record<string, string>, reversed: boolean, endOffset: number, tags: string[] = [], inserted = false, mediaNames: string[], containsCode: boolean) {
|
||||
super(id, deckName, initialContent, fields, reversed, endOffset, tags, inserted, mediaNames, containsCode)
|
||||
this.modelName = this.reversed ? `Obsidian-basic-reversed` : `Obsidian-basic`
|
||||
if (fields["Source"]) {
|
||||
@ -13,8 +13,8 @@ export class Flashcard extends Card {
|
||||
}
|
||||
}
|
||||
|
||||
public getCard(update: boolean = false): object {
|
||||
let card: any = {
|
||||
public getCard(update = false): object {
|
||||
const card: any = {
|
||||
"deckName": this.deckName,
|
||||
"modelName": this.modelName,
|
||||
"fields": this.fields,
|
||||
@ -29,7 +29,7 @@ export class Flashcard extends Card {
|
||||
}
|
||||
|
||||
public getMedias(): object[] {
|
||||
let medias: object[] = []
|
||||
const medias: object[] = []
|
||||
this.mediaBase64Encoded.forEach((data, index) => {
|
||||
medias.push({
|
||||
"filename": this.mediaNames[index],
|
||||
|
||||
@ -2,7 +2,7 @@ import { codeDeckExtension, sourceDeckExtension } from 'src/constants';
|
||||
import { Card } from "src/entities/card";
|
||||
|
||||
export class Inlinecard extends Card {
|
||||
constructor(id: number = -1, deckName: string, initialContent: string, fields: Record<string, string>, reversed: boolean, endOffset: number, tags: string[] = [], inserted: boolean = false, mediaNames: string[], containsCode: boolean) {
|
||||
constructor(id = -1, deckName: string, initialContent: string, fields: Record<string, string>, reversed: boolean, endOffset: number, tags: string[] = [], inserted = false, mediaNames: string[], containsCode: boolean) {
|
||||
super(id, deckName, initialContent, fields, reversed, endOffset, tags, inserted, mediaNames, containsCode) // ! CHANGE []
|
||||
|
||||
this.modelName = this.reversed ? `Obsidian-basic-reversed` : `Obsidian-basic`
|
||||
@ -14,8 +14,8 @@ export class Inlinecard extends Card {
|
||||
}
|
||||
}
|
||||
|
||||
public getCard(update: boolean = false): object {
|
||||
let card: any = {
|
||||
public getCard(update = false): object {
|
||||
const card: any = {
|
||||
"deckName": this.deckName,
|
||||
"modelName": this.modelName,
|
||||
"fields": this.fields,
|
||||
@ -30,7 +30,7 @@ export class Inlinecard extends Card {
|
||||
}
|
||||
|
||||
public getMedias(): object[] {
|
||||
let medias: object[] = []
|
||||
const medias: object[] = []
|
||||
this.mediaBase64Encoded.forEach((data, index) => {
|
||||
medias.push({
|
||||
"filename": this.mediaNames[index],
|
||||
|
||||
@ -2,7 +2,7 @@ import { codeDeckExtension, sourceDeckExtension } from 'src/constants';
|
||||
import { Card } from "src/entities/card";
|
||||
|
||||
export class Spacedcard extends Card {
|
||||
constructor(id: number = -1, deckName: string, initialContent: string, fields: Record<string, string>, reversed: boolean, endOffset: number, tags: string[] = [], inserted: boolean = false, mediaNames: string[], containsCode: boolean) {
|
||||
constructor(id = -1, deckName: string, initialContent: string, fields: Record<string, string>, reversed: boolean, endOffset: number, tags: string[] = [], inserted = false, mediaNames: string[], containsCode: boolean) {
|
||||
super(id, deckName, initialContent, fields, reversed, endOffset, tags, inserted, mediaNames, containsCode)
|
||||
this.modelName = `Obsidian-spaced`
|
||||
if (fields["Source"]) {
|
||||
@ -13,9 +13,9 @@ export class Spacedcard extends Card {
|
||||
}
|
||||
}
|
||||
|
||||
public getCard(update: boolean = false): object {
|
||||
public getCard(update = false): object {
|
||||
|
||||
let card: any = {
|
||||
const card: any = {
|
||||
"deckName": this.deckName,
|
||||
"modelName": this.modelName,
|
||||
"fields": this.fields,
|
||||
@ -30,7 +30,7 @@ export class Spacedcard extends Card {
|
||||
}
|
||||
|
||||
public getMedias(): object[] {
|
||||
let medias: object[] = []
|
||||
const medias: object[] = []
|
||||
this.mediaBase64Encoded.forEach((data, index) => {
|
||||
medias.push({
|
||||
"filename": this.mediaNames[index],
|
||||
|
||||
@ -3,7 +3,7 @@ import { Anki } from 'src/services/anki'
|
||||
|
||||
export class SettingsTab extends PluginSettingTab {
|
||||
display(): void {
|
||||
let { containerEl } = this
|
||||
const { containerEl } = this
|
||||
const plugin = (this as any).plugin
|
||||
|
||||
containerEl.empty()
|
||||
|
||||
@ -34,13 +34,13 @@ export class Regex {
|
||||
this.cardsToDelete = /^\s*(?:\n)(?:\^(\d{13}))(?:\n\s*?)?/gm
|
||||
|
||||
// https://regex101.com/r/WxuFI2/1
|
||||
this.globalTagsSplitter = /\[\[(.*?)\]\]|#([\p{L}:\-_\/]+)|([\p{L}:\-_\/]+)/gmiu
|
||||
this.globalTagsSplitter = /\[\[(.*?)\]\]|#([\p{L}:\-_/]+)|([\p{L}:\-_/]+)/gmiu
|
||||
this.tagHierarchy = /\//gm
|
||||
|
||||
// Cards
|
||||
let flags = "gimu"
|
||||
const flags = "gimu"
|
||||
// https://regex101.com/r/p3yQwY/2
|
||||
let str = "( {0,3}[#]*)((?:[^\\n]\\n?)+?)(#" + settings.flashcardsTag + "(?:[\/-]reverse)?)((?: *#[\\p{Letter}\\-\\/_]+)*) *?\\n+((?:[^\\n]\\n?)*?(?=\\^\\d{13}|$))(?:\\^(\\d{13}))?"
|
||||
let str = "( {0,3}[#]*)((?:[^\\n]\\n?)+?)(#" + settings.flashcardsTag + "(?:[/-]reverse)?)((?: *#[\\p{Letter}\\-\\/_]+)*) *?\\n+((?:[^\\n]\\n?)*?(?=\\^\\d{13}|$))(?:\\^(\\d{13}))?"
|
||||
this.flashscardsWithTag = new RegExp(str, flags)
|
||||
|
||||
// https://regex101.com/r/Ixtzlv/1
|
||||
@ -52,7 +52,7 @@ export class Regex {
|
||||
this.cardsInlineStyle = new RegExp(str, flags)
|
||||
|
||||
// https://regex101.com/r/HOXF5E/1
|
||||
str = "( {0,3}[#]*)((?:[^\\n]\\n?)+?)(#" + settings.flashcardsTag + "[\/-]spaced)((?: *#[\\p{Letter}-]+)*) *\\n?(?:\\^(\\d{13}))?"
|
||||
str = "( {0,3}[#]*)((?:[^\\n]\\n?)+?)(#" + settings.flashcardsTag + "[/-]spaced)((?: *#[\\p{Letter}-]+)*) *\\n?(?:\\^(\\d{13}))?"
|
||||
this.cardsSpacedStyle = new RegExp(str, flags)
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,10 +16,10 @@ export class Anki {
|
||||
}
|
||||
|
||||
public async storeMediaFiles(cards: Card[]) {
|
||||
let actions: any[] = []
|
||||
const actions: any[] = []
|
||||
|
||||
for (let card of cards) {
|
||||
for (let media of card.getMedias()) {
|
||||
for (const card of cards) {
|
||||
for (const media of card.getMedias()) {
|
||||
actions.push({
|
||||
"action": "storeMediaFile",
|
||||
"params": media
|
||||
@ -35,7 +35,7 @@ export class Anki {
|
||||
}
|
||||
|
||||
public async storeCodeHighlightMedias() {
|
||||
let fileExists = await this.invoke(
|
||||
const fileExists = await this.invoke(
|
||||
"retrieveMediaFile",
|
||||
6,
|
||||
{
|
||||
@ -43,19 +43,19 @@ export class Anki {
|
||||
})
|
||||
|
||||
if (!fileExists) {
|
||||
let highlightjs = {
|
||||
const highlightjs = {
|
||||
"action": "storeMediaFile", "params": {
|
||||
"filename": "_highlight.js",
|
||||
"data": highlightjsBase64
|
||||
}
|
||||
}
|
||||
let highlightjsInit = {
|
||||
const highlightjsInit = {
|
||||
"action": "storeMediaFile", "params": {
|
||||
"filename": "_highlightInit.js",
|
||||
"data": hihglightjsInitBase64
|
||||
}
|
||||
}
|
||||
let highlightjcss = {
|
||||
const highlightjcss = {
|
||||
"action": "storeMediaFile", "params": {
|
||||
"filename": "_highlight.css",
|
||||
"data": highlightCssBase64
|
||||
@ -66,7 +66,7 @@ export class Anki {
|
||||
}
|
||||
|
||||
public async addCards(cards: Card[]): Promise<number[]> {
|
||||
let notes: any = []
|
||||
const notes: any = []
|
||||
|
||||
cards.forEach(card => notes.push(card.getCard(false)))
|
||||
|
||||
@ -92,9 +92,9 @@ export class Anki {
|
||||
// This means that the delta from the current tags on Anki and the generated one should be added/removed
|
||||
// That's what the current approach does, but in the future if the API it is made more consistent
|
||||
// then mergeTags(...) is not needed anymore
|
||||
let ids: number[] = []
|
||||
const ids: number[] = []
|
||||
|
||||
for (let card of cards) {
|
||||
for (const card of cards) {
|
||||
updateActions.push({
|
||||
"action": "updateNoteFields",
|
||||
"params": {
|
||||
@ -139,11 +139,11 @@ export class Anki {
|
||||
}
|
||||
|
||||
private mergeTags(oldTags: string[], newTags: string[], cardId: number) {
|
||||
let actions = []
|
||||
const actions = []
|
||||
|
||||
// Find tags to Add
|
||||
for (let tag of newTags) {
|
||||
let index = oldTags.indexOf(tag)
|
||||
for (const tag of newTags) {
|
||||
const index = oldTags.indexOf(tag)
|
||||
if (index > -1) {
|
||||
oldTags.splice(index, 1)
|
||||
} else {
|
||||
@ -158,7 +158,7 @@ export class Anki {
|
||||
}
|
||||
|
||||
// All Tags to delete
|
||||
for (let tag of oldTags) {
|
||||
for (const tag of oldTags) {
|
||||
actions.push({
|
||||
"action": "removeTags",
|
||||
"params": {
|
||||
@ -171,7 +171,7 @@ export class Anki {
|
||||
return actions
|
||||
}
|
||||
|
||||
private invoke(action: string, version: number = 6, params = {}): any {
|
||||
private invoke(action: string, version = 6, params = {}): any {
|
||||
return new Promise((resolve, reject) => {
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.addEventListener('error', () => reject('failed to issue request'));
|
||||
@ -181,10 +181,10 @@ export class Anki {
|
||||
if (Object.getOwnPropertyNames(response).length != 2) {
|
||||
throw 'response has an unexpected number of fields';
|
||||
}
|
||||
if (!response.hasOwnProperty('error')) {
|
||||
if (!Object.prototype.hasOwnProperty.call(response, "error")) {
|
||||
throw 'response is missing required error field';
|
||||
}
|
||||
if (!response.hasOwnProperty('result')) {
|
||||
if (!Object.prototype.hasOwnProperty.call(response, "result")) {
|
||||
throw 'response is missing required result field';
|
||||
}
|
||||
if (response.error) {
|
||||
@ -216,13 +216,13 @@ export class Anki {
|
||||
codeExtension = codeDeckExtension
|
||||
}
|
||||
|
||||
let css = ".card {\r\n font-family: arial;\r\n font-size: 20px;\r\n text-align: center;\r\n color: black;\r\n background-color: white;\r\n}\r\n\r\n.tag::before {\r\n\tcontent: \"#\";\r\n}\r\n\r\n.tag {\r\n color: white;\r\n background-color: #9F2BFF;\r\n border: none;\r\n font-size: 11px;\r\n font-weight: bold;\r\n padding: 1px 8px;\r\n margin: 0px 3px;\r\n text-align: center;\r\n text-decoration: none;\r\n cursor: pointer;\r\n border-radius: 14px;\r\n display: inline;\r\n vertical-align: middle;\r\n}\r\n"
|
||||
let front = `{{Front}}\r\n<p class=\"tags\">{{Tags}}<\/p>\r\n\r\n<script>\r\n var tagEl = document.querySelector(\'.tags\');\r\n var tags = tagEl.innerHTML.split(\' \');\r\n var html = \'\';\r\n tags.forEach(function(tag) {\r\n\tif (tag) {\r\n\t var newTag = \'<span class=\"tag\">\' + tag + \'<\/span>\';\r\n html += newTag;\r\n \t tagEl.innerHTML = html;\r\n\t}\r\n });\r\n \r\n<\/script>${codeScriptContent}`
|
||||
let back = `{{FrontSide}}\n\n<hr id=answer>\n\n{{Back}}${sourceFieldContent}`
|
||||
let frontReversed = `{{Back}}\r\n<p class=\"tags\">{{Tags}}<\/p>\r\n\r\n<script>\r\n var tagEl = document.querySelector(\'.tags\');\r\n var tags = tagEl.innerHTML.split(\' \');\r\n var html = \'\';\r\n tags.forEach(function(tag) {\r\n\tif (tag) {\r\n\t var newTag = \'<span class=\"tag\">\' + tag + \'<\/span>\';\r\n html += newTag;\r\n \t tagEl.innerHTML = html;\r\n\t}\r\n });\r\n \r\n<\/script>${codeScriptContent}`
|
||||
let backReversed = `{{FrontSide}}\n\n<hr id=answer>\n\n{{Front}}${sourceFieldContent}`
|
||||
let prompt = `{{Prompt}}\r\n<p class=\"tags\">🧠spaced {{Tags}}<\/p>\r\n\r\n<script>\r\n var tagEl = document.querySelector(\'.tags\');\r\n var tags = tagEl.innerHTML.split(\' \');\r\n var html = \'\';\r\n tags.forEach(function(tag) {\r\n\tif (tag) {\r\n\t var newTag = \'<span class=\"tag\">\' + tag + \'<\/span>\';\r\n html += newTag;\r\n \t tagEl.innerHTML = html;\r\n\t}\r\n });\r\n \r\n<\/script>${codeScriptContent}`
|
||||
let promptBack = `{{FrontSide}}\n\n<hr id=answer>🧠 Review done.${sourceFieldContent}`
|
||||
const css = ".card {\r\n font-family: arial;\r\n font-size: 20px;\r\n text-align: center;\r\n color: black;\r\n background-color: white;\r\n}\r\n\r\n.tag::before {\r\n\tcontent: \"#\";\r\n}\r\n\r\n.tag {\r\n color: white;\r\n background-color: #9F2BFF;\r\n border: none;\r\n font-size: 11px;\r\n font-weight: bold;\r\n padding: 1px 8px;\r\n margin: 0px 3px;\r\n text-align: center;\r\n text-decoration: none;\r\n cursor: pointer;\r\n border-radius: 14px;\r\n display: inline;\r\n vertical-align: middle;\r\n}\r\n"
|
||||
const front = `{{Front}}\r\n<p class=\"tags\">{{Tags}}<\/p>\r\n\r\n<script>\r\n var tagEl = document.querySelector(\'.tags\');\r\n var tags = tagEl.innerHTML.split(\' \');\r\n var html = \'\';\r\n tags.forEach(function(tag) {\r\n\tif (tag) {\r\n\t var newTag = \'<span class=\"tag\">\' + tag + \'<\/span>\';\r\n html += newTag;\r\n \t tagEl.innerHTML = html;\r\n\t}\r\n });\r\n \r\n<\/script>${codeScriptContent}`
|
||||
const back = `{{FrontSide}}\n\n<hr id=answer>\n\n{{Back}}${sourceFieldContent}`
|
||||
const frontReversed = `{{Back}}\r\n<p class=\"tags\">{{Tags}}<\/p>\r\n\r\n<script>\r\n var tagEl = document.querySelector(\'.tags\');\r\n var tags = tagEl.innerHTML.split(\' \');\r\n var html = \'\';\r\n tags.forEach(function(tag) {\r\n\tif (tag) {\r\n\t var newTag = \'<span class=\"tag\">\' + tag + \'<\/span>\';\r\n html += newTag;\r\n \t tagEl.innerHTML = html;\r\n\t}\r\n });\r\n \r\n<\/script>${codeScriptContent}`
|
||||
const backReversed = `{{FrontSide}}\n\n<hr id=answer>\n\n{{Front}}${sourceFieldContent}`
|
||||
const prompt = `{{Prompt}}\r\n<p class=\"tags\">🧠spaced {{Tags}}<\/p>\r\n\r\n<script>\r\n var tagEl = document.querySelector(\'.tags\');\r\n var tags = tagEl.innerHTML.split(\' \');\r\n var html = \'\';\r\n tags.forEach(function(tag) {\r\n\tif (tag) {\r\n\t var newTag = \'<span class=\"tag\">\' + tag + \'<\/span>\';\r\n html += newTag;\r\n \t tagEl.innerHTML = html;\r\n\t}\r\n });\r\n \r\n<\/script>${codeScriptContent}`
|
||||
const promptBack = `{{FrontSide}}\n\n<hr id=answer>🧠 Review done.${sourceFieldContent}`
|
||||
|
||||
let classicFields = ["Front", "Back"]
|
||||
let promptFields = ["Prompt"]
|
||||
@ -231,7 +231,7 @@ export class Anki {
|
||||
promptFields = promptFields.concat("Source")
|
||||
}
|
||||
|
||||
let obsidianBasic = {
|
||||
const obsidianBasic = {
|
||||
"action": "createModel",
|
||||
"params": {
|
||||
"modelName": `Obsidian-basic${sourceExtension}${codeExtension}`,
|
||||
@ -247,7 +247,7 @@ export class Anki {
|
||||
}
|
||||
}
|
||||
|
||||
let obsidianBasicReversed = {
|
||||
const obsidianBasicReversed = {
|
||||
"action": "createModel",
|
||||
"params": {
|
||||
"modelName": `Obsidian-basic-reversed${sourceExtension}${codeExtension}`,
|
||||
@ -268,7 +268,7 @@ export class Anki {
|
||||
}
|
||||
}
|
||||
|
||||
let obsidianSpaced = {
|
||||
const obsidianSpaced = {
|
||||
"action": "createModel",
|
||||
"params": {
|
||||
"modelName": `Obsidian-spaced${sourceExtension}${codeExtension}`,
|
||||
|
||||
@ -43,14 +43,14 @@ export class CardsService {
|
||||
this.updateFile = false
|
||||
this.totalOffset = 0
|
||||
this.notifications = []
|
||||
let filePath = activeFile.basename
|
||||
let sourcePath = activeFile.path
|
||||
let fileCachedMetadata = this.app.metadataCache.getFileCache(activeFile)
|
||||
let vaultName = this.app.vault.getName()
|
||||
const filePath = activeFile.basename
|
||||
const sourcePath = activeFile.path
|
||||
const fileCachedMetadata = this.app.metadataCache.getFileCache(activeFile)
|
||||
const vaultName = this.app.vault.getName()
|
||||
let globalTags: string[] = undefined
|
||||
|
||||
// Parse frontmatter
|
||||
let frontmatter = fileCachedMetadata.frontmatter
|
||||
const frontmatter = fileCachedMetadata.frontmatter
|
||||
let deckName = this.settings.deck
|
||||
if (frontmatter) {
|
||||
deckName = parseFrontMatterEntry(frontmatter, "cards-deck") || this.settings.deck
|
||||
@ -66,13 +66,13 @@ export class CardsService {
|
||||
}
|
||||
globalTags = this.parseGlobalTags(this.file)
|
||||
// TODO with empty check that does not call ankiCards line
|
||||
let ankiBlocks = this.parser.getAnkiIDsBlocks(this.file)
|
||||
let ankiCards = ankiBlocks ? await this.anki.getCards(this.getAnkiIDs(ankiBlocks)) : undefined
|
||||
const ankiBlocks = this.parser.getAnkiIDsBlocks(this.file)
|
||||
const ankiCards = ankiBlocks ? await this.anki.getCards(this.getAnkiIDs(ankiBlocks)) : undefined
|
||||
|
||||
let cards: Card[] = this.parser.generateFlashcards(this.file, deckName, vaultName, filePath, globalTags)
|
||||
let [cardsToCreate, cardsToUpdate, cardsNotInAnki] = this.filterByUpdate(ankiCards, cards)
|
||||
let cardIds: number[] = this.getCardsIds(ankiCards, cards)
|
||||
let cardsToDelete: number[] = this.parser.getCardsToDelete(this.file)
|
||||
const cards: Card[] = this.parser.generateFlashcards(this.file, deckName, vaultName, filePath, globalTags)
|
||||
const [cardsToCreate, cardsToUpdate, cardsNotInAnki] = this.filterByUpdate(ankiCards, cards)
|
||||
const cardIds: number[] = this.getCardsIds(ankiCards, cards)
|
||||
const cardsToDelete: number[] = this.parser.getCardsToDelete(this.file)
|
||||
|
||||
console.info("Flashcards: Cards to create")
|
||||
console.info(cardsToCreate)
|
||||
@ -82,7 +82,7 @@ export class CardsService {
|
||||
console.info(cardsToDelete)
|
||||
if (cardsNotInAnki) {
|
||||
console.info("Flashcards: Cards not in Anki (maybe deleted)")
|
||||
for (let card of cardsNotInAnki) {
|
||||
for (const card of cardsNotInAnki) {
|
||||
this.notifications.push(`Error: Card with ID ${card.id} is not in Anki!`)
|
||||
}
|
||||
}
|
||||
@ -94,7 +94,7 @@ export class CardsService {
|
||||
await this.insertCardsOnAnki(cardsToCreate, frontmatter, deckName)
|
||||
|
||||
// Update decks if needed
|
||||
let deckNeedToBeChanged = await this.deckNeedToBeChanged(cardIds, deckName)
|
||||
const deckNeedToBeChanged = await this.deckNeedToBeChanged(cardIds, deckName)
|
||||
if (deckNeedToBeChanged) {
|
||||
try {
|
||||
this.anki.changeDeck(cardIds, deckName)
|
||||
@ -141,17 +141,17 @@ export class CardsService {
|
||||
if (this.app.vault.adapter instanceof FileSystemAdapter) {
|
||||
// @ts-ignore: Unreachable code error
|
||||
|
||||
for (let card of cards) {
|
||||
for (let media of card.mediaNames) {
|
||||
let image = this.app.metadataCache.getFirstLinkpathDest(decodeURIComponent(media), sourcePath);
|
||||
for (const card of cards) {
|
||||
for (const media of card.mediaNames) {
|
||||
const image = this.app.metadataCache.getFirstLinkpathDest(decodeURIComponent(media), sourcePath);
|
||||
try {
|
||||
let binaryMedia = await this.app.vault.readBinary(image)
|
||||
const binaryMedia = await this.app.vault.readBinary(image)
|
||||
card.mediaBase64Encoded.push(arrayBufferToBase64(binaryMedia))
|
||||
} catch (err) {
|
||||
Error("Error: Could not read media")
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -159,7 +159,7 @@ export class CardsService {
|
||||
if (cardsToCreate.length) {
|
||||
let insertedCards = 0
|
||||
try {
|
||||
let ids = await this.anki.addCards(cardsToCreate)
|
||||
const ids = await this.anki.addCards(cardsToCreate)
|
||||
// Add IDs from response to Flashcard[]
|
||||
ids.map((id: number, index: number) => {
|
||||
cardsToCreate[index].id = id
|
||||
@ -188,10 +188,10 @@ export class CardsService {
|
||||
}
|
||||
|
||||
private updateFrontmatter(frontmatter: FrontMatterCache, deckName: string) {
|
||||
let newFrontmatter: string = ""
|
||||
let cardsDeckLine: string = `cards-deck: ${deckName}\n`
|
||||
let newFrontmatter = ""
|
||||
const cardsDeckLine = `cards-deck: ${deckName}\n`
|
||||
if (frontmatter) {
|
||||
let oldFrontmatter: string = this.file.substring(frontmatter.position.start.offset, frontmatter.position.end.offset)
|
||||
const oldFrontmatter: string = this.file.substring(frontmatter.position.start.offset, frontmatter.position.end.offset)
|
||||
if (!oldFrontmatter.match(this.regex.cardsDeckLine)) {
|
||||
newFrontmatter = oldFrontmatter.substring(0, oldFrontmatter.length - 3) + cardsDeckLine + "---"
|
||||
this.totalOffset += cardsDeckLine.length
|
||||
@ -205,7 +205,7 @@ export class CardsService {
|
||||
}
|
||||
|
||||
private writeAnkiBlocks(cardsToCreate: Card[]) {
|
||||
for (let card of cardsToCreate) {
|
||||
for (const card of cardsToCreate) {
|
||||
// Card.id cannot be null, because if written already previously it has an ID,
|
||||
// if it has been inserted it has an ID too
|
||||
if (card.id !== null && !card.inserted) {
|
||||
@ -218,7 +218,7 @@ export class CardsService {
|
||||
}
|
||||
}
|
||||
card.endOffset += this.totalOffset
|
||||
let offset = card.endOffset
|
||||
const offset = card.endOffset
|
||||
|
||||
this.updateFile = true
|
||||
this.file = this.file.substring(0, offset) + id + this.file.substring(offset, this.file.length + 1)
|
||||
@ -245,7 +245,7 @@ export class CardsService {
|
||||
if (cards.length) {
|
||||
let deletedCards = 0
|
||||
for (const block of ankiBlocks) {
|
||||
let id = Number(block[1])
|
||||
const id = Number(block[1])
|
||||
|
||||
// Deletion of cards that need to be deleted (i.e. blocks ID that don't have content)
|
||||
if (cards.includes(id)) {
|
||||
@ -269,8 +269,8 @@ export class CardsService {
|
||||
}
|
||||
|
||||
private getAnkiIDs(blocks: RegExpMatchArray[]): number[] {
|
||||
let IDs: number[] = []
|
||||
for (let b of blocks) {
|
||||
const IDs: number[] = []
|
||||
for (const b of blocks) {
|
||||
IDs.push(Number(b[1]))
|
||||
}
|
||||
|
||||
@ -280,11 +280,11 @@ export class CardsService {
|
||||
|
||||
public filterByUpdate(ankiCards: any, generatedCards: Card[]) {
|
||||
let cardsToCreate: Card[] = []
|
||||
let cardsToUpdate: Card[] = []
|
||||
let cardsNotInAnki: Card[] = []
|
||||
const cardsToUpdate: Card[] = []
|
||||
const cardsNotInAnki: Card[] = []
|
||||
|
||||
if (ankiCards) {
|
||||
for (let flashcard of generatedCards) {
|
||||
for (const flashcard of generatedCards) {
|
||||
// Inserted means that anki blocks are available, that means that the card should
|
||||
// (the user can always delete it) be in Anki
|
||||
let ankiCard = undefined
|
||||
@ -308,7 +308,7 @@ export class CardsService {
|
||||
}
|
||||
|
||||
public async deckNeedToBeChanged(cardsIds: number[], deckName: string) {
|
||||
let cardsInfo = await this.anki.cardsInfo(cardsIds)
|
||||
const cardsInfo = await this.anki.cardsInfo(cardsIds)
|
||||
console.log("Flashcards: Cards info")
|
||||
console.log(cardsInfo)
|
||||
if (cardsInfo.length !== 0) {
|
||||
@ -322,7 +322,7 @@ export class CardsService {
|
||||
let ids: number[] = []
|
||||
|
||||
if (ankiCards) {
|
||||
for (let flashcard of generatedCards) {
|
||||
for (const flashcard of generatedCards) {
|
||||
let ankiCard = undefined
|
||||
if (flashcard.inserted) {
|
||||
ankiCard = ankiCards.filter((card: any) => Number(card.noteId) === flashcard.id)[0]
|
||||
@ -336,10 +336,10 @@ export class CardsService {
|
||||
return ids
|
||||
}
|
||||
|
||||
public parseGlobalTags(file: String): string[] {
|
||||
public parseGlobalTags(file: string): string[] {
|
||||
let globalTags: string[] = []
|
||||
|
||||
let tags = file.match(/(?:cards-)?tags: ?(.*)/im)
|
||||
const tags = file.match(/(?:cards-)?tags: ?(.*)/im)
|
||||
globalTags = tags ? tags[1].match(this.regex.globalTagsSplitter) : []
|
||||
|
||||
if (globalTags) {
|
||||
|
||||
@ -24,7 +24,7 @@ export class Parser {
|
||||
}
|
||||
|
||||
public generateFlashcards(file: string, deck: string, vault: string, note: string, globalTags: string[] = []): Flashcard[] {
|
||||
let contextAware = this.settings.contextAwareMode
|
||||
const contextAware = this.settings.contextAwareMode
|
||||
let cards: Flashcard[] = []
|
||||
let headings: any = []
|
||||
|
||||
@ -39,7 +39,7 @@ export class Parser {
|
||||
cards = cards.concat(this.generateSpacedCards(file, headings, deck, vault, note, globalTags))
|
||||
cards.sort((a, b) => a.endOffset - b.endOffset)
|
||||
|
||||
let defaultAnkiTag = this.settings.defaultAnkiTag
|
||||
const defaultAnkiTag = this.settings.defaultAnkiTag
|
||||
if (defaultAnkiTag) {
|
||||
for (const card of cards) {
|
||||
card.tags.push(defaultAnkiTag)
|
||||
@ -57,9 +57,9 @@ export class Parser {
|
||||
* @param headingLevel The level of the first ancestor heading, i.e. the number of #.
|
||||
*/
|
||||
private getContext(headings: any, index: number, headingLevel: number): string[] {
|
||||
let context: string[] = []
|
||||
const context: string[] = []
|
||||
let currentIndex: number = index
|
||||
let goalLevel: number = 6
|
||||
let goalLevel = 6
|
||||
|
||||
let i = headings.length - 1
|
||||
// Get the level of the first heading before the index (i.e. above the current line)
|
||||
@ -82,7 +82,7 @@ export class Parser {
|
||||
|
||||
// Search for the other headings
|
||||
for (i; i >= 0; i--) {
|
||||
let currentLevel = headings[i][1].length
|
||||
const currentLevel = headings[i][1].length
|
||||
if (currentLevel == goalLevel && headings[i].index < currentIndex) {
|
||||
currentIndex = headings[i].index
|
||||
goalLevel = currentLevel - 1
|
||||
@ -95,36 +95,36 @@ export class Parser {
|
||||
}
|
||||
|
||||
private generateSpacedCards(file: string, headings: any, deck: string, vault: string, note: string, globalTags: string[] = []) {
|
||||
let contextAware = this.settings.contextAwareMode
|
||||
let cards: Spacedcard[] = []
|
||||
let matches = [...file.matchAll(this.regex.cardsSpacedStyle)]
|
||||
const contextAware = this.settings.contextAwareMode
|
||||
const cards: Spacedcard[] = []
|
||||
const matches = [...file.matchAll(this.regex.cardsSpacedStyle)]
|
||||
|
||||
for (let match of matches) {
|
||||
let reversed: boolean = false
|
||||
for (const match of matches) {
|
||||
const reversed = false
|
||||
let headingLevel = -1
|
||||
if (match[1]) {
|
||||
headingLevel = match[1].trim().length !== 0 ? match[1].trim().length : -1
|
||||
}
|
||||
// Match.index - 1 because otherwise in the context there will be even match[1], i.e. the question itself
|
||||
let context = contextAware ? this.getContext(headings, match.index - 1, headingLevel) : ""
|
||||
const context = contextAware ? this.getContext(headings, match.index - 1, headingLevel) : ""
|
||||
|
||||
let originalPrompt = match[2].trim()
|
||||
const originalPrompt = match[2].trim()
|
||||
let prompt = contextAware ? [...context, match[2].trim()].join(`${this.settings.contextSeparator}`) : match[2].trim()
|
||||
let medias: string[] = this.getImageLinks(prompt)
|
||||
medias = medias.concat(this.getAudioLinks(prompt))
|
||||
prompt = this.parseLine(prompt, vault)
|
||||
|
||||
let endingLine = match.index + match[0].length
|
||||
let tags: string[] = this.parseTags(match[4], globalTags)
|
||||
let id: number = match[5] ? Number(match[5]) : -1
|
||||
let inserted: boolean = match[5] ? true : false
|
||||
let fields: any = { "Prompt": prompt }
|
||||
const endingLine = match.index + match[0].length
|
||||
const tags: string[] = this.parseTags(match[4], globalTags)
|
||||
const id: number = match[5] ? Number(match[5]) : -1
|
||||
const inserted: boolean = match[5] ? true : false
|
||||
const fields: any = { "Prompt": prompt }
|
||||
if (this.settings.sourceSupport) {
|
||||
fields["Source"] = note
|
||||
}
|
||||
let containsCode = this.containsCode([prompt])
|
||||
const containsCode = this.containsCode([prompt])
|
||||
|
||||
let card = new Spacedcard(id, deck, originalPrompt, fields, reversed, endingLine, tags, inserted, medias, containsCode)
|
||||
const card = new Spacedcard(id, deck, originalPrompt, fields, reversed, endingLine, tags, inserted, medias, containsCode)
|
||||
cards.push(card)
|
||||
}
|
||||
|
||||
@ -132,24 +132,24 @@ export class Parser {
|
||||
}
|
||||
|
||||
private generateInlineCards(file: string, headings: any, deck: string, vault: string, note: string, globalTags: string[] = []) {
|
||||
let contextAware = this.settings.contextAwareMode
|
||||
let cards: Inlinecard[] = []
|
||||
let matches = [...file.matchAll(this.regex.cardsInlineStyle)]
|
||||
const contextAware = this.settings.contextAwareMode
|
||||
const cards: Inlinecard[] = []
|
||||
const matches = [...file.matchAll(this.regex.cardsInlineStyle)]
|
||||
|
||||
for (let match of matches) {
|
||||
for (const match of matches) {
|
||||
if (match[2].toLowerCase().startsWith("cards-deck") || match[2].toLowerCase().startsWith("tags")) {
|
||||
continue
|
||||
}
|
||||
|
||||
let reversed: boolean = match[3].trim().toLowerCase() === ':::'
|
||||
const reversed: boolean = match[3].trim().toLowerCase() === ':::'
|
||||
let headingLevel = -1
|
||||
if (match[1]) {
|
||||
headingLevel = match[1].trim().length !== 0 ? match[1].trim().length : -1
|
||||
}
|
||||
// Match.index - 1 because otherwise in the context there will be even match[1], i.e. the question itself
|
||||
let context = contextAware ? this.getContext(headings, match.index - 1, headingLevel) : ""
|
||||
const context = contextAware ? this.getContext(headings, match.index - 1, headingLevel) : ""
|
||||
|
||||
let originalQuestion = match[2].trim()
|
||||
const originalQuestion = match[2].trim()
|
||||
let question = contextAware ? [...context, match[2].trim()].join(`${this.settings.contextSeparator}`) : match[2].trim()
|
||||
let answer = match[4].trim()
|
||||
let medias: string[] = this.getImageLinks(question)
|
||||
@ -158,17 +158,17 @@ export class Parser {
|
||||
question = this.parseLine(question, vault)
|
||||
answer = this.parseLine(answer, vault)
|
||||
|
||||
let endingLine = match.index + match[0].length
|
||||
let tags: string[] = this.parseTags(match[5], globalTags)
|
||||
let id: number = match[6] ? Number(match[6]) : -1
|
||||
let inserted: boolean = match[6] ? true : false
|
||||
let fields: any = { "Front": question, "Back": answer }
|
||||
const endingLine = match.index + match[0].length
|
||||
const tags: string[] = this.parseTags(match[5], globalTags)
|
||||
const id: number = match[6] ? Number(match[6]) : -1
|
||||
const inserted: boolean = match[6] ? true : false
|
||||
const fields: any = { "Front": question, "Back": answer }
|
||||
if (this.settings.sourceSupport) {
|
||||
fields["Source"] = note
|
||||
}
|
||||
let containsCode = this.containsCode([question, answer])
|
||||
const containsCode = this.containsCode([question, answer])
|
||||
|
||||
let card = new Inlinecard(id, deck, originalQuestion, fields, reversed, endingLine, tags, inserted, medias, containsCode)
|
||||
const card = new Inlinecard(id, deck, originalQuestion, fields, reversed, endingLine, tags, inserted, medias, containsCode)
|
||||
cards.push(card)
|
||||
}
|
||||
|
||||
@ -176,17 +176,17 @@ export class Parser {
|
||||
}
|
||||
|
||||
private generateCardsWithTag(file: string, headings: any, deck: string, vault: string, note: string, globalTags: string[] = []) {
|
||||
let contextAware = this.settings.contextAwareMode
|
||||
let cards: Flashcard[] = []
|
||||
let matches = [...file.matchAll(this.regex.flashscardsWithTag)]
|
||||
const contextAware = this.settings.contextAwareMode
|
||||
const cards: Flashcard[] = []
|
||||
const matches = [...file.matchAll(this.regex.flashscardsWithTag)]
|
||||
|
||||
for (let match of matches) {
|
||||
let reversed: boolean = match[3].trim().toLowerCase() === `#${this.settings.flashcardsTag}-reverse` || match[3].trim().toLowerCase() === `#${this.settings.flashcardsTag}/reverse`
|
||||
let headingLevel = match[1].trim().length !== 0 ? match[1].length : -1
|
||||
for (const match of matches) {
|
||||
const reversed: boolean = match[3].trim().toLowerCase() === `#${this.settings.flashcardsTag}-reverse` || match[3].trim().toLowerCase() === `#${this.settings.flashcardsTag}/reverse`
|
||||
const headingLevel = match[1].trim().length !== 0 ? match[1].length : -1
|
||||
// Match.index - 1 because otherwise in the context there will be even match[1], i.e. the question itself
|
||||
let context = contextAware ? this.getContext(headings, match.index - 1, headingLevel) : ""
|
||||
const context = contextAware ? this.getContext(headings, match.index - 1, headingLevel) : ""
|
||||
|
||||
let originalQuestion = match[2].trim()
|
||||
const originalQuestion = match[2].trim()
|
||||
let question = contextAware ? [...context, match[2].trim()].join(`${this.settings.contextSeparator}`) : match[2].trim()
|
||||
let answer = match[5].trim()
|
||||
let medias: string[] = this.getImageLinks(question)
|
||||
@ -195,17 +195,17 @@ export class Parser {
|
||||
question = this.parseLine(question, vault)
|
||||
answer = this.parseLine(answer, vault)
|
||||
|
||||
let endingLine = match.index + match[0].length
|
||||
let tags: string[] = this.parseTags(match[4], globalTags)
|
||||
let id: number = match[6] ? Number(match[6]) : -1
|
||||
let inserted: boolean = match[6] ? true : false
|
||||
let fields: any = { "Front": question, "Back": answer }
|
||||
const endingLine = match.index + match[0].length
|
||||
const tags: string[] = this.parseTags(match[4], globalTags)
|
||||
const id: number = match[6] ? Number(match[6]) : -1
|
||||
const inserted: boolean = match[6] ? true : false
|
||||
const fields: any = { "Front": question, "Back": answer }
|
||||
if (this.settings.sourceSupport) {
|
||||
fields["Source"] = note
|
||||
}
|
||||
let containsCode = this.containsCode([question, answer])
|
||||
const containsCode = this.containsCode([question, answer])
|
||||
|
||||
let card = new Flashcard(id, deck, originalQuestion, fields, reversed, endingLine, tags, inserted, medias, containsCode)
|
||||
const card = new Flashcard(id, deck, originalQuestion, fields, reversed, endingLine, tags, inserted, medias, containsCode)
|
||||
cards.push(card)
|
||||
}
|
||||
|
||||
@ -213,7 +213,7 @@ export class Parser {
|
||||
}
|
||||
|
||||
public containsCode(str: string[]): boolean {
|
||||
for (let s of str) {
|
||||
for (const s of str) {
|
||||
if (s.match(this.regex.codeBlock)) {
|
||||
return true
|
||||
}
|
||||
@ -231,15 +231,15 @@ export class Parser {
|
||||
}
|
||||
|
||||
private getImageLinks(str: string) {
|
||||
let wikiMatches = str.matchAll(this.regex.wikiImageLinks)
|
||||
let markdownMatches = str.matchAll(this.regex.markdownImageLinks)
|
||||
let links: string[] = []
|
||||
const wikiMatches = str.matchAll(this.regex.wikiImageLinks)
|
||||
const markdownMatches = str.matchAll(this.regex.markdownImageLinks)
|
||||
const links: string[] = []
|
||||
|
||||
for (let wikiMatch of wikiMatches) {
|
||||
for (const wikiMatch of wikiMatches) {
|
||||
links.push(wikiMatch[1])
|
||||
}
|
||||
|
||||
for (let markdownMatch of markdownMatches) {
|
||||
for (const markdownMatch of markdownMatches) {
|
||||
links.push(decodeURIComponent(markdownMatch[1]))
|
||||
}
|
||||
|
||||
@ -247,10 +247,10 @@ export class Parser {
|
||||
}
|
||||
|
||||
private getAudioLinks(str: string) {
|
||||
let wikiMatches = str.matchAll(this.regex.wikiAudioLinks)
|
||||
let links: string[] = []
|
||||
const wikiMatches = str.matchAll(this.regex.wikiAudioLinks)
|
||||
const links: string[] = []
|
||||
|
||||
for (let wikiMatch of wikiMatches) {
|
||||
for (const wikiMatch of wikiMatches) {
|
||||
links.push(wikiMatch[1])
|
||||
}
|
||||
|
||||
@ -258,13 +258,13 @@ export class Parser {
|
||||
}
|
||||
|
||||
private substituteObsidianLinks(str: string, vaultName: string) {
|
||||
let linkRegex = /\[\[(.+?)(?:\|(.+))?\]\]/gmi
|
||||
const linkRegex = /\[\[(.+?)(?:\|(.+))?\]\]/gmi
|
||||
vaultName = encodeURIComponent(vaultName)
|
||||
|
||||
return str.replace(linkRegex, (match, filename, rename) => {
|
||||
let href = `obsidian://open?vault=${vaultName}&file=${encodeURIComponent(filename)}.md`
|
||||
let fileRename = rename ? rename : filename
|
||||
let link = `<a href="${href}">[[${fileRename}]]</a>`
|
||||
const href = `obsidian://open?vault=${vaultName}&file=${encodeURIComponent(filename)}.md`
|
||||
const fileRename = rename ? rename : filename
|
||||
const link = `<a href="${href}">[[${fileRename}]]</a>`
|
||||
return link
|
||||
})
|
||||
}
|
||||
@ -281,12 +281,12 @@ export class Parser {
|
||||
}
|
||||
|
||||
private mathToAnki(str: string) {
|
||||
let mathBlockRegex = /(\$\$)(.*?)(\$\$)/gis
|
||||
const mathBlockRegex = /(\$\$)(.*?)(\$\$)/gis
|
||||
str = str.replace(mathBlockRegex, function (match, p1, p2) {
|
||||
return '\\\\[' + escapeMarkdown(p2) + ' \\\\]'
|
||||
})
|
||||
|
||||
let mathInlineRegex = /(\$)(.*?)(\$)/gi
|
||||
const mathInlineRegex = /(\$)(.*?)(\$)/gi
|
||||
str = str.replace(mathInlineRegex, function (match, p1, p2) {
|
||||
return '\\\\(' + escapeMarkdown(p2) + '\\\\)'
|
||||
})
|
||||
@ -295,10 +295,10 @@ export class Parser {
|
||||
}
|
||||
|
||||
private parseTags(str: string, globalTags: string[]): string[] {
|
||||
let tags: string[] = [...globalTags]
|
||||
const tags: string[] = [...globalTags]
|
||||
|
||||
if (str) {
|
||||
for (let tag of str.split("#")) {
|
||||
for (const tag of str.split("#")) {
|
||||
let newTag = tag.trim()
|
||||
if (newTag) {
|
||||
// Replace obsidian hierarchy tags delimeter \ with anki delimeter ::
|
||||
|
||||
22
src/utils.ts
22
src/utils.ts
@ -1,10 +1,8 @@
|
||||
import { Vault, TFile} from 'obsidian';
|
||||
|
||||
export function arrayBufferToBase64(buffer: ArrayBuffer): string {
|
||||
var binary = "";
|
||||
var bytes = new Uint8Array(buffer);
|
||||
var len = bytes.byteLength;
|
||||
for (var i = 0; i < len; i++) {
|
||||
let binary = "";
|
||||
const bytes = new Uint8Array(buffer);
|
||||
const len = bytes.byteLength;
|
||||
for (let i = 0; i < len; i++) {
|
||||
binary += String.fromCharCode(bytes[i]);
|
||||
}
|
||||
return window.btoa(binary);
|
||||
@ -18,14 +16,14 @@ export function arraysEqual(a: string[], b: string[]) {
|
||||
a.sort();
|
||||
b.sort();
|
||||
|
||||
for (var i = 0; i < a.length; ++i) {
|
||||
for (let i = 0; i < a.length; ++i) {
|
||||
if (a[i] !== b[i]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
export function escapeMarkdown(string: string, skips: string[] = []) {
|
||||
let replacements: any = [
|
||||
const replacements: any = [
|
||||
[/\*/g, "\\*", "asterisks"],
|
||||
[/#/g, "\\#", "number signs"],
|
||||
[/\//g, "\\/", "slashes"],
|
||||
@ -39,10 +37,10 @@ export function escapeMarkdown(string: string, skips: string[] = []) {
|
||||
[/_/g, "\\_", "underscores"],
|
||||
];
|
||||
|
||||
return replacements.reduce(function (string: string, replacement: any) {
|
||||
let name = replacement[2];
|
||||
return replacements.reduce(function (s: string, replacement: any) {
|
||||
const name = replacement[2];
|
||||
return name && skips.indexOf(name) !== -1
|
||||
? string
|
||||
: string.replace(replacement[0], replacement[1]);
|
||||
? s
|
||||
: s.replace(replacement[0], replacement[1]);
|
||||
}, string);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user