diff --git a/src/lib/parser/DeckParser.ts b/src/lib/parser/DeckParser.ts index ee15d9a8..31c4d8a3 100644 --- a/src/lib/parser/DeckParser.ts +++ b/src/lib/parser/DeckParser.ts @@ -19,7 +19,11 @@ import { embedFile } from './exporters/embedFile'; import getYouTubeEmbedLink from './helpers/getYouTubeEmbedLink'; import getYouTubeID from './helpers/getYouTubeID'; import { isFileNameEqual } from '../storage/types'; -import { isImageFileEmbedable, isMarkdownFile } from '../storage/checks'; +import { + isHTMLFile, + isImageFileEmbedable, + isMarkdownFile, +} from '../storage/checks'; import { getFileContents } from './getFileContents'; import { handleNestedBulletPointsInMarkdown } from './handleNestedBulletPointsInMarkdown'; import { checkFlashcardsLimits } from '../User/checkFlashcardsLimits'; @@ -60,30 +64,34 @@ export class DeckParser { this.firstDeckName = input.name; this.noLimits = input.noLimits; this.globalTags = null; + this.payload = []; + this.processFirstFile(input.name); + } - const firstFile = this.files.find((file) => - isFileNameEqual(file, input.name) - ); + processFirstFile(name: string) { + const firstFile = this.files.find((file) => isFileNameEqual(file, name)); - if (this.settings.nestedBulletPoints && isMarkdownFile(input.name)) { + if (this.settings.nestedBulletPoints && isMarkdownFile(name)) { const contents = getFileContents(firstFile, false); this.payload = handleNestedBulletPointsInMarkdown( - input.name, + name, contents?.toString(), this.settings.deckName, [], this.settings ); - } else { + } else if (isHTMLFile(name)) { const contents = getFileContents(firstFile, true); this.payload = contents ? this.handleHTML( - input.name, + name, contents.toString(), this.settings.deckName || '', [] ) : []; + } else { + this.payload = []; } } diff --git a/src/lib/parser/PrepareDeck.ts b/src/lib/parser/PrepareDeck.ts index 3092206f..a1f4a7da 100644 --- a/src/lib/parser/PrepareDeck.ts +++ b/src/lib/parser/PrepareDeck.ts @@ -1,7 +1,12 @@ import getDeckFilename from '../anki/getDeckFilename'; import { DeckParser, DeckParserInput } from './DeckParser'; import Deck from './Deck'; -import { isImageFile, isPDFFile, isPPTFile } from '../storage/checks'; +import { + isHTMLFile, + isImageFile, + isPDFFile, + isPPTFile, +} from '../storage/checks'; import { convertPDFToHTML } from './experimental/VertexAPI/convertPDFToHTML'; import { convertPDFToImages } from '../pdf/convertPDFToImages'; import { convertPPTToPDF } from '../pdf/ConvertPPTToPDF'; @@ -16,6 +21,8 @@ interface PrepareDeckResult { export async function PrepareDeck( input: DeckParserInput ): Promise { + const convertedImageFiles = []; + for (const file of input.files) { if (!file.contents) { continue; @@ -26,9 +33,13 @@ export async function PrepareDeck( input.settings.imageQuizHtmlToAnki && input.noLimits ) { - file.contents = await convertImageToHTML( + const convertedImageContents = await convertImageToHTML( file.contents?.toString('base64') ); + convertedImageFiles.push({ + name: `${file.name}.html`, + contents: convertedImageContents, + }); } if (!isPDFFile(file.name) && !isPPTFile(file.name)) continue; @@ -57,15 +68,23 @@ export async function PrepareDeck( } } + input.files.push(...convertedImageFiles); const parser = new DeckParser(input); if (parser.totalCardCount() === 0) { - const apkg = await parser.tryExperimental(input.workspace); - return { - name: getDeckFilename(parser.name ?? input.name), - apkg, - deck: parser.payload, - }; + if (convertedImageFiles.length > 0) { + const htmlFile = convertedImageFiles.find((file) => + isHTMLFile(file.name) + ); + parser.processFirstFile(htmlFile?.name ?? input.name); + } else { + const apkg = await parser.tryExperimental(input.workspace); + return { + name: getDeckFilename(parser.name ?? input.name), + apkg, + deck: parser.payload, + }; + } } const apkg = await parser.build(input.workspace); diff --git a/src/lib/parser/experimental/FallbackParser.ts b/src/lib/parser/experimental/FallbackParser.ts index a75cfd16..8236a814 100644 --- a/src/lib/parser/experimental/FallbackParser.ts +++ b/src/lib/parser/experimental/FallbackParser.ts @@ -121,7 +121,7 @@ class FallbackParser { const plainTextParser = new PlainTextParser(); const found = plainTextParser.parse(plainText); cards = this.mapCardsToNotes(found); - deckName = this.getTitleFromHTML(contents); + deckName = this.getTitleFromHTML(contents) ?? file.name; } else if (isMarkdownFile(file.name) || isPlainText(file.name)) { const plainTextParser = new PlainTextParser(); const items = this.getMarkdownBulletLists(contents); diff --git a/src/lib/parser/experimental/VertexAPI/convertImageToHTML.ts b/src/lib/parser/experimental/VertexAPI/convertImageToHTML.ts index 8e025a80..40cb94bc 100644 --- a/src/lib/parser/experimental/VertexAPI/convertImageToHTML.ts +++ b/src/lib/parser/experimental/VertexAPI/convertImageToHTML.ts @@ -1,5 +1,6 @@ import { VertexAI } from '@google-cloud/vertexai'; import { SAFETY_SETTINGS } from './constants'; +import { removeFirstAndLastLine } from './removeFirstAndLastLine'; export const convertImageToHTML = async ( imageData: string @@ -8,7 +9,7 @@ export const convertImageToHTML = async ( project: 'notion-to-anki', location: 'europe-west3', }); - const model = 'gemini-1.5-flash-002'; + const model = 'gemini-1.5-pro-002'; const generativeModel = vertexAI.preview.getGenerativeModel({ model: model, @@ -21,7 +22,7 @@ export const convertImageToHTML = async ( }); const text1 = { - text: `Convert the text in this image to the following format:  + text: `Convert the text in this image to the following format for (every question is their own ul):