diff --git a/.gitignore b/.gitignore
index 4969a45a..42ca261d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
+# data.json need save
+./data.json
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
diff --git a/Images/1cfcb1bb28a06e354b339691fe79a5d40c32ac3d8d74a0c1a5fd1b4f554e201a.png b/Images/1cfcb1bb28a06e354b339691fe79a5d40c32ac3d8d74a0c1a5fd1b4f554e201a.png
new file mode 100644
index 00000000..a5017f48
Binary files /dev/null and b/Images/1cfcb1bb28a06e354b339691fe79a5d40c32ac3d8d74a0c1a5fd1b4f554e201a.png differ
diff --git a/Images/5913712e835c128fdc7a12c0c0c1caa006ac7d47bf85a3a9f6c5970e37a0a948.png b/Images/5913712e835c128fdc7a12c0c0c1caa006ac7d47bf85a3a9f6c5970e37a0a948.png
new file mode 100644
index 00000000..7c79e5e8
Binary files /dev/null and b/Images/5913712e835c128fdc7a12c0c0c1caa006ac7d47bf85a3a9f6c5970e37a0a948.png differ
diff --git a/README.md b/README.md
index 18b04483..a73f67de 100644
--- a/README.md
+++ b/README.md
@@ -1,132 +1,53 @@
-# Obsidian_to_Anki
-Plugin to add flashcards from a text or markdown file to Anki. Run in Obsidian as a plugin, or from the command-line as a python script. Built with [Obsidian](https://obsidian.md/) markdown syntax in mind. Supports **user-defined custom syntax for flashcards.**
-See the [Trello](https://trello.com/b/6MXEizGg/obsidiantoanki) for planned features.
-
-## Getting started
-
-Check out the [Wiki](https://github.com/Pseudonium/Obsidian_to_Anki/wiki)! It has a ton of information, including setup instructions for new users. I will include a copy of the instructions here:
-
-## Setup
-
-### All users
-1. Start up [Anki](https://apps.ankiweb.net/), and navigate to your desired profile.
-2. Ensure that you've installed [AnkiConnect](https://git.foosoft.net/alex/anki-connect).
-
-### Obsidian plugin users
-3. Have [Obsidian](https://obsidian.md/) downloaded
-4. Search the 'Community plugins' list for this plugin
-5. Install the plugin.
-6. In Anki, navigate to Tools->Addons->AnkiConnect->Config, and change it to look like this:
-
-{
- "apiKey": null,
- "apiLogPath": null,
- "webBindAddress": "127.0.0.1",
- "webBindPort": 8765,
- "webCorsOrigin": "http://localhost",
- "webCorsOriginList": [
- "http://localhost",
- "app://obsidian.md"
- ]
-}
-
-
-7. Restart Anki to apply the above changes
-8. With Anki running in the background, load the plugin. This will generate the plugin settings.
-
-
-You shouldn't need Anki running to load Obsidian in the future, though of course you will need it for using the plugin!
-
-To run the plugin, look for an Anki icon on your ribbon (the place where buttons such as 'open Graph view' and 'open Quick Switcher' are).
-For more information on use, please check out the [Wiki](https://github.com/Pseudonium/Obsidian_to_Anki/wiki)!
-
-### Python script users
-3. Install the latest version of [Python](https://www.python.org/downloads/).
-4. If you are a new user, download `obstoanki_setup.py` from the [releases page](https://github.com/Pseudonium/Obsidian_to_Anki/releases), and place it in the folder you want the script installed (for example your notes folder).
-5. Run `obstoanki_setup.py`, for example by double-clicking it in a file explorer. This will download the latest version of the script and required dependencies automatically. Existing users should be able to run their existing `obstoanki_setup.py` to get the latest version of the script.
-6. Check the Permissions tab below to ensure the script is able to run.
-7. Run `obsidian_to_anki.py`, for example by double-clicking it in a file explorer. This will generate a config file, `obsidian_to_anki_config.ini`.
-
-#### Permissions
-The script needs to be able to:
-* Make a config file in the directory the script is installed.
-* Read the file in the directory the script is used.
-* Make a backup file in the directory the script is used.
-* Rename files in the directory the script is used.
-* Remove a backup file in the directory the script is used.
-* Change the current working directory temporarily (so that local image paths are resolved correctly).
-
-## Features
-
-Current features (check out the wiki for more details):
-* **Custom note types** - You're not limited to the 6 built-in note types of Anki.
-* **Custom scan directory**
- * The plugin will scan the entire vault by default
- * You can also set which directory (includes all sub-directories as well) to scan via plugin settings
-* **Ignore Folders and Files**
- * You can specify which files and folders to ignore
- * This can be done in the settings of this plugin with [Glob syntax](https://en.wikipedia.org/wiki/Glob_(programming)#Syntax).
- * If you're working on your own globs, you can test them out [here](https://globster.xyz/)
- * Examples:
- * `**/*.excalidraw.md` - Ignore all files that end in `.excalidraw.md`
- * => avoids excalidraw files from being scanned which can be extremely slow
- * `Template/**` - Ignore all files in the `Template` folder (including subfolders)
- * `**/private/**` - Ignore all files in folders that are called `private` no matter where they are in the vault
- * `[Pp]rivate*/**` - Ignore all files and folders in the root of the vault that start with `private` or with `Private`
-* **Updating notes from file** - Your text files are the canonical source of the notes.
-* **Tags**, including **tags for an entire file**.
-* **Adding to user-specified deck** on a *per-file* basis.
-* **Markdown formatting**.
-* **Math formatting**.
-* **Embedded images**. GIFs should work too.
-* **Audio**.
-* **Auto-deleting notes from the file**.
-* **Reading from all files in a directory automatically** - recursively too!
-* **Inline Notes** - Shorter syntax for typing out notes on a single line.
-* **Easy cloze formatting** - A more compact syntax to do Cloze text
-* **Frozen Fields**
-* **Obsidian integration** - A link to the file that made the flashcard, full link and image embed support.
-* **Custom syntax** - Using **regular expressions**, add custom syntax to generate **notes that make sense for you.** Some examples:
- * RemNote single-line style. `This is how to use::Remnote single-line style`
- 
- * Header paragraph style.
-
- # Style
- This style is suitable for having the header as the front, and the answer as the back
-
- 
- * Question answer style.
-
- Q: How do you use this style?
- A: Just like this.
-
- 
- * Neuracache #flashcard style.
-
- In Neuracache style, to make a flashcard you do #flashcard
- The next lines then become the back of the flashcard
-
- 
- * Ruled style
-
- How do you use ruled style?
- ---
- You need at least three '-' between the front and back of the card.
-
- 
- * Markdown table style
-
- | Why might this style be useful? |
- | ------ |
- | It looks nice when rendered as HTML in a markdown editor. |
-
- 
- * Cloze paragraph style
-
- The idea of {cloze paragraph style} is to be able to recognise any paragraphs that contain {cloze deletions}.
-
- 
-
-Note that **all custom syntax is off by default**, and must be programmed into the script via the config file - see the Wiki for more details.
-
-
+# 简介
+本项目由 [Obsidian_to_Anki](https://github.com/Pseudonium/Obsidian_to_Anki) fork而来
+在原来代码的基础上,添加一些功能
+1. 让obsidian markdown文件中的卡片在anki的deck的结构与文件夹结构保存一致
+例如:"/root/hello/world.md"中的卡片会自动同步到"root::hello::world"中
+2. 把id修改为blockid的形式,从而实现anki直接跳转到obsidian markdown文件对应的block
+
+3. 优化了context的内容,路径和标题加在最前面,以换行分割,后面有一行分割线和卡片具体内容区分。标题中如果有链接或公式可以转化成功。
+4. 对于卡片中对blockid的引用链接,自动转化为anki link插件支持的格式`[link test|nid1714433449297]`
+5. 优化了$的识别。现在\\\$不会识别为公式,会转化为\$。修改的格式化的顺序。现在先处理代码的部分。所以代码中出现\$不会识别为latex
+# 本项目使用方法
+将main.js和manifes.json文件替换obsidian to anki中的main.js manifes.json
+在插件设置中,开启设置,并重启obsidian
+具体的使用方法可以参考[Obsidian_to_Anki](https://github.com/Pseudonium/Obsidian_to_Anki)
+
+原来的正则表达式`(?)": "",
+ "问答题(同时生成翻转的卡片)": "",
+ "问答题(输入答案)": ""
+ },
+ "FILE_LINK_FIELDS": {
+ "Basic": "Front",
+ "Basic+": "Front",
+ "Basic++": "Front",
+ "Basic+++": "Front",
+ "Basic-73fde": "Front",
+ "Cloze ALL": "文字",
+ "Pot Card 2": "Front",
+ "Python - Basic": "Front",
+ "Python - Basic (and reversed card)": "Front",
+ "Python - Cloze": "Text",
+ "UVBasic-English": "英语单词",
+ "单词": "单词",
+ "图片遮盖": "遮盖",
+ "填空题": "文字",
+ "红宝书": "单词",
+ "问答题": "正面",
+ "问答题(同时生成翻转的卡片<可选>)": "正面",
+ "问答题(同时生成翻转的卡片)": "正面",
+ "问答题(输入答案)": "正面"
+ },
+ "CONTEXT_FIELDS": {
+ "Cloze ALL": "文字",
+ "问答题": "正面"
+ },
+ "FOLDER_DECKS": {
+ "未命名": "",
+ "第一个文件夹": "",
+ "第一个文件夹/第二个文件夹": "",
+ "norcx'anki'test": "",
+ "norcx'anki'test/asserts": ""
+ },
+ "FOLDER_TAGS": {
+ "未命名": "",
+ "第一个文件夹": "",
+ "第一个文件夹/第二个文件夹": "",
+ "norcx'anki'test": "",
+ "norcx'anki'test/asserts": ""
+ },
+ "Syntax": {
+ "Begin Note": "START",
+ "End Note": "END",
+ "Begin Inline Note": "STARTI",
+ "End Inline Note": "ENDI",
+ "Target Deck Line": "TARGET DECK",
+ "File Tags Line": "FILE TAGS",
+ "Delete Note Line": "DELETE",
+ "Frozen Fields Line": "FROZEN"
+ },
+ "Defaults": {
+ "Scan Directory": "",
+ "Tag": "Obsidian_to_Anki",
+ "Deck": "Default",
+ "Scheduling Interval": 0,
+ "Add File Link": true,
+ "Add Context": true,
+ "CurlyCloze": false,
+ "CurlyCloze - Highlights to Clozes": false,
+ "ID Comments": true,
+ "Add Obsidian Tags": false,
+ "Use Path as Deck": true,
+ "Add Card link": true
+ },
+ "IGNORED_FILE_GLOBS": [
+ "**/*.excalidraw.md"
+ ]
+ },
+ "Added Media": [
+ "Pasted image 20240419143443.png",
+ "Pasted image 20240419143952.png",
+ "Pasted image 20240419152053.png",
+ "Pasted image 20240419152108.png",
+ "Pasted image 20240419152116.png",
+ "Pasted image 20240419152119.png",
+ "Pasted image 20240504143655.png"
+ ],
+ "File Hashes": {
+ "这个文件不会出现.md": "3bf0f4061ead725b9f00d10156e48c32",
+ "这次必须成功.md": "c8cb44b25bf0f5f3abdb489ce570dea7",
+ "第一个文件夹/读书.md": "d41d8cd98f00b204e9800998ecf8427e",
+ "第一个文件夹/读一本好书.md": "2bc012e3b6e73af53f1e2254e494d7d2",
+ "第一个文件夹/第二个文件夹/你好呀.md": "09639afc110da5e7033d4e6ce12147ff",
+ "第一个文件夹/第二个文件夹/未命名.md": "ef1e094f5b366fe563e71c1f6bcd141c",
+ "第一个文件夹/第二个文件夹/你好.md": "d41d8cd98f00b204e9800998ecf8427e",
+ "要成功了.md": "9ff4e52b269f2e12afbb019771ca51c7",
+ "破案吧.md": "03e25ab08d38fd6ea0c97b27ad4a4b4a",
+ "未命名 1.md": "4c811787fb4a175e57da923063c1e41c",
+ "有笔记但是没有内容.md": "284f5c9fb85e25bcd79b43b83b1c3e33",
+ "未命名 4.md": "295a6be3b2f9283e4d143f2dc27d7ff2",
+ "未命名 2.md": "30a44ea90cb104d9b16dda3826232784",
+ "成功.md": "bcab17d6d9aa24ec021d86219ba80275",
+ "你是谁.md": "7ce5d9b5499bf82ca585cd0556562db2",
+ "什么都没有.md": "2228e977ebea8966e27929f43e39cb67",
+ "README.md": "5844997ffd21e5020ecaa7670e5d942e",
+ "图片测试.md": "0e71ded111d1d619f9693a3b48e20cc3",
+ "测试文件.md": "f0ccad7d3b2091db20689782f5b34cc5",
+ "Welcome.md": "5dce4937496ad2d20178a7578f1a1368",
+ "norcx'anki'test/未命名.md": "68a672a3c453707a5db64bd4da5324c5",
+ "未命名.md": "63d5a30db0177e57313c15e5cb709767",
+ "norcx'anki'test/挖空测试.md": "08d3f20ea7d3869cf4e63b8ad32533ae",
+ "未命名 1 1.md": "166ac5eb16bb207e951f3c68aa1f4943",
+ "一次添加成功测试.md": "988168da191b9968488324f0f79360fb",
+ "anki测试2.md": "76a3ee4bba713fca92310ecfe0d57a30",
+ "$测试.md": "3bce4a5b61225248526ad4c60e1a3037"
+ },
+ "fields_dict": {
+ "Basic": [
+ "Front",
+ "Back"
+ ],
+ "Basic+": [
+ "Front",
+ "Back"
+ ],
+ "Basic++": [
+ "Front",
+ "Back"
+ ],
+ "Basic+++": [
+ "Front",
+ "Back"
+ ],
+ "Basic-73fde": [
+ "Front",
+ "Back"
+ ],
+ "Cloze ALL": [
+ "文字",
+ "背面额外"
+ ],
+ "Pot Card 2": [
+ "Front",
+ "Back",
+ "Symbol1",
+ "Voice1",
+ "Symbol2",
+ "Voice2"
+ ],
+ "Python - Basic": [
+ "Front",
+ "Back - Basic",
+ "Back - Code",
+ "Additional Info",
+ "Example",
+ "Version"
+ ],
+ "Python - Basic (and reversed card)": [
+ "Front",
+ "Back",
+ "Additional Info",
+ "With Options",
+ "Example",
+ "Version"
+ ],
+ "Python - Cloze": [
+ "Text",
+ "Example",
+ "Version"
+ ],
+ "UVBasic-English": [
+ "英语单词",
+ "英美音标",
+ "中文释义",
+ "vocab简明",
+ "vocab扩展",
+ "真题原句",
+ "柯林斯星级",
+ "柯林斯解释",
+ "来源",
+ "英语发音"
+ ],
+ "单词": [
+ "单词",
+ "音标",
+ "助记词",
+ "线索",
+ "词性1",
+ "释义1",
+ "词性2",
+ "释义2",
+ "发音",
+ "拓展"
+ ],
+ "图片遮盖": [
+ "遮盖",
+ "图片",
+ "标题",
+ "背面额外",
+ "注释"
+ ],
+ "填空题": [
+ "文字",
+ "背面额外"
+ ],
+ "红宝书": [
+ "单词",
+ "音标",
+ "解释",
+ "红宝书",
+ "字源",
+ "不择手段背单词",
+ "趣味全助记",
+ "Audio"
+ ],
+ "问答题": [
+ "正面",
+ "背面"
+ ],
+ "问答题(同时生成翻转的卡片<可选>)": [
+ "正面",
+ "背面",
+ "添加翻转的卡片"
+ ],
+ "问答题(同时生成翻转的卡片)": [
+ "正面",
+ "背面"
+ ],
+ "问答题(输入答案)": [
+ "正面",
+ "背面"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/image.png b/image.png
new file mode 100644
index 00000000..44121bec
Binary files /dev/null and b/image.png differ
diff --git a/main.ts b/main.ts
index 4b4c1d30..666c494d 100644
--- a/main.ts
+++ b/main.ts
@@ -42,6 +42,8 @@ export default class MyPlugin extends Plugin {
"CurlyCloze - Highlights to Clozes": false,
"ID Comments": true,
"Add Obsidian Tags": false,
+ "Use Path as Deck" : false,
+ "Add Card link": false
},
IGNORED_FILE_GLOBS: DEFAULT_IGNORED_FILE_GLOBS,
}
diff --git a/manifest.json b/manifest.json
index e10e8a8e..99c90f74 100644
--- a/manifest.json
+++ b/manifest.json
@@ -1,10 +1,10 @@
{
- "id": "obsidian-to-anki-plugin",
- "name": "Obsidian_to_Anki",
- "version": "3.6.0",
+ "id": "norcx' obsidian-to-anki-plugin",
+ "name": "norcx' Obsidian_to_Anki",
+ "version": "0.2.0",
"minAppVersion": "0.9.20",
- "description": "This is an Anki integration plugin! Designed for efficient bulk exporting.",
- "author": "Pseudonium",
- "authorUrl": "https://github.com/Pseudonium/Obsidian_to_Anki",
+ "description": "More function for obsidian to anki",
+ "author": "Norcx",
+ "authorUrl": "https://github.com/norcx/new_obsidian_to_anki",
"isDesktopOnly": true
}
diff --git a/src/constants.ts b/src/constants.ts
index b0168b42..51ca8f4b 100644
--- a/src/constants.ts
+++ b/src/constants.ts
@@ -1,6 +1,6 @@
export const ANKI_ICON: string = ` `
-export const OBS_INLINE_MATH_REGEXP: RegExp = /(?"
@@ -92,8 +95,10 @@ abstract class AbstractFile {
tags: string[]
formatter: FormatConverter
-
- constructor(file_contents: string, path:string, url: string, data: FileData, file_cache: CachedMetadata) {
+ fullpath: string
+ use_path_as_deck:boolean
+ add_card_link:boolean
+ constructor(file_contents: string, path:string, url: string, data: FileData, file_cache: CachedMetadata, fullpath: string,use_path_as_deck:boolean, add_card_link:boolean) {
this.data = data
this.file = file_contents
this.path = path
@@ -101,6 +106,9 @@ abstract class AbstractFile {
this.original_file = this.file
this.file_cache = file_cache
this.formatter = new FormatConverter(file_cache, this.data.vault_name)
+ this.fullpath = fullpath
+ this.use_path_as_deck = use_path_as_deck
+ this.add_card_link = add_card_link
}
setup_frozen_fields_dict() {
@@ -129,8 +137,14 @@ abstract class AbstractFile {
}
setup_target_deck() {
+ if(this.use_path_as_deck){
+ this.target_deck = this.fullpath.replaceAll("/","::")
+ }
+ else{
const result = this.file.match(this.data.DECK_REGEXP)
this.target_deck = result ? result[1] : this.data.template["deckName"]
+ }
+
}
setup_global_tags() {
@@ -154,7 +168,7 @@ abstract class AbstractFile {
let result: string = this.path
let currentContext: HeadingCache[] = []
if (!(this.file_cache.hasOwnProperty('headings'))) {
- return result
+ return " "+result+" "+" "
}
for (let currentHeading of this.file_cache.headings) {
if (position < currentHeading.position.start.offset) {
@@ -174,11 +188,17 @@ abstract class AbstractFile {
}
let heading_strs: string[] = []
for (let contextHeading of currentContext) {
- heading_strs.push(contextHeading.heading)
+ let convertedHeading = contextHeading.heading
+ // 修改:添加Markdown链接转换为HTML链接的代码
+ const markdownLinkRegex = /\[([^\]]+)\]\(([^)]+)\)/g;
+ convertedHeading = contextHeading.heading.replace(markdownLinkRegex, '$1 ');
+ const mathRegex = /\$(.+?)\$/g;
+ convertedHeading = convertedHeading.replace(mathRegex, '\\($1\\)');
+ heading_strs.push(convertedHeading)
}
let result_arr: string[] = [result]
result_arr.push(...heading_strs)
- return result_arr.join(" > ")
+ return " "+result_arr.join(" ")+" "+" "
}
abstract writeIDs(): void
@@ -259,8 +279,8 @@ export class AllFile extends AbstractFile {
regex_notes_to_add: AnkiConnectNote[]
regex_id_indexes: number[]
- constructor(file_contents: string, path:string, url: string, data: FileData, file_cache: CachedMetadata) {
- super(file_contents, path, url, data, file_cache)
+ constructor(file_contents: string, path:string, url: string, data: FileData, file_cache: CachedMetadata,fullpath:string,use_path_as_deck:boolean,add_card_link:boolean) {
+ super(file_contents, path, url, data, file_cache, fullpath,use_path_as_deck,add_card_link)
this.custom_regexps = data.custom_regexps
}
@@ -417,6 +437,7 @@ export class AllFile extends AbstractFile {
}
}
+
scanFile() {
this.setupScan()
this.scanNotes()
@@ -434,6 +455,31 @@ export class AllFile extends AbstractFile {
fix_newline_ids() {
this.file = this.file.replace(double_regexp, "$1")
}
+ getAddNotesWithId(): AnkiConnect.AnkiConnectRequest {
+ let actions: AnkiConnect.AnkiConnectRequest[] = [];
+ this.all_notes_to_add.forEach((note, index) => {
+ // 使用this.note_ids数组中的相应ID
+ let id = this.note_ids[index];
+ if (id !== null) {
+ let updated = false; // 标志是否成功替换
+ // 遍历note.fields,查找"ID-null"的子字符串,替换为"ID-"+String(id)
+ for (let key in note.fields) {
+ let originalValue = note.fields[key];
+ note.fields[key] = originalValue.replace(/ID-null/g, "ID-" + id);
+ // 如果字段被更新,则设置 updated 为 true
+ if (originalValue !== note.fields[key]) {
+ updated = true;
+ }
+ }
+ // 如果成功替换,则添加更新操作,并继续到下一个笔记
+ if (updated) {
+ actions.push(AnkiConnect.updateNoteFields(id, note.fields));
+ }
+ }
+ });
+ return AnkiConnect.multi(actions);
+ }
+
writeIDs() {
let normal_inserts: [number, string][] = []
@@ -441,7 +487,7 @@ export class AllFile extends AbstractFile {
(id_position: number, index: number) => {
const identifier: number | null = this.note_ids[index]
if (identifier) {
- normal_inserts.push([id_position, id_to_str(identifier, false, this.data.comment)])
+ normal_inserts.push([id_position, id_to_str(identifier, false, this.data.comment,this.data.add_card_link)])
}
}
)
@@ -450,7 +496,7 @@ export class AllFile extends AbstractFile {
(id_position: number, index: number) => {
const identifier: number | null = this.note_ids[index + this.notes_to_add.length] //Since regular then inline
if (identifier) {
- inline_inserts.push([id_position, id_to_str(identifier, true, this.data.comment)])
+ inline_inserts.push([id_position, id_to_str(identifier, true, this.data.comment,this.data.add_card_link)])
}
}
)
@@ -459,7 +505,7 @@ export class AllFile extends AbstractFile {
(id_position: number, index: number) => {
const identifier: number | null = this.note_ids[index + this.notes_to_add.length + this.inline_notes_to_add.length] // Since regular then inline then regex
if (identifier) {
- regex_inserts.push([id_position, "\n" + id_to_str(identifier, false, this.data.comment)])
+ regex_inserts.push([id_position, "\n" + id_to_str(identifier, false, this.data.comment,this.data.add_card_link)])
}
}
)
diff --git a/src/files-manager.ts b/src/files-manager.ts
index fb4d35f3..cf311a11 100644
--- a/src/files-manager.ts
+++ b/src/files-manager.ts
@@ -5,6 +5,7 @@ import { AllFile } from './file'
import * as AnkiConnect from './anki'
import { basename } from 'path'
import multimatch from "multimatch"
+import { AnkiConnectNote } from './interfaces/note-interface'
interface addNoteResponse {
result: number,
error: string | null
@@ -136,15 +137,19 @@ export class FileManager {
async genAllFiles() {
for (let file of this.files) {
const content: string = await this.app.vault.read(file)
+ const fullpath: string = (file.path.slice(0, -file.extension.length - 1))
const cache: CachedMetadata = this.app.metadataCache.getCache(file.path)
const file_data = this.dataToFileData(file)
this.ownFiles.push(
new AllFile(
content,
file.path,
- this.data.add_file_link ? this.getUrl(file) : "",
+ this.data.add_file_link ? (this.data.add_card_link ? this.getUrl(file).slice(0,-3)+"%23%5E" :this.getUrl(file)) : "",
file_data,
- cache
+ cache,
+ fullpath,
+ this.data.use_path_as_deck,
+ this.data.add_card_link
)
)
}
@@ -279,6 +284,7 @@ export class FileManager {
}
file.card_ids = temp
}
+ let temp: AnkiConnect.AnkiConnectRequest[] = []
for (let index in this.ownFiles) {
let i: number = parseInt(index)
let ownFile = this.ownFiles[i]
@@ -286,10 +292,13 @@ export class FileManager {
ownFile.tags = tag_list
ownFile.writeIDs()
ownFile.removeEmpties()
+ temp.push(ownFile.getAddNotesWithId())
if (ownFile.file !== ownFile.original_file) {
await this.app.vault.modify(obFile, ownFile.file)
}
}
+ console.info("Requesting addition of id links...")
+ await AnkiConnect.invoke('multi', {actions: temp})
await this.requests_2()
}
@@ -306,6 +315,8 @@ export class FileManager {
let temp: AnkiConnect.AnkiConnectRequest[] = []
console.info("Requesting cards to be moved to target deck...")
for (let file of this.ownFiles) {
+ if (file.regex_id_indexes.length + file.inline_id_indexes.length === 0)
+ continue
temp.push(file.getChangeDecks())
}
requests.push(AnkiConnect.multi(temp))
diff --git a/src/format.ts b/src/format.ts
index 0e81dfad..6eb7bb89 100644
--- a/src/format.ts
+++ b/src/format.ts
@@ -58,7 +58,7 @@ export class FormatConverter {
}
format_note_with_url(note: AnkiConnectNote, url: string, field: string): void {
- note.fields[field] += 'Obsidian '
+ note.fields[field] += '🔗 '
}
format_note_with_frozen_fields(note: AnkiConnectNote, frozen_fields_dict: Record>): void {
@@ -119,8 +119,16 @@ export class FormatConverter {
if (!(this.file_cache.hasOwnProperty("links"))) {
return note_text
}
+ const regex = /\[([^\]]+)\]\(([^\)]+#\^ID-(\d{13}))\)/g;
for (let link of this.file_cache.links) {
+ //regex.test(input)
+ if(link.link.includes("#^ID-")){
+ const replacedString = link.original.replace(regex, '[$1|nid$3]');
+ note_text = note_text.replace(new RegExp(c.escapeRegex(link.original), "g"),replacedString)
+ }
+ else{
note_text = note_text.replace(new RegExp(c.escapeRegex(link.original), "g"), '' + link.displayText + " ")
+ }
}
return note_text
}
@@ -144,38 +152,43 @@ export class FormatConverter {
}
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[]
- let inline_code_matches: string[]
- let display_code_matches: string[]
+ // First, isolate display and inline code blocks
+ let math_matches: string[];
+ let inline_code_matches: string[];
+ let display_code_matches: string[];
const add_highlight_css: boolean = note_text.match(c.OBS_DISPLAY_CODE_REGEXP) ? true : false;
- [note_text, math_matches] = this.censor(note_text, ANKI_MATH_REGEXP, MATH_REPLACE);
[note_text, display_code_matches] = this.censor(note_text, c.OBS_DISPLAY_CODE_REGEXP, DISPLAY_CODE_REPLACE);
[note_text, inline_code_matches] = this.censor(note_text, c.OBS_CODE_REGEXP, INLINE_CODE_REPLACE);
+
+ // Process other parts of the text
+ note_text = this.obsidian_to_anki_math(note_text);
+ [note_text, math_matches] = this.censor(note_text, ANKI_MATH_REGEXP, MATH_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.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`$1 `)
- note_text = this.decensor(note_text, DISPLAY_CODE_REPLACE, display_code_matches, false)
- note_text = this.decensor(note_text, INLINE_CODE_REPLACE, inline_code_matches, false)
- note_text = converter.makeHtml(note_text)
- note_text = this.decensor(note_text, MATH_REPLACE, math_matches, true).trim()
- // Remove unnecessary paragraph tag
+ note_text = this.getAndFormatMedias(note_text);
+ note_text = this.formatLinks(note_text);
+ note_text = note_text.replace(HIGHLIGHT_REGEXP, String.raw`$1 `);
+
+ // Restore code blocks
+ note_text = this.decensor(note_text, DISPLAY_CODE_REPLACE, display_code_matches, false);
+ note_text = this.decensor(note_text, INLINE_CODE_REPLACE, inline_code_matches, false);
+
+ // Final conversions
+ note_text = converter.makeHtml(note_text);
+ note_text = this.decensor(note_text, MATH_REPLACE, math_matches, true).trim();
if (note_text.startsWith(PARA_OPEN) && note_text.endsWith(PARA_CLOSE)) {
- note_text = note_text.slice(PARA_OPEN.length, -1 * PARA_CLOSE.length)
+ note_text = note_text.slice(PARA_OPEN.length, -1 * PARA_CLOSE.length);
}
if (add_highlight_css) {
- note_text = ' ' + note_text
+ note_text = ' ' + note_text;
}
- return note_text
+ return note_text.replace(/\\\$/g,"$");
}
+
diff --git a/src/interfaces/settings-interface.ts b/src/interfaces/settings-interface.ts
index dd022b0f..0d6ae05e 100644
--- a/src/interfaces/settings-interface.ts
+++ b/src/interfaces/settings-interface.ts
@@ -27,7 +27,10 @@ export interface PluginSettings {
"CurlyCloze": boolean,
"CurlyCloze - Highlights to Clozes": boolean,
"ID Comments": boolean,
- "Add Obsidian Tags": boolean
+ "Add Obsidian Tags": boolean,
+ "Use Path as Deck" : boolean,
+ "Add Card link": boolean
+
},
IGNORED_FILE_GLOBS:string[]
}
@@ -54,6 +57,8 @@ export interface FileData {
comment: boolean
add_context: boolean
add_obs_tags: boolean
+ use_path_as_deck: boolean
+ add_card_link: boolean
}
export interface ParsedSettings extends FileData {
diff --git a/src/note.ts b/src/note.ts
index 17330c31..c4278247 100644
--- a/src/note.ts
+++ b/src/note.ts
@@ -10,7 +10,7 @@ import { FileData } from './interfaces/settings-interface'
const TAG_PREFIX:string = "Tags: "
export const TAG_SEP:string = " "
-export const ID_REGEXP_STR: string = String.raw`\n?(?: