Skip to content

Instantly share code, notes, and snippets.

@adelin-b
Last active May 3, 2022 05:05
Show Gist options
  • Save adelin-b/362a04fb29dd7ee618952fe2fe5e2417 to your computer and use it in GitHub Desktop.
Save adelin-b/362a04fb29dd7ee618952fe2fe5e2417 to your computer and use it in GitHub Desktop.
A script to convert anki file to org file using anki-connect anki plugin and anki-editor for emacs `deno run --allow-net anki.ts "*"` or `deno run --allow-net anki.ts "Deckname"` or inside emacs evil mode `:read !deno run --allow-net anki.ts "*"` WARNING, currently anki-editor break html by escaping it automaticaly when you push the imported decks
const notesInfo = (results: any[]) => ({
action: "notesInfo",
version: 6,
params: {
notes: results,
},
});
const deckname = Deno.args[0] ?? "*";
const findNotes = {
action: "findNotes",
version: 6,
params: {
query: "deck:" + deckname,
},
};
const notesResponse = await fetch("http://localhost:8765", {
method: "POST",
body: JSON.stringify(findNotes),
});
const notesJson = await notesResponse.json();
const notesInfoResponse = await fetch("http://localhost:8765", {
method: "POST",
body: JSON.stringify(notesInfo(notesJson.result)),
});
interface Note {
noteId: number;
tags: string[];
deck: string;
fields: {
[key: string]: {
value: string;
order: number;
};
};
modelName: string;
cards: number[];
}
const getDeck = async (card: number) => {
return deckLookup[card];
};
const getDeckLookup = async (card: number[]) => {
let lookupDeck: { [key: number]: string } = {};
let i,
j,
chunkedCards,
chunk = 100000000;
for (i = 0, j = card.length; i < j; i += chunk) {
chunkedCards = card.slice(i, i + chunk);
// do whatever
const getDeckQuery = {
action: "getDecks",
version: 6,
params: {
cards: [...chunkedCards],
},
};
const decksResponse = await fetch("http://localhost:8765", {
method: "GET",
body: JSON.stringify(getDeckQuery),
});
const deckJson = await decksResponse.json();
Object.keys(deckJson.result).forEach((deckname) => {
deckJson.result[deckname].forEach(
(card: number) => (lookupDeck[card] = deckname)
);
});
}
return lookupDeck;
};
const notesInfoJson = await notesInfoResponse.json();
const allCards: number[] = [];
const unused = (notesInfoJson.result as Note[]).forEach((note) =>
note.cards.forEach((card) => allCards.push(card))
);
const deckLookup = await getDeckLookup(allCards);
const tagsToOrg = (tags: Note["tags"]) => {
if (tags.length) return `:${tags.join(":")}:`;
};
const tagsToOrgProperty = (tags: Note["tags"]) => {
if (tags.length) return tags.join(" ");
};
const fieldsToOrg = (fields: Note["fields"]) => {
const keys = Object.keys(fields);
const listField = new Array(keys.length);
keys.forEach((key) => {
listField[fields[key].order] = `** ${key}\n${fields[key].value}`;
});
return listField.join("\n");
};
const noteToOrg = async (note: Note) => {
const tags = tagsToOrg(note.tags) ?? "";
const fields = fieldsToOrg(note.fields) ?? "";
const properties = `:PROPERTIES:
:ANKI_DECK: ${await getDeck(note.cards[0])}
:ANKI_NOTE_TYPE: ${note.modelName}
${tags && `:ANKI_TAGS: ${tagsToOrgProperty(note.tags)}`}
:ANKI_NOTE_ID: ${note.noteId}
:END:
`;
return `
* Item ${tags}
${properties}
${fields}
`;
};
for (const note of notesInfoJson.result) {
console.log(await noteToOrg(note));
}
@dcunited001
Copy link

thanks for posting this. it just worked for me on node/typescript.

i created a tsconfig.json for async issues, added a package.json (with type: module) and imported node-fetch. it's been awhile since i've used JS/TS

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment