Skip to content

Commit

Permalink
Smarter html markup inheritence when updating last card
Browse files Browse the repository at this point in the history
  • Loading branch information
killergerbah committed Apr 14, 2024
1 parent 7b77100 commit 6a89516
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 19 deletions.
33 changes: 33 additions & 0 deletions common/anki/anki.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { inheritHtmlMarkup } from './anki';

it('inherits marked up html', () => {
expect(inheritHtmlMarkup('a foo bar', '<c>foo</c> <b>bar</b> is')).toEqual('a <c>foo</c> <b>bar</b>');
});

it('inherits marked up html for nested tags', () => {
expect(inheritHtmlMarkup('a <c class="term">foo</c> bar', '<b><c class="term">foo</c></b> <b>bar</b> is')).toEqual(
'a <b><c class="term">foo</c></b> <b>bar</b>'
);
});

it('inherits marked up html for nested tags 2', () => {
expect(inheritHtmlMarkup('a foo bar', '<b><c class="term">foo</c></b> <b>bar</b> is')).toEqual(
'a <b><c class="term">foo</c></b> <b>bar</b>'
);
});

it('inherits marked up html for nested tags 3', () => {
expect(
inheritHtmlMarkup('a <c class="term">foo</c> bar', '<d><b><c class="term">foo</c></b></d> <b>bar</b> is')
).toEqual('a <d><b><c class="term">foo</c></b></d> <b>bar</b>');
});

it('inherits marked up html with break lines', () => {
expect(inheritHtmlMarkup('a foo bar', '<d>foo</d><br> <b>bar</b> is')).toEqual('a <d>foo</d> <b>bar</b>');
});

it('does not inherit marked up html if already marked up', () => {
expect(
inheritHtmlMarkup('a <d><b><c class="term">foo</c></b></d> bar', '<b><c class="term">foo</c></b> <b>bar</b> is')
).toEqual('a <d><b><c class="term">foo</c></b></d> <b>bar</b>');
});
74 changes: 55 additions & 19 deletions common/anki/anki.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,60 @@ const makeUniqueFileName = (fileName: string) => {
return `${baseName}_${randomString()}.${exension}`;
};

const htmlTagRegexString = '<([^/ >])*[^>]*>(.*?)</\\1>';

// Given <a><b>content</b></a> return ['<a><b>content</b></a>', '<b>content</b>', 'content']
const tagContent = (html: string) => {
const htmlTagRegex = new RegExp(htmlTagRegexString);
let content = html;
let contents = [html];

while (true) {
const match = htmlTagRegex.exec(content);

if (match === null || match.length < 3) {
break;
}

content = match[2];
contents.push(content);
}

return contents;
};

export const inheritHtmlMarkup = (original: string, markedUp: string) => {
const htmlTagRegex = new RegExp(htmlTagRegexString, 'ig');
const markedUpWithoutBreaklines = markedUp.replaceAll('<br>', '');
let inherited = original;

while (true) {
const match = htmlTagRegex.exec(markedUpWithoutBreaklines);

if (match === null || match.length < 3) {
break;
}

let newInherited = inherited;

if (!inherited.includes(match[0])) {
const candidateTargets = tagContent(match[2]);

for (const target of candidateTargets) {
newInherited = inherited.replace(target, match[0]);

if (newInherited !== inherited) {
break;
}
}
}

inherited = newInherited;
}

return inherited;
};

export type AnkiExportMode = 'gui' | 'updateLast' | 'default';

export async function exportCard(card: CardModel, ankiSettings: AnkiSettings, exportMode: AnkiExportMode) {
Expand Down Expand Up @@ -249,7 +303,7 @@ export class Anki {
typeof info.fields[this.settingsProvider.sentenceField]?.value === 'string' &&
typeof params.note.fields[this.settingsProvider.sentenceField] === 'string'
) {
params.note.fields[this.settingsProvider.sentenceField] = this._inheritHtmlMarkup(
params.note.fields[this.settingsProvider.sentenceField] = inheritHtmlMarkup(
params.note.fields[this.settingsProvider.sentenceField],
info.fields[this.settingsProvider.sentenceField].value
);
Expand Down Expand Up @@ -305,24 +359,6 @@ export class Anki {
return sanitize(name, { replacement: '_' });
}

private _inheritHtmlMarkup(original: string, markedUp: string) {
const htmlTagRegex = RegExp('<[^>]*>(.*?)</[^>]*>', 'ig');
const markedUpWithoutBreaklines = markedUp.replace('<br>', '');
let inherited = original;

while (true) {
const match = htmlTagRegex.exec(markedUpWithoutBreaklines);

if (match === null || match.length < 2) {
break;
}

inherited = inherited.replace(match[1], match[0]);
}

return inherited;
}

private async _storeMediaFile(name: string, base64: string, ankiConnectUrl?: string) {
return this._executeAction(
'storeMediaFile',
Expand Down

0 comments on commit 6a89516

Please sign in to comment.