html 요소의 속성에 원본 텍스트를 저장해 두고, addTagDecorateCallback() 콜백 함수에서 해당 값을 반환하도록 하여 원본 텍스트를 가져오게 함으로써 문제를 해결할 수 있었습니다.
제가 어떤 방식으로 처리했는지 궁금한 분들을 위해 코드를 일부 공유합니다.
assets/javascripts/lib/discourse-markdown/snapblocks-discourse.js 파일에서 bbcode 태그를 초기화하는 부분에서, 나중에 이를 가져올 수 있도록 원본 텍스트를 snapblocks-source 속성에 저장하도록 수정했습니다.
assets\javascripts\discourse\initializers\snapblocks-discourse.js 파일에서는 인용(quoting)을 처리하는 코드를 추가했습니다.
// assets\javascripts\discourse\initializers\snapblocks-discourse.js
import {
addBlockDecorateCallback, // 블록 bbcode 태그
addTagDecorateCallback, // 인라인 bbcode 태그
} from "discourse/lib/to-markdown";
function initializeSnapblocks(api, siteSettings) {
addTagDecorateCallback(function () {
// this.element은 HTML 요소가 아닙니다.
// 하지만 모든 html 속성을 포함하고 있습니다.
const { attributes } = this.element;
// 일반적으로 "class"가 자신의 클래스인지 확인해야 하지만,
// 여기서는 "snapblocks-source"만 필요합니다.
if (attributes["snapblocks-source"]) {
let prefix = "[sb";
// bbcode 태그에 속성을 추가합니다. (이 속성들은 요소의 속성으로도 저장됩니다.)
const attrs = [
"blockstyle",
"wrap",
"wrapsize",
"zebra",
"showspaces",
"santa",
];
for (const attr of attrs) {
if (attributes[attr]) {
prefix += ` ${attr}=${attributes[attr]}`;
}
}
prefix += "]";
this.prefix = prefix;
this.suffix = "[/sb]";
// 텍스트를 반환하면, 선택된 텍스트 대신 이 값이 사용됩니다.
return attributes["snapblocks-source"];
}
});
}
블록 bbcode 태그의 경우에도 동일한 방식이며, addBlockDecorateCallback()을 사용하도록 변경하면 됩니다.
불행히도 이전 snapblocks 스니펫을 인용할 수 있도록 하려면 게시물을 다시 재처리(rebake)해야 합니다. 또한 svg 위의 텍스트를 선택하는 경우는 처리하지 않으며, svg 텍스트 앞뒤로 일부 텍스트를 함께 선택하고 svg 텍스트의 일부도 선택해야만 작동합니다.