Skip to content

Commit

Permalink
Merge pull request #122 from Pseudonium/develop
Browse files Browse the repository at this point in the history
Context Update
  • Loading branch information
Pseudonium authored Dec 11, 2020
2 parents 6291095 + a019f0c commit 979c378
Show file tree
Hide file tree
Showing 8 changed files with 113 additions and 13 deletions.
2 changes: 2 additions & 0 deletions main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export default class MyPlugin extends Plugin {
let settings: PluginSettings = {
CUSTOM_REGEXPS: {},
FILE_LINK_FIELDS: {},
CONTEXT_FIELDS: {},
Syntax: {
"Begin Note": "START",
"End Note": "END",
Expand All @@ -32,6 +33,7 @@ export default class MyPlugin extends Plugin {
"Tag": "Obsidian_to_Anki",
"Deck": "Default",
"Add File Link": false,
"Add Context": false,
"CurlyCloze": false,
"Regex": false,
"ID Comments": true,
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.0.2",
"version": "3.1.0",
"minAppVersion": "0.9.20",
"description": "This is an Anki integration plugin! Designed for efficient bulk exporting.",
"author": "Pseudonium",
Expand Down
62 changes: 56 additions & 6 deletions src/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ abstract class AbstractFile {
url: string
original_file: string
data: FileData
file_cache: CachedMetadata

frozen_fields_dict: FROZEN_FIELDS_DICT
target_deck: string
Expand All @@ -98,6 +99,7 @@ abstract class AbstractFile {
this.path = path
this.url = url
this.original_file = this.file
this.file_cache = file_cache
this.formatter = new FormatConverter(file_cache, this.data.vault_name)
}

Expand Down Expand Up @@ -142,6 +144,22 @@ abstract class AbstractFile {
}
}

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

abstract writeIDs(): void

removeEmpties() {
Expand Down Expand Up @@ -228,7 +246,11 @@ export class File extends AbstractFile {
let parsed = new Note(
note, this.data.fields_dict, this.data.curly_cloze, this.formatter
).parse(
this.target_deck, this.url, this.frozen_fields_dict, this.data.file_link_fields
this.target_deck,
this.url,
this.frozen_fields_dict,
this.data,
this.data.add_context ? this.getContextAtIndex(note_match.index) : ""
)
if (parsed.identifier == null) {
// Need to make sure global_tags get added
Expand All @@ -254,7 +276,11 @@ export class File extends AbstractFile {
let parsed = new InlineNote(
note, this.data.fields_dict, this.data.curly_cloze, this.formatter
).parse(
this.target_deck, this.url, this.frozen_fields_dict, this.data.file_link_fields
this.target_deck,
this.url,
this.frozen_fields_dict,
this.data,
this.data.add_context ? this.getContextAtIndex(note_match.index) : ""
)
if (parsed.identifier == null) {
// Need to make sure global_tags get added
Expand Down Expand Up @@ -365,7 +391,13 @@ export class RegexFile extends AbstractFile {
const parsed: AnkiConnectNoteAndID = new RegexNote(
match, note_type, this.data.fields_dict,
true, true, this.data.curly_cloze, this.formatter
).parse(this.target_deck,this.url,this.frozen_fields_dict, this.data.file_link_fields)
).parse(
this.target_deck,
this.url,
this.frozen_fields_dict,
this.data,
this.data.add_context ? this.getContextAtIndex(match.index) : ""
)
if (!this.data.EXISTING_IDS.includes(parsed.identifier)) {
if (parsed.identifier == CLOZE_ERROR) {
continue
Expand All @@ -384,7 +416,13 @@ export class RegexFile extends AbstractFile {
const parsed: AnkiConnectNoteAndID = new RegexNote(
match, note_type, this.data.fields_dict,
false, true, this.data.curly_cloze, this.formatter
).parse(this.target_deck, this.url, this.frozen_fields_dict, this.data.file_link_fields)
).parse(
this.target_deck,
this.url,
this.frozen_fields_dict,
this.data,
this.data.add_context ? this.getContextAtIndex(match.index) : ""
)
if (!this.data.EXISTING_IDS.includes(parsed.identifier)) {
if (parsed.identifier == CLOZE_ERROR) {
continue
Expand All @@ -403,7 +441,13 @@ export class RegexFile extends AbstractFile {
const parsed: AnkiConnectNoteAndID = new RegexNote(
match, note_type, this.data.fields_dict,
true, false, this.data.curly_cloze, this.formatter
).parse(this.target_deck, this.url, this.frozen_fields_dict, this.data.file_link_fields)
).parse(
this.target_deck,
this.url,
this.frozen_fields_dict,
this.data,
this.data.add_context ? this.getContextAtIndex(match.index) : ""
)
if (parsed.identifier == CLOZE_ERROR) {
continue
}
Expand All @@ -420,7 +464,13 @@ export class RegexFile extends AbstractFile {
const parsed: AnkiConnectNoteAndID = new RegexNote(
match, note_type, this.data.fields_dict,
false, false, this.data.curly_cloze, this.formatter
).parse(this.target_deck, this.url, this.frozen_fields_dict, this.data.file_link_fields)
).parse(
this.target_deck,
this.url,
this.frozen_fields_dict,
this.data,
this.data.add_context ? this.getContextAtIndex(match.index) : ""
)
if (parsed.identifier == CLOZE_ERROR) {
//console.log("Note has no cloze deletions!")
continue
Expand Down
4 changes: 4 additions & 0 deletions src/interfaces/settings-interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { AnkiConnectNote } from './note-interface'
export interface PluginSettings {
CUSTOM_REGEXPS: Record<string, string>,
FILE_LINK_FIELDS: Record<string, string>,
CONTEXT_FIELDS: Record<string, string>
Syntax: {
"Begin Note": string,
"End Note": string,
Expand All @@ -18,6 +19,7 @@ export interface PluginSettings {
"Tag": string,
"Deck": string,
"Add File Link": boolean,
"Add Context": boolean,
"CurlyCloze": boolean,
"Regex": boolean,
"ID Comments": boolean,
Expand All @@ -29,6 +31,7 @@ export interface FileData {
fields_dict: FIELDS_DICT
custom_regexps: Record<string, string>
file_link_fields: Record<string, string>
context_fields: Record<string, string>
template: AnkiConnectNote
EXISTING_IDS: number[]
vault_name: string
Expand All @@ -42,6 +45,7 @@ export interface FileData {

curly_cloze: boolean
comment: boolean
add_context: boolean
}

export interface ParsedSettings extends FileData {
Expand Down
16 changes: 13 additions & 3 deletions src/note.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Does NOT deal with finding the note in the file.*/
import { FormatConverter } from './format'
import { AnkiConnectNote, AnkiConnectNoteAndID } from './interfaces/note-interface'
import { FIELDS_DICT, FROZEN_FIELDS_DICT } from './interfaces/field-interface'
import { FileData } from './interfaces/settings-interface'

const TAG_PREFIX:string = "Tags: "
export const TAG_SEP:string = " "
Expand Down Expand Up @@ -79,17 +80,21 @@ abstract class AbstractNote {

abstract getFields(): Record<string, string>

parse(deck:string, url:string, frozen_fields_dict: FROZEN_FIELDS_DICT, file_link_fields: Record<string, string>): AnkiConnectNoteAndID {
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))
template["modelName"] = this.note_type
template["fields"] = this.getFields()
const file_link_fields = data.file_link_fields
if (url) {
this.formatter.format_note_with_url(template, url, file_link_fields[this.note_type])
}
if (Object.keys(frozen_fields_dict).length) {
this.formatter.format_note_with_frozen_fields(template, frozen_fields_dict)
}

if (context) {
const context_field = data.context_fields[this.note_type]
template["fields"][context_field] += context
}
template["tags"].push(...this.tags)
template["deckName"] = deck
return {note: template, identifier: this.identifier}
Expand Down Expand Up @@ -263,16 +268,21 @@ export class RegexNote {
return fields
}

parse(deck: string, url: string = "", frozen_fields_dict: FROZEN_FIELDS_DICT, file_link_fields: Record<string, string>): AnkiConnectNoteAndID {
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))
template["modelName"] = this.note_type
template["fields"] = this.getFields()
const file_link_fields = data.file_link_fields
if (url) {
this.formatter.format_note_with_url(template, url, file_link_fields[this.note_type])
}
if (Object.keys(frozen_fields_dict).length) {
this.formatter.format_note_with_frozen_fields(template, frozen_fields_dict)
}
if (context) {
const context_field = data.context_fields[this.note_type]
template["fields"][context_field] += context
}
if (this.note_type.includes("Cloze") && !(note_has_clozes(template))) {
this.identifier = CLOZE_ERROR //An error code that says "don't add this note!"
}
Expand Down
2 changes: 2 additions & 0 deletions src/setting-to-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export async function settingToData(app: App, settings: PluginSettings, fields_d
result.fields_dict = fields_dict
result.custom_regexps = settings.CUSTOM_REGEXPS
result.file_link_fields = settings.FILE_LINK_FIELDS
result.context_fields = settings.CONTEXT_FIELDS
result.template = {
deckName: settings.Defaults.Deck,
modelName: "",
Expand All @@ -37,6 +38,7 @@ export async function settingToData(app: App, settings: PluginSettings, fields_d
result.add_file_link = settings.Defaults["Add File Link"]
result.comment = settings.Defaults["ID Comments"]
result.regex = settings.Defaults.Regex
result.add_context = settings.Defaults["Add Context"]

return result
}
37 changes: 34 additions & 3 deletions src/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const defaultDescs = {
"Tag": "The tag that the plugin automatically adds to any generated cards.",
"Deck": "The deck the plugin adds cards to if TARGET DECK is not specified in the file.",
"Add File Link": "Append a link to the file that generated the flashcard on the field specified in the table.",
"Add Context": "Append 'context' for the card, in the form of path > heading > heading etc, to the field specified in the table.",
"CurlyCloze": "Convert {cloze deletions} -> {{c1::cloze deletions}} on note types that have a 'Cloze' in their name.",
"Regex": "Scan using the provided custom regexps rather than the START END syntax.",
"ID Comments": "Wrap note IDs in a HTML comment."
Expand All @@ -19,17 +20,21 @@ export class SettingsTab extends PluginSettingTab {
let note_type_table = containerEl.createEl('table', {cls: "anki-settings-table"})
let head = note_type_table.createTHead()
let header_row = head.insertRow()
for (let header of ["Note Type", "Custom Regexp", "File Link Field"]) {
for (let header of ["Note Type", "Custom Regexp", "File Link Field", "Context Field"]) {
let th = document.createElement("th")
th.appendChild(document.createTextNode(header))
header_row.appendChild(th)
}
let main_body = note_type_table.createTBody()
if (!(plugin.settings.hasOwnProperty("CONTEXT_FIELDS"))) {
plugin.settings.CONTEXT_FIELDS = {}
}
for (let note_type of plugin.note_types) {
let row = main_body.insertRow()
row.insertCell()
row.insertCell()
row.insertCell()
row.insertCell()
let row_cells = row.children
row_cells[0].innerHTML = note_type

Expand All @@ -48,7 +53,7 @@ export class SettingsTab extends PluginSettingTab {
custom_regexp.infoEl.remove()
custom_regexp.controlEl.className += " anki-center"

let fields_section = plugin.settings.FILE_LINK_FIELDS
let link_fields_section = plugin.settings.FILE_LINK_FIELDS
let link_field = new Setting(row_cells[2] as HTMLElement)
.addDropdown(
async dropdown => {
Expand All @@ -71,7 +76,7 @@ export class SettingsTab extends PluginSettingTab {
dropdown.addOption(field, field)
}
dropdown.setValue(
fields_section.hasOwnProperty(note_type) ? fields_section[note_type] : field_names[0]
link_fields_section.hasOwnProperty(note_type) ? link_fields_section[note_type] : field_names[0]
)
dropdown.onChange((value) => {
plugin.settings.FILE_LINK_FIELDS[note_type] = value
Expand All @@ -82,6 +87,27 @@ export class SettingsTab extends PluginSettingTab {
link_field.settingEl = row_cells[2] as HTMLElement
link_field.infoEl.remove()
link_field.controlEl.className += " anki-center"

let context_fields_section: Record<string, string> = plugin.settings.CONTEXT_FIELDS
let context_field = new Setting(row_cells[3] as HTMLElement)
.addDropdown(
async dropdown => {
const field_names = plugin.fields_dict[note_type]
for (let field of field_names) {
dropdown.addOption(field, field)
}
dropdown.setValue(
context_fields_section.hasOwnProperty(note_type) ? context_fields_section[note_type] : field_names[0]
)
dropdown.onChange((value) => {
plugin.settings.CONTEXT_FIELDS[note_type] = value
plugin.saveAllData()
})
}
)
context_field.settingEl = row_cells[3] as HTMLElement
context_field.infoEl.remove()
context_field.controlEl.className += " anki-center"
}
}

Expand All @@ -106,6 +132,11 @@ export class SettingsTab extends PluginSettingTab {
let {containerEl} = this;
const plugin = (this as any).plugin
let defaults_settings = containerEl.createEl('h3', {text: 'Defaults'})

// To account for new add context
if (!(plugin.settings["Defaults"].hasOwnProperty("Add Context"))) {
plugin.settings["Defaults"]["Add Context"] = false
}
for (let key of Object.keys(plugin.settings["Defaults"])) {
if (typeof plugin.settings["Defaults"][key] === "string") {
new Setting(defaults_settings)
Expand Down
1 change: 1 addition & 0 deletions versions.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

{
"3.1.0": "0.9.20",
"3.0.2": "0.9.20",
"3.0.1": "0.9.20",
"3.0.0": "0.9.20"
Expand Down

0 comments on commit 979c378

Please sign in to comment.