| 87 | } |
| 88 | |
| 89 | function extractRefs(content) { |
| 90 | // 去除 ``` 代码块和 ` 行内代码,避免误报 |
| 91 | const stripped = content |
| 92 | .replace(/```[\s\S]*?```/g, '') |
| 93 | .replace(/`[^`\n]*`/g, ''); |
| 94 | |
| 95 | const refs = []; |
| 96 | const push = (url, type, index) => { |
| 97 | if (typeof url === 'string' && url.length > 0) refs.push({ url, type, index }); |
| 98 | }; |
| 99 | |
| 100 | const imgRe = /!\[[^\]]*\]\(\s*<?([^)\s>]+)>?(?:\s+"[^"]*")?\s*\)/g; |
| 101 | const linkRe = /(^|[^!])\[(?:[^\]]*?)\]\(\s*<?([^)\s>]+)>?(?:\s+"[^"]*")?\s*\)/g; |
| 102 | const attrRe = /\b(?:src|href|to)\s*=\s*(?:"([^"]+)"|'([^']+)'|\{\s*["']([^"']+)["']\s*\})/g; |
| 103 | |
| 104 | let m; |
| 105 | while ((m = imgRe.exec(stripped))) push(m[1], 'image', m.index); |
| 106 | while ((m = linkRe.exec(stripped))) push(m[2], 'link', m.index); |
| 107 | while ((m = attrRe.exec(stripped))) push(m[1] || m[2] || m[3], 'attr', m.index); |
| 108 | |
| 109 | return refs; |
| 110 | } |
| 111 | |
| 112 | function lineOf(content, index) { |
| 113 | return content.slice(0, index).split('\n').length; |