bak
This commit is contained in:
1 parent
e85b5203cd
commit
0d4d369870
19 files changed
+2258
-1814
No files matched your search
@@ -0,0 +1,62 @@
|
||||
// ── Markdown rendering ──
|
||||
|
||||
import { esc } from './util.js';
|
||||
import { state } from './state.js';
|
||||
|
||||
marked.use({ breaks: true, gfm: true });
|
||||
|
||||
const purifyConfig = {
|
||||
ALLOWED_TAGS: ['h1','h2','h3','h4','h5','h6','p','br','hr','ul','ol','li','a','strong','em','del','code','pre','blockquote','table','thead','tbody','tr','th','td','img','input','span','div'],
|
||||
ALLOWED_ATTR: ['href','src','alt','width','height','type','checked','disabled','class','style','data-card-id','title'],
|
||||
ALLOW_DATA_ATTR: true,
|
||||
};
|
||||
|
||||
export function renderMd(src) {
|
||||
const linked = (src || '').replace(/\[\[([^\]]+)\]\]/g, (_, title) => {
|
||||
const card = state.cards.find(c => c.title.toLowerCase() === title.toLowerCase());
|
||||
if (card) return `<span class="card-link" data-card-id="${card.id}">${esc(title)}</span>`;
|
||||
return `<span class="card-link broken" title="card not found">${esc(title)}</span>`;
|
||||
});
|
||||
const raw = marked.parse(linked);
|
||||
return typeof DOMPurify !== 'undefined' ? DOMPurify.sanitize(raw, purifyConfig) : raw;
|
||||
}
|
||||
|
||||
export function stripMd(src) {
|
||||
return (src || '')
|
||||
.replace(/<img[^>]*>/gi, '')
|
||||
.replace(/<[^>]+>/g, '')
|
||||
.replace(/!\[[^\]]*\]\([^)]*\)/g, '')
|
||||
.replace(/\[\[([^\]]+)\]\]/g, '$1')
|
||||
.replace(/^#{1,6}\s+/gm, '')
|
||||
.replace(/(\*{1,3}|_{1,3}|~~)(.*?)\1/g, '$2')
|
||||
.replace(/\[([^\]]*)\]\([^)]*\)/g, '$1')
|
||||
.replace(/`{1,3}[^`]*`{1,3}/g, '')
|
||||
.replace(/^[-*>]\s+/gm, '')
|
||||
.replace(/^\d+\.\s+/gm, '')
|
||||
.replace(/\n{2,}/g, '\n')
|
||||
.trim();
|
||||
}
|
||||
|
||||
export function getTodos(src) {
|
||||
const s = src || '';
|
||||
const total = (s.match(/- \[([ x])\]/g) || []).length;
|
||||
if (!total) return null;
|
||||
return { total, done: (s.match(/- \[x\]/g) || []).length };
|
||||
}
|
||||
|
||||
export function firstImage(src) {
|
||||
const s = src || '';
|
||||
const md = s.match(/!\[[^\]]*\]\(([^)]+)\)/);
|
||||
if (md) return md[1];
|
||||
const html = s.match(/<img[^>]+src="([^"]+)"/i);
|
||||
return html ? html[1] : null;
|
||||
}
|
||||
|
||||
export function leadingImage(src) {
|
||||
const s = (src || '').trimStart();
|
||||
if (!s) return null;
|
||||
const md = s.match(/^!\[[^\]]*\]\(([^)]+)\)/);
|
||||
if (md) return md[1].split(/\s+/)[0].replace(/^<(.+)>$/, '$1') || null;
|
||||
const html = s.match(/^<img[^>]+src=(['"])(.*?)\1/i);
|
||||
return html ? html[2] : null;
|
||||
}
|
||||
Reference in new issue
Block a user