Skip to content

Commit

Permalink
Merge pull request #132 from Pseudonium/develop
Browse files Browse the repository at this point in the history
Scheduling and Highlights update
  • Loading branch information
Pseudonium authored Dec 12, 2020
2 parents 03a7393 + 8e24775 commit ad6367c
Show file tree
Hide file tree
Showing 9 changed files with 132 additions and 56 deletions.
46 changes: 26 additions & 20 deletions main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@ export default class MyPlugin extends Plugin {
Defaults: {
"Tag": "Obsidian_to_Anki",
"Deck": "Default",
"Scheduling Interval": 0,
"Add File Link": false,
"Add Context": false,
"CurlyCloze": false,
"CurlyCloze - Highlights to Clozes": false,
"Regex": false,
"ID Comments": true,
}
Expand Down Expand Up @@ -151,6 +153,29 @@ export default class MyPlugin extends Plugin {
}
}

async scanVault() {
new Notice('Scanning vault, check console for details...');
console.log("Checking connection to Anki...")
try {
const test = await AnkiConnect.invoke('modelNames')
}
catch(e) {
new Notice("Error, couldn't connect to Anki! Check console for error message.")
return
}
const data: ParsedSettings = await settingToData(this.app, this.settings, this.fields_dict)
const manager = new FileManager(this.app, data, this.app.vault.getMarkdownFiles(), this.file_hashes, this.added_media)
await manager.initialiseFiles()
await manager.requests_1()
this.added_media = Array.from(manager.added_media_set)
const hashes = manager.getHashes()
for (let key in hashes) {
this.file_hashes[key] = hashes[key]
}
new Notice("All done! Saving file hashes and added media now...")
this.saveAllData()
}

async onload() {
console.log('loading Obsidian_to_Anki...');
addIcon('anki', ANKI_ICON)
Expand Down Expand Up @@ -182,26 +207,7 @@ export default class MyPlugin extends Plugin {
this.addSettingTab(new SettingsTab(this.app, this));

this.addRibbonIcon('anki', 'Obsidian_to_Anki - Scan Vault', async () => {
new Notice('Scanning vault, check console for details...');
console.log("Checking connection to Anki...")
try {
const test = await AnkiConnect.invoke('modelNames')
}
catch(e) {
new Notice("Error, couldn't connect to Anki! Check console for error message.")
return
}
const data: ParsedSettings = await settingToData(this.app, this.settings, this.fields_dict)
const manager = new FileManager(this.app, data, this.app.vault.getMarkdownFiles(), this.file_hashes, this.added_media)
await manager.initialiseFiles()
await manager.requests_1()
this.added_media = Array.from(manager.added_media_set)
const hashes = manager.getHashes()
for (let key in hashes) {
this.file_hashes[key] = hashes[key]
}
new Notice("All done! Saving file hashes and added media now...")
this.saveAllData()
await this.scanVault()
})
}

Expand Down
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "obsidian-to-anki-plugin",
"name": "Obsidian_to_Anki",
"version": "3.1.0",
"version": "3.2.0",
"minAppVersion": "0.9.20",
"description": "This is an Anki integration plugin! Designed for efficient bulk exporting.",
"author": "Pseudonium",
Expand Down
61 changes: 45 additions & 16 deletions src/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Md5 } from 'ts-md5/dist/md5';
import * as AnkiConnect from './anki'
import * as c from './constants'
import { FormatConverter } from './format'
import { CachedMetadata } from 'obsidian'
import { CachedMetadata, HeadingCache } from 'obsidian'

const double_regexp: RegExp = /(?:\r\n|\r|\n)((?:\r\n|\r|\n)(?:<!--)?ID: \d+)/g

Expand Down Expand Up @@ -116,7 +116,13 @@ abstract class AbstractFile {
for (let match of this.file.matchAll(this.data.FROZEN_REGEXP)) {
const [note_type, fields]: [string, string] = [match[1], match[2]]
const virtual_note = note_type + "\n" + fields
const parsed_fields: Record<string, string> = new Note(virtual_note, this.data.fields_dict, this.data.curly_cloze, this.formatter).getFields()
const parsed_fields: Record<string, string> = new Note(
virtual_note,
this.data.fields_dict,
this.data.curly_cloze,
this.data.highlights_to_cloze,
this.formatter
).getFields()
frozen_fields_dict[note_type] = parsed_fields
}
this.frozen_fields_dict = frozen_fields_dict
Expand Down Expand Up @@ -145,19 +151,34 @@ abstract class AbstractFile {
}

getContextAtIndex(position: number): string {
let result: string[] = [this.path]
let result: string = this.path
let currentContext: HeadingCache[] = []
if (!(this.file_cache.hasOwnProperty('headings'))) {
return result.join(" > ")
return result
}
for (let heading of this.file_cache.headings) {
if (position < heading.position.start.offset) {
for (let currentHeading of this.file_cache.headings) {
if (position < currentHeading.position.start.offset) {
//We've gone past position now with headings, so let's return!
return result.join(" > ")
break
}
result = result.slice(0, heading.level)
result.push(heading.heading)
let insert_index: number = 0
for (let contextHeading of currentContext) {
if (currentHeading.level > contextHeading.level) {
insert_index += 1
continue
}
break
}
currentContext = currentContext.slice(0, insert_index)
currentContext.push(currentHeading)
}
let heading_strs: string[] = []
for (let contextHeading of currentContext) {
heading_strs.push(contextHeading.heading)
}
return result.join(" > ")
let result_arr: string[] = [result]
result_arr.push(...heading_strs)
return result_arr.join(" > ")
}

abstract writeIDs(): void
Expand Down Expand Up @@ -244,7 +265,11 @@ export class File extends AbstractFile {
let [note, position]: [string, number] = [note_match[1], note_match.index + note_match[0].indexOf(note_match[1]) + note_match[1].length]
// That second thing essentially gets the index of the end of the first capture group.
let parsed = new Note(
note, this.data.fields_dict, this.data.curly_cloze, this.formatter
note,
this.data.fields_dict,
this.data.curly_cloze,
this.data.highlights_to_cloze,
this.formatter
).parse(
this.target_deck,
this.url,
Expand Down Expand Up @@ -274,7 +299,11 @@ export class File extends AbstractFile {
let [note, position]: [string, number] = [note_match[1], note_match.index + note_match[0].indexOf(note_match[1]) + note_match[1].length]
// That second thing essentially gets the index of the end of the first capture group.
let parsed = new InlineNote(
note, this.data.fields_dict, this.data.curly_cloze, this.formatter
note,
this.data.fields_dict,
this.data.curly_cloze,
this.data.highlights_to_cloze,
this.formatter
).parse(
this.target_deck,
this.url,
Expand Down Expand Up @@ -390,7 +419,7 @@ export class RegexFile extends AbstractFile {
this.ignore_spans.push([match.index, match.index + match[0].length])
const parsed: AnkiConnectNoteAndID = new RegexNote(
match, note_type, this.data.fields_dict,
true, true, this.data.curly_cloze, this.formatter
true, true, this.data.curly_cloze, this.data.highlights_to_cloze, this.formatter
).parse(
this.target_deck,
this.url,
Expand All @@ -415,7 +444,7 @@ export class RegexFile extends AbstractFile {
this.ignore_spans.push([match.index, match.index + match[0].length])
const parsed: AnkiConnectNoteAndID = new RegexNote(
match, note_type, this.data.fields_dict,
false, true, this.data.curly_cloze, this.formatter
false, true, this.data.curly_cloze, this.data.highlights_to_cloze, this.formatter
).parse(
this.target_deck,
this.url,
Expand All @@ -440,7 +469,7 @@ export class RegexFile extends AbstractFile {
this.ignore_spans.push([match.index, match.index + match[0].length])
const parsed: AnkiConnectNoteAndID = new RegexNote(
match, note_type, this.data.fields_dict,
true, false, this.data.curly_cloze, this.formatter
true, false, this.data.curly_cloze, this.data.highlights_to_cloze, this.formatter
).parse(
this.target_deck,
this.url,
Expand All @@ -463,7 +492,7 @@ export class RegexFile extends AbstractFile {
this.ignore_spans.push([match.index, match.index + match[0].length])
const parsed: AnkiConnectNoteAndID = new RegexNote(
match, note_type, this.data.fields_dict,
false, false, this.data.curly_cloze, this.formatter
false, false, this.data.curly_cloze, this.data.highlights_to_cloze, this.formatter
).parse(
this.target_deck,
this.url,
Expand Down
8 changes: 7 additions & 1 deletion src/format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { CachedMetadata } from 'obsidian'
import * as c from './constants'

const ANKI_MATH_REGEXP:RegExp = /(\\\[[\s\S]*?\\\])|(\\\([\s\S]*?\\\))/g
const HIGHLIGHT_REGEXP:RegExp = /==(.*)==/g

const MATH_REPLACE:string = "OBSTOANKIMATH"
const INLINE_CODE_REPLACE:string = "OBSTOANKICODEINLINE"
Expand Down Expand Up @@ -130,7 +131,7 @@ export class FormatConverter {
return note_text
}

format(note_text: string, cloze: boolean = false): string {
format(note_text: string, cloze: boolean, highlights_to_cloze: boolean): string {
note_text = this.obsidian_to_anki_math(note_text)
//Extract the parts that are anki math
let math_matches: string[]
Expand All @@ -140,10 +141,15 @@ export class FormatConverter {
[note_text, inline_code_matches] = this.censor(note_text, c.OBS_CODE_REGEXP, INLINE_CODE_REPLACE);
[note_text, display_code_matches] = this.censor(note_text, c.OBS_DISPLAY_CODE_REGEXP, DISPLAY_CODE_REPLACE)
if (cloze) {
if (highlights_to_cloze) {
note_text = note_text.replace(HIGHLIGHT_REGEXP, "{$1}")
}
note_text = this.curly_to_cloze(note_text)
}
note_text = this.getAndFormatMedias(note_text)
note_text = this.formatLinks(note_text)
//Special for formatting highlights now, but want to avoid any == in code
note_text = note_text.replace(HIGHLIGHT_REGEXP, String.raw`<mark>$1</mark>`)
note_text = this.decensor(note_text, INLINE_CODE_REPLACE, inline_code_matches)
note_text = this.decensor(note_text, DISPLAY_CODE_REPLACE, display_code_matches)
note_text = converter.makeHtml(note_text)
Expand Down
3 changes: 3 additions & 0 deletions src/interfaces/settings-interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ export interface PluginSettings {
Defaults: {
"Tag": string,
"Deck": string,
"Scheduling Interval": number
"Add File Link": boolean,
"Add Context": boolean,
"CurlyCloze": boolean,
"CurlyCloze - Highlights to Clozes": boolean,
"Regex": boolean,
"ID Comments": boolean,
}
Expand All @@ -44,6 +46,7 @@ export interface FileData {
EMPTY_REGEXP: RegExp

curly_cloze: boolean
highlights_to_cloze: boolean
comment: boolean
add_context: boolean
}
Expand Down
31 changes: 14 additions & 17 deletions src/note.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,6 @@ export const TAG_SEP:string = " "
export const ID_REGEXP_STR: string = String.raw`\n?(?:<!--)?(?:ID: (\d+).*)`
export const TAG_REGEXP_STR: string = String.raw`(Tags: .*)`

const NOTE_DICT_TEMPLATE: AnkiConnectNote = {
deckName: "",
modelName: "",
fields: {},
options: {
allowDuplicate: true,
duplicateScope: "deck",
},
tags: ["Obsidian_to_Anki"],
}

const ANKI_CLOZE_REGEXP: RegExp = /{{c\d+::[\s\S]+?}}/g
export const CLOZE_ERROR: number = 42

Expand Down Expand Up @@ -55,8 +44,9 @@ abstract class AbstractNote {
ID_REGEXP: RegExp = /(?:<!--)?ID: (\d+)/
formatter: FormatConverter
curly_cloze: boolean
highlights_to_cloze: boolean

constructor(note_text: string, fields_dict: FIELDS_DICT, curly_cloze: boolean, formatter: FormatConverter) {
constructor(note_text: string, fields_dict: FIELDS_DICT, curly_cloze: boolean, highlights_to_cloze: boolean, formatter: FormatConverter) {
this.text = note_text.trim()
this.current_field_num = 0
this.delete = false
Expand All @@ -68,6 +58,7 @@ abstract class AbstractNote {
this.current_field = this.field_names[0]
this.formatter = formatter
this.curly_cloze = curly_cloze
this.highlights_to_cloze = highlights_to_cloze
}

abstract getSplitText(): string[]
Expand All @@ -81,7 +72,7 @@ abstract class AbstractNote {
abstract getFields(): Record<string, string>

parse(deck:string, url:string, frozen_fields_dict: FROZEN_FIELDS_DICT, data: FileData, context:string): AnkiConnectNoteAndID {
let template = JSON.parse(JSON.stringify(NOTE_DICT_TEMPLATE))
let template = data.template
template["modelName"] = this.note_type
template["fields"] = this.getFields()
const file_link_fields = data.file_link_fields
Expand Down Expand Up @@ -152,7 +143,8 @@ export class Note extends AbstractNote {
for (let key in fields) {
fields[key] = this.formatter.format(
fields[key].trim(),
this.note_type.includes("Cloze") && this.curly_cloze
this.note_type.includes("Cloze") && this.curly_cloze,
this.highlights_to_cloze
).trim()
}
return fields
Expand Down Expand Up @@ -213,7 +205,8 @@ export class InlineNote extends AbstractNote {
for (let key in fields) {
fields[key] = this.formatter.format(
fields[key].trim(),
this.note_type.includes("Cloze") && this.curly_cloze
this.note_type.includes("Cloze") && this.curly_cloze,
this.highlights_to_cloze
).trim()
}
return fields
Expand All @@ -231,6 +224,7 @@ export class RegexNote {
tags: string[]
field_names: string[]
curly_cloze: boolean
highlights_to_cloze: boolean
formatter: FormatConverter

constructor(
Expand All @@ -240,6 +234,7 @@ export class RegexNote {
tags: boolean,
id: boolean,
curly_cloze: boolean,
highlights_to_cloze: boolean,
formatter: FormatConverter
) {
this.match = match
Expand All @@ -249,6 +244,7 @@ export class RegexNote {
this.field_names = fields_dict[note_type]
this.curly_cloze = curly_cloze
this.formatter = formatter
this.highlights_to_cloze = highlights_to_cloze
}

getFields(): Record<string, string> {
Expand All @@ -262,14 +258,15 @@ export class RegexNote {
for (let key in fields) {
fields[key] = this.formatter.format(
fields[key].trim(),
this.note_type.includes("Cloze") && this.curly_cloze
this.note_type.includes("Cloze") && this.curly_cloze,
this.highlights_to_cloze
).trim()
}
return fields
}

parse(deck: string, url: string = "", frozen_fields_dict: FROZEN_FIELDS_DICT, data: FileData, context: string): AnkiConnectNoteAndID {
let template = JSON.parse(JSON.stringify(NOTE_DICT_TEMPLATE))
let template = data.template
template["modelName"] = this.note_type
template["fields"] = this.getFields()
const file_link_fields = data.file_link_fields
Expand Down
1 change: 1 addition & 0 deletions src/setting-to-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export async function settingToData(app: App, settings: PluginSettings, fields_d

//Just a simple transfer
result.curly_cloze = settings.Defaults.CurlyCloze
result.highlights_to_cloze = settings.Defaults["CurlyCloze - Highlights to Clozes"]
result.add_file_link = settings.Defaults["Add File Link"]
result.comment = settings.Defaults["ID Comments"]
result.regex = settings.Defaults.Regex
Expand Down
Loading

0 comments on commit ad6367c

Please sign in to comment.