0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2026-06-27 08:28:40 +00:00

repair injection highlight and add image previews

This commit is contained in:
Víctor Losada Hernández
2026-04-24 12:34:16 +02:00
parent cb4bc16c69
commit 0587266e22
3 changed files with 134 additions and 14 deletions
+91 -11
View File
@@ -38,15 +38,30 @@ const themes = { default: defaultCM5Theme, ...cm5Themes, darkbrewery };
const themeCompartment = new Compartment(); const themeCompartment = new Compartment();
const highlightCompartment = new Compartment(); const highlightCompartment = new Compartment();
console.log(themes);
import { generalKeymap, markdownKeymap } from './extensions/customKeyMaps.js'; import { generalKeymap, markdownKeymap } from './extensions/customKeyMaps.js';
import foldOnPages from './extensions/customFolding.js'; import foldOnPages from './extensions/customFolding.js';
import { customHighlightStyle, tokenizeCustomMarkdown, tokenizeCustomCSS } from './extensions/customHighlight.js'; import { customHighlightStyle, tokenizeCustomMarkdown, tokenizeCustomCSS } from './extensions/customHighlight.js';
import { legacyCustomHighlightStyle, legacyTokenizeCustomMarkdown } from './extensions/legacyCustomHighlight.js'; import { legacyCustomHighlightStyle, legacyTokenizeCustomMarkdown } from './extensions/legacyCustomHighlight.js';
import { syntaxTree } from '@codemirror/language';
const PAGEBREAK_REGEX_V3 = /^(?=\\page(?:break)?(?: *{[^\n{}]*})?$)/m; const PAGEBREAK_REGEX_V3 = /^(?=\\page(?:break)?(?: *{[^\n{}]*})?$)/m;
function getUrl(node, doc) {
let url = null;
const cursor = node.node.cursor();
if (cursor.firstChild()) {
do {
if (cursor.name === "URL") {
url = doc.sliceString(cursor.from, cursor.to);
break;
}
} while (cursor.nextSibling());
}
return url;
}
const createHighlightPlugin = (renderer, tab)=>{ const createHighlightPlugin = (renderer, tab)=>{
//this function takes the custom tokens created in the tokenize function in customhighlight files //this function takes the custom tokens created in the tokenize function in customhighlight files
//takes the tokens defined by that function and assigns classes to them //takes the tokens defined by that function and assigns classes to them
@@ -76,21 +91,84 @@ const createHighlightPlugin = (renderer, tab)=>{
let pageCount = 1; let pageCount = 1;
let snippetCount = 0; let snippetCount = 0;
const tree = syntaxTree(view.state);
tree.iterate({
enter: (node) => {
if (node.name === "Image") {
const url = getUrl(node, view.state.doc);
if (!url) return;
decos.push(
Decoration.mark({
class: "cm-image",
attributes: {
"style": `--preview-img:url(${url});`
}
}).range(node.from, node.to)
);
}
}
});
tokens.forEach((tok)=>{ tokens.forEach((tok)=>{
const line = view.state.doc.line(tok.line + 1); const line = view.state.doc.line(tok.line + 1);
// INLINE TOKENS (marks)
if(tok.from != null && tok.to != null && tok.from < tok.to) { if(tok.from != null && tok.to != null && tok.from < tok.to) {
decos.push(Decoration.mark({ class: `cm-${tok.type}` }).range(line.from + tok.from, line.from + tok.to)); const from = line.from + tok.from;
} else { const to = line.from + tok.to;
decos.push(Decoration.line({ class: `cm-${tok.type}` }).range(line.from));
if(tok.type === 'pageLine' && tab === 'brewText') { const attrs = {};
pageCount++; console.log(tok);
line.from === 0 && pageCount--; // attach URL only for links
decos.push(Decoration.line({ attributes: { 'data-page-number': pageCount } }).range(line.from)); if(tok.type === 'Image' && tok.url) {
attrs['data-url'] = tok.url;
} }
decos.push(
Decoration.mark({
class : `cm-${tok.type}`,
...(Object.keys(attrs).length
? { attributes: attrs }
: {})
}).range(from, to)
);
}
// LINE TOKENS
else {
decos.push(
Decoration.line({
class : `cm-${tok.type}`
}).range(line.from)
);
if(tok.type === 'pageLine' && tab === 'brewText') {
pageCount++;
if(line.from === 0) pageCount--;
decos.push(
Decoration.line({
attributes : {
'data-page-number' : pageCount
}
}).range(line.from)
);
}
if(tok.type === 'snippetLine' && tab === 'brewSnippets') { if(tok.type === 'snippetLine' && tab === 'brewSnippets') {
snippetCount++; snippetCount++;
decos.push(Decoration.line({ attributes: { 'data-page-number': snippetCount } }).range(line.from));
decos.push(
Decoration.line({
attributes : {
'data-page-number' : snippetCount
}
}).range(line.from)
);
} }
} }
}); });
@@ -99,7 +177,9 @@ const createHighlightPlugin = (renderer, tab)=>{
return Decoration.set(decos); return Decoration.set(decos);
} }
}, },
{ decorations: (v)=>v.decorations } {
decorations : (v)=>v.decorations
}
); );
}; };
@@ -157,6 +157,44 @@
outline : 1px inset #00000055 !important; outline : 1px inset #00000055 !important;
} }
.cm-image[style] {
position: relative;
&::before, &::after {
content:"";
width:100px;
height:100px;
position:absolute;
bottom:0;
left:0;
translate:0 100%;
display:block;
z-index:1000;
pointer-events: none;
opacity:0;
transition:0.2s opacity;
}
&::before{
background-color: #fff;
border-radius:10px;
border:3px solid grey;
}
&::after {
background-image: var(--preview-img);
background-size:80%;
background-repeat:no-repeat;
background-position:center;
filter:drop-shadow(0 0 5px #0008);
}
&:hover::before,
&:hover::after {
opacity:1;
}
}
/* Tab character visualization (optional) */ /* Tab character visualization (optional) */
//.cm-tab { //.cm-tab {
// background: url(...) no-repeat right; // background: url(...) no-repeat right;
@@ -182,13 +182,15 @@ export function tokenizeCustomMarkdown(text) {
} }
if(lineText.includes('{') && lineText.includes('}')) { if(lineText.includes('{') && lineText.includes('}')) {
const injectionRegex = /(?:^|[^{\n])({(?=((?:[:=](?:"[\w,\-()#%. ]*"|[\w\-()#%.]*)|[^"':={}\s]*)*))\2})/gm; const injectionRegex = /(?:^|[^{\n])({(?=((?:[:=](?:"[\w,\-()#%. ]*"|[\w\-()#%.]*)|[^"':={}\s]*)*))\2})/gmd;
let match; let match;
while ((match = injectionRegex.exec(lineText)) !== null) { while ((match = injectionRegex.exec(lineText)) !== null) {
console.log(match.indices[1][0]);
tokens.push({ tokens.push({
line : lineNumber, line : lineNumber,
from : match.index, from : match.indices[1][0],
to : match.index + match[1].length, to : match.indices[1][0] + match[1].length,
type : customTags.injection, type : customTags.injection,
}); });
} }