/**
|
|
* Query syntax is documented here.
|
|
*
|
|
* @link https://docs.ankiweb.net/searching.html
|
|
*/
|
|
export type IAnkiQuery = string;
|
|
|
|
export interface IAnkiCard {
|
|
sortf: number;
|
|
did: number;
|
|
latexPre: string;
|
|
latexPost: string;
|
|
mod: number;
|
|
usn: number;
|
|
vers: number[];
|
|
type: number;
|
|
css: string;
|
|
name: string;
|
|
flds: IAnkiField[];
|
|
tmpls: IAnkiTemplate[];
|
|
tags: string[];
|
|
id: number | string;
|
|
req: unknown[];
|
|
}
|
|
|
|
export interface IAnkiField {
|
|
name: string;
|
|
ord: number;
|
|
sticky: boolean;
|
|
rtl: boolean;
|
|
font: string;
|
|
size: number;
|
|
media: unknown[];
|
|
}
|
|
|
|
export interface IAnkiTemplate {
|
|
name: string;
|
|
ord: number;
|
|
qfmt: string;
|
|
afmt: string;
|
|
did: number | null;
|
|
bqfmt: string;
|
|
bamt: string;
|
|
}
|
|
|
|
export interface IAnkiDeckConfig {
|
|
id: number;
|
|
}
|
|
|
|
export const soundTag = {
|
|
pre: '[sound:',
|
|
post: ']',
|
|
is(src: string) {
|
|
return src.startsWith(this.pre) && src.endsWith(this.post);
|
|
},
|
|
make(src: string) {
|
|
if (this.is(src)) return src;
|
|
const out = this.pre + src + this.post;
|
|
if (this.isBroken(out)) return src;
|
|
return out;
|
|
},
|
|
clean(src: string) {
|
|
if (this.isBroken(src)) return src;
|
|
if (this.isEmpty(src)) return src;
|
|
return src.substring(this.pre.length, src.length - this.post.length);
|
|
},
|
|
isEmpty(src: string) {
|
|
return src === this.pre + this.post;
|
|
},
|
|
isBroken(src: string) {
|
|
if (this.is(src)) {
|
|
return (
|
|
src.indexOf(this.pre) > 0 ||
|
|
src.indexOf(this.post) < src.length - this.post.length
|
|
);
|
|
}
|
|
|
|
return false;
|
|
},
|
|
};
|