@traptitech/traq-markdown-it
Advanced tools
Comparing version 2.2.7 to 2.3.0
@@ -1,1 +0,1 @@ | ||
export declare const createHighlightFunc: (preClass: string, withCaption?: boolean) => (code: string, lang: string) => string; | ||
export declare const createHighlightFunc: (preClass: string, withCaption?: boolean, useSubsetForAuto?: boolean) => (code: string, lang: string) => string; |
@@ -9,10 +9,16 @@ /// <reference types="../src/types/markdown-it-mark" /> | ||
import { Store } from './Store'; | ||
import { EmbeddingsExtractedMessage } from './embeddingExtractor'; | ||
export { Store } from './Store'; | ||
export { Embedding, EmbeddingFile, EmbeddingMessage, EmbeddingsExtractedMessage } from './embeddingExtractor'; | ||
export declare type MarkdownRenderResult = EmbeddingsExtractedMessage & { | ||
renderedText: string; | ||
}; | ||
export default class { | ||
readonly md: MarkdownIt; | ||
constructor(store: Store, whitelist?: string[]); | ||
readonly embeddingRegExp: RegExp; | ||
constructor(store: Store, whitelist: string[] | undefined, embeddingOrigin: string); | ||
setPlugin(store: Store, whitelist: string[]): void; | ||
setRendererRule(): void; | ||
render(text: string): string; | ||
renderInline(text: string): string; | ||
render(text: string): MarkdownRenderResult; | ||
renderInline(text: string): MarkdownRenderResult; | ||
} | ||
@@ -19,0 +25,0 @@ export { createHighlightFunc } from './highlight'; |
@@ -472,4 +472,6 @@ 'use strict'; | ||
var defaultSubset = ['actionscript', 'awk', 'bash', 'basic', 'bnf', 'brainfuck', 'csharp', 'h', 'cpp', 'cmake', 'coq', 'css', 'clojure', 'coffeescript', 'crystal', 'd', 'dart', 'delphi', 'diff', 'django', 'dockerfile', 'elixir', 'elm', 'fsharp', 'fortran', 'go', 'gradle', 'groovy', 'xml', 'http', 'haml', 'handlebars', 'haxe', 'ini', 'json', 'java', 'javascript', 'kotlin', 'tex', 'less', 'lisp', 'livescript', 'lua', 'makefile', 'markdown', 'mathematica', 'matlab', 'moonscript', 'nginx', 'nimrod', 'ocaml', 'objectivec', 'glsl', 'php', 'perl', 'plaintext', 'pgsql', 'powershell', 'processing', 'prolog', 'protobuf', 'python', 'k', 'r', 'ruby', 'scss', 'sql', 'scheme', 'shell', 'stylus', 'swift', 'twig', 'typescript', 'vbnet', 'vbscript', 'verilog', 'vim', 'x86asm', 'xquery', 'yaml', 'zephir']; | ||
const noHighlightRe = /^(no-?highlight|plain|text)$/i; | ||
const createHighlightFunc = (preClass, withCaption = true) => (code, lang) => { | ||
const createHighlightFunc = (preClass, withCaption = true, useSubsetForAuto = true) => (code, lang) => { | ||
let langName, langCaption; | ||
@@ -494,3 +496,3 @@ let citeTag = ''; | ||
} else { | ||
const result = hljs.highlightAuto(code); | ||
const result = hljs.highlightAuto(code, useSubsetForAuto ? defaultSubset : undefined); | ||
return `<pre class="${preClass}">${citeTag}<code class="lang-${result.language}">${result.value}</code></pre>`; | ||
@@ -502,2 +504,122 @@ } | ||
const createEmbeddingRegexp = embeddingOrigin => RegExp(`${embeddingOrigin}/(files|messages)/([\\da-f]{8}-[\\da-f]{4}-[\\da-f]{4}-[\\da-f]{4}-[\\da-f]{12})(\\s*)`, 'g'); | ||
/** | ||
* markdownから埋め込みURLを抽出する | ||
* | ||
* @param regexp | ||
* マッチに使う正規表現。グループは順に | ||
* | ||
* - 種別 | ||
* - UUID | ||
* - 削除されるスペース | ||
* | ||
* であることを期待する | ||
*/ | ||
const embeddingExtractor = (rawMessage, regexp) => { | ||
const embeddings = []; | ||
const knownIdSet = new Set(); | ||
const matches = rawMessage.matchAll(regexp); | ||
/** 連続したマッチの開始インデックス */ | ||
let sequenceStartIndex = 0; | ||
/** スペースを含んだ、連続したマッチ全体の終了インデックス */ | ||
let sequenceEndIndex = 0; | ||
for (const match of matches) { | ||
var _match$index, _match$0$length, _match$, _match$3$length, _match$2, _match$3, _match$4; | ||
const matchIndex = (_match$index = match.index) !== null && _match$index !== void 0 ? _match$index : 0; | ||
const matchLength = (_match$0$length = (_match$ = match[0]) === null || _match$ === void 0 ? void 0 : _match$.length) !== null && _match$0$length !== void 0 ? _match$0$length : 0; | ||
const spaceLength = (_match$3$length = (_match$2 = match[3]) === null || _match$2 === void 0 ? void 0 : _match$2.length) !== null && _match$3$length !== void 0 ? _match$3$length : 0; | ||
const type = (_match$3 = match[1]) !== null && _match$3 !== void 0 ? _match$3 : ''; | ||
const id = (_match$4 = match[2]) !== null && _match$4 !== void 0 ? _match$4 : ''; | ||
const startIndex = matchIndex; | ||
const endIndex = matchIndex + matchLength - spaceLength; | ||
if (!knownIdSet.has(id)) { | ||
if (type === 'files') { | ||
embeddings.push({ | ||
type: 'file', | ||
id, | ||
startIndex, | ||
endIndex | ||
}); | ||
} | ||
if (type === 'messages') { | ||
embeddings.push({ | ||
type: 'message', | ||
id, | ||
startIndex, | ||
endIndex | ||
}); | ||
} | ||
knownIdSet.add(id); | ||
} | ||
if (startIndex !== sequenceEndIndex) { | ||
// 連続したマッチではなかった | ||
sequenceStartIndex = startIndex; | ||
} | ||
sequenceEndIndex = matchIndex + matchLength; | ||
} | ||
const hasSequenceReachedEos = sequenceEndIndex === rawMessage.length; | ||
return { | ||
rawText: rawMessage, | ||
text: hasSequenceReachedEos ? rawMessage.substring(0, sequenceStartIndex) : rawMessage, | ||
embeddings | ||
}; | ||
}; | ||
/** | ||
* markdownから埋め込みURLを抽出してすべて置換する | ||
* | ||
* @param regexp | ||
* マッチに使う正規表現。グループは順に | ||
* | ||
* - 種別 | ||
* - UUID | ||
* - 削除されるスペース | ||
* | ||
* であることを期待する | ||
*/ | ||
const embeddingReplacer = (rawMessage, regexp) => { | ||
const { | ||
text, | ||
embeddings | ||
} = embeddingExtractor(rawMessage, regexp); | ||
let newText = text; // 置換で文字数がずれるのでずれた数を保持する | ||
let placeDiff = 0; | ||
for (const embedding of embeddings) { | ||
// 末尾のものは抽出で消えているので置換しない | ||
if (text.length <= embedding.startIndex) break; | ||
let replaced; | ||
if (embedding.type === 'file') { | ||
replaced = '[[添付ファイル]]'; | ||
} else if (embedding.type === 'message') { | ||
replaced = '[[添付メッセージ]]'; | ||
} else { | ||
const invalid = embedding; | ||
throw new Error(`embeddingReplacer unknown embedding type: ${invalid}`); | ||
} | ||
newText = newText.slice(0, placeDiff + embedding.startIndex) + replaced + newText.slice(placeDiff + embedding.endIndex); | ||
placeDiff += replaced.length - (embedding.endIndex - embedding.startIndex); | ||
} | ||
return { | ||
rawText: rawMessage, | ||
text: newText, | ||
embeddings | ||
}; | ||
}; | ||
const defaultLabels = ['success', 'info', 'warning', 'danger']; | ||
@@ -518,3 +640,3 @@ const useContainer = (md, labels = defaultLabels) => { | ||
class index { | ||
constructor(store, whitelist = defaultWhitelist) { | ||
constructor(store, whitelist = defaultWhitelist, embeddingOrigin) { | ||
this.md = new MarkdownIt({ | ||
@@ -525,2 +647,3 @@ breaks: true, | ||
}); | ||
this.embeddingRegExp = createEmbeddingRegexp(embeddingOrigin); | ||
this.setRendererRule(); | ||
@@ -548,6 +671,3 @@ this.setPlugin(store, whitelist); | ||
setRendererRule() { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const blockState = this.md.block.State; | ||
blockState.prototype.skipEmptyLines = function skipEmptyLines(from) { | ||
this.md.block.State.prototype.skipEmptyLines = function skipEmptyLines(from) { | ||
for (let max = this.lineMax; from < max; from++) { | ||
@@ -566,7 +686,11 @@ if (this.bMarks[from] + this.tShift[from] < this.eMarks[from]) { | ||
render(text) { | ||
return this.md.render(text, {}); | ||
const data = embeddingExtractor(text, this.embeddingRegExp); | ||
return { ...data, | ||
renderedText: this.md.render(data.text, {}) | ||
}; | ||
} | ||
renderInline(text) { | ||
const parsed = this.md.parseInline(text, {}); | ||
const data = embeddingReplacer(text, this.embeddingRegExp); | ||
const parsed = this.md.parseInline(data.text, {}); | ||
const tokens = parsed[0].children || []; | ||
@@ -591,3 +715,5 @@ const rendered = []; | ||
return rendered.join(''); | ||
return { ...data, | ||
renderedText: rendered.join('') | ||
}; | ||
} | ||
@@ -594,0 +720,0 @@ |
@@ -1,2 +0,2 @@ | ||
"use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e.default:e}Object.defineProperty(exports,"__esModule",{value:!0}),require("core-js/modules/web.dom-collections.iterator");var t=e(require("markdown-it")),r=e(require("markdown-it-mark")),n=e(require("@traptitech/markdown-it-spoiler")),s=e(require("markdown-it-regexp"));require("core-js/modules/es.string.replace");var o=e(require("markdown-it-json")),i=e(require("@traptitech/markdown-it-katex")),a=e(require("katex")),u=e(require("markdown-it-link-attributes")),l=e(require("markdown-it-image-filter")),c=e(require("highlight.js")),p=e(require("markdown-it-container"));function h(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&g(e,t)}function f(e){return(f=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function g(e,t){return(g=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function d(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}function m(e,t,r){return(m=d()?Reflect.construct:function(e,t,r){var n=[null];n.push.apply(n,t);var s=new(Function.bind.apply(e,n));return r&&g(s,r.prototype),s}).apply(null,arguments)}function y(e){var t="function"==typeof Map?new Map:void 0;return(y=function(e){if(null===e||-1===Function.toString.call(e).indexOf("[native code]"))return e;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,r)}function r(){return m(e,arguments,f(this).constructor)}return r.prototype=Object.create(e.prototype,{constructor:{value:r,enumerable:!1,writable:!0,configurable:!0}}),g(r,e)})(e)}function x(e,t){x=function(e,t){return new o(e,void 0,t)};var r=y(RegExp),n=RegExp.prototype,s=new WeakMap;function o(e,t,n){var o=r.call(this,e,t);return s.set(o,n||s.get(e)),o}function i(e,t){var r=s.get(t);return Object.keys(r).reduce((function(t,n){return t[n]=e[r[n]],t}),Object.create(null))}return h(o,r),o.prototype.exec=function(e){var t=n.exec.call(this,e);return t&&(t.groups=i(t,this)),t},o.prototype[Symbol.replace]=function(e,t){if("string"==typeof t){var r=s.get(this);return n[Symbol.replace].call(this,e,t.replace(/\$<([^>]+)>/g,(function(e,t){return"$"+r[t]})))}if("function"==typeof t){var o=this;return n[Symbol.replace].call(this,e,(function(){var e=[];return e.push.apply(e,arguments),"object"!=typeof e[e.length-1]&&e.push(i(e,o)),t.apply(this,e)}))}return n[Symbol.replace].call(this,e,t)},x.apply(this,arguments)}const k=/[&<>"]/g,_=new Map([["&","&"],["<","<"],[">",">"],['"',"""]]),v=e=>_.get(e),w=e=>k.test(e)?e.replace(k,v):e;let b,$="";const q=new Set(["rotate","rotate-inv","wiggle","parrot","zoom","inversion","turn","turn-v","happa","pyon","flashy","pull","atsumori","stretch","stretch-v","conga","conga-inv","marquee","marquee-inv","rainbow"]),j=new Set(["ex-large","large","small"]),F=new Map([["marquee","conga"],["marquee-inv","conga-inv"]]),M=(e,t,r,n,s)=>{const o=w(r),i=w(n),a=w(t),u=s.filter(e=>j.has(e)),l=s.filter(e=>q.has(e));if(u.length+l.length<s.length)return e;if(l.length>5)return e;const c=l.map(e=>F.has(e)?F.get(e):e),p=u[u.length-1]||"";return((e,t,r)=>t.map((e,t)=>`<span class="emoji-effect ${e}${0===t&&r?" "+r:""}">`).join("")+e+"</span>".repeat(t.length))(`<i class="emoji s24 message-emoji ${p}" title=":${o}:" style="${i};">:${a}:</i>`,c,p)},O=(e,t,r,n,s)=>M(e,t,r,`background-image: url(${n})`,s),P=/[a-zA-Z0-9+_-]{1,32}/,S=x(/(hsl\([0-9]+,[\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]*[0-9]+(?:\.[0-9]+)?%,[\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]*[0-9]+(?:\.[0-9]+)?%\))(.*)/,{color:1,effects:2}),R=x(/0x([0-9A-Fa-f]{6})(.*)/,{color:1,effects:2}),A=e=>{const{inner:t}={inner:e[1]},r=R.exec(t);if(r)return(e=>{const{color:t,effects:r}=e.groups;return M(`:${e[0]}:`,"0x"+t,"0x"+t,"background-color: #"+t,""===r?[]:r.split(".").slice(1))})(r);const n=S.exec(t);if(n)return(e=>{const{color:t,effects:r}=e.groups;return M(`:${e[0]}:`,t,t,"background-color: "+t,""===r?[]:r.split(".").slice(1))})(n);if(!P.exec(t))return e[0];const[s,...o]=t.split(".");if(s.startsWith("@")){const t=b.getUserByName(s.slice(1));return t?O(e[0],s,s,`${$}/api/v3/files/${t.iconFileId}`,o):e[0]}const i=b.getStampByName(s);return i?O(e[0],s,i.name,`${$}/api/v3/files/${i.fileId}`,o):e[0]},E=/:((?:@?[a-zA-Z0-9+_-]{1,32}|\w+\([^:<>"'=+!?]+\))[\w+-.]*):/;function C(e,t,r){b=t,r&&($=r),s(E,A)(e)}let I;const z=e=>{if(!(e=>"string"==typeof e.type&&"string"==typeof e.raw&&"string"==typeof e.id)(e))return!1;const{type:t,id:r}=e;return"user"===t||"channel"===t&&!!I.getChannel(r)||"group"===t||"file"===t||"message"===t},T=(e,t)=>{"user"!==t.type?"channel"===t.type&&I.getChannel(t.id)?((e,{type:t,id:r,raw:n})=>{const s=[];s.push(["href",`javascript:changeChannel('${I.getChannelPath(r)}')`]),s.push(["class","message-channel-link"]);let o=e.push("traq_extends_link_open","a",1);o.attrs=s,o.meta={type:t,data:n},o=e.push("text","",0),o.content=n,e.push("traq_extends_link_close","a",-1)})(e,t):"group"!==t.type?"file"!==t.type?(e.push("traq_extends_plain_open","a",1),e.push("text","",0).content=t.raw,e.push("traq_extends_plain_close","a",-1)):((e,{type:t,id:r,raw:n})=>{let s=e.push("traq_extends_link_open","a",1);s.attrs=[["href","/api/v3/files/"+r],["download",r]],s.meta={type:t,data:r},s=e.push("text","",0),s.content=n,e.push("traq_extends_link_close","a",-1)})(e,t):((e,{type:t,id:r,raw:n})=>{var s,o;const i=[],a=I.getUserGroup(r),u=I.getMe();i.push(["href",`javascript:openGroupModal('${r}')`]),null!==(s=null==a||null===(o=a.members)||void 0===o?void 0:o.some(e=>e.id===(null==u?void 0:u.id)))&&void 0!==s&&s?i.push(["class","message-group-link-highlight message-group-link"]):i.push(["class","message-group-link"]);let l=e.push("traq_extends_link_open","a",1);l.attrs=i,l.meta={type:t,data:r},l=e.push("text","",0),l.content=n,e.push("traq_extends_link_close","a",-1)})(e,t):((e,{type:t,id:r,raw:n})=>{const s=[],o=I.getMe();s.push(["href",`javascript:openUserModal('${r}')`]),s.push(r===(null==o?void 0:o.id)?["class","message-user-link-highlight message-user-link"]:["class","message-user-link"]);let i=e.push("traq_extends_link_open","a",1);i.attrs=s,i.meta={type:t,data:r},i=e.push("text","",0),i.content=n,e.push("traq_extends_link_close","a",-1)})(e,t)};function U(e,t){I=t,o(z,T)(e)}const W=/^(no-?highlight|plain|text)$/i,B=(e,t=!0)=>(r,n)=>{let s,o,i="";if(t?([s,o]=n.split(":"),o&&(i=`<cite>${w(o)}</cite>`)):s=n,c.getLanguage(s)){const t=c.highlight(s,r);return`<pre class="${e}">${i}<code class="lang-${t.language}">${t.value}</code></pre>`}if(W.test(s))return`<pre class="${e}">${i}<code>${w(r)}</code></pre>`;{const t=c.highlightAuto(r);return`<pre class="${e}">${i}<code class="lang-${t.language}">${t.value}</code></pre>`}};var D=["libra.tokyotech.org","user-images.githubusercontent.com","git.trap.jp","wiki.trapti.tech","wiki.trap.jp","md.trapti.tech","md.trap.jp","trap.jp","traq-dev.tokyotech.org"];const G=["success","info","warning","danger"],H=r,L=n,N=C,Z=U,J=i;exports.createHighlightFunc=B,exports.default=class{constructor(e,r=D){this.md=new t({breaks:!0,linkify:!0,highlight:B("traq-code traq-lang")}),this.setRendererRule(),this.setPlugin(e,r)}setPlugin(e,t){this.md.use(r).use(n,!0).use(U,e).use(C,e).use(i,{katex:a,output:"html",strict:e=>"unicodeTextInMathMode"===e?"ignore":"warn",maxSize:100,blockClass:"is-scroll"}).use(u,{attrs:{target:"_blank",rel:"nofollow noopener noreferrer"}}).use(l(t,{httpsOnly:!0}))}setRendererRule(){this.md.block.State.prototype.skipEmptyLines=function(e){for(let t=this.lineMax;e<t&&!(this.bMarks[e]+this.tShift[e]<this.eMarks[e]);e++)this.push("hardbreak","br",0);return e}}render(e){return this.md.render(e,{})}renderInline(e){const t=this.md.parseInline(e,{})[0].children||[],r=[];for(const e of t)r.push("regexp-0"===e.type?A(e.meta.match):"spoiler_open"===e.type?'<span class="spoiler">':"spoiler_close"===e.type?"</span>":"softbreak"===e.type?" ":this.md.utils.escapeHtml(e.content));return r.join("")}},exports.jsonPlugin=Z,exports.katexPlugin=J,exports.markPlugin=H,exports.spoilerPlugin=L,exports.stampCssPlugin=(e,t)=>{s(/:([\w-_]+?)[:;]/,([e,r])=>t.includes(r)?`<i class="emoji s${e.endsWith(":")?32:16} e_${r.replace(/\+/g,"_-plus-_")}" title="${e}">${e}</i>`:e)(e)},exports.stampPlugin=N,exports.useContainer=(e,t=G)=>{t.forEach(t=>{e.use(p,t)})}; | ||
"use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e.default:e}Object.defineProperty(exports,"__esModule",{value:!0}),require("core-js/modules/web.dom-collections.iterator");var t=e(require("markdown-it")),r=e(require("markdown-it-mark")),n=e(require("@traptitech/markdown-it-spoiler")),s=e(require("markdown-it-regexp"));require("core-js/modules/es.string.replace");var i=e(require("markdown-it-json")),o=e(require("@traptitech/markdown-it-katex")),a=e(require("katex")),l=e(require("markdown-it-link-attributes")),u=e(require("markdown-it-image-filter")),c=e(require("highlight.js")),p=e(require("markdown-it-container"));function d(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&g(e,t)}function h(e){return(h=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function g(e,t){return(g=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function f(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}function m(e,t,r){return(m=f()?Reflect.construct:function(e,t,r){var n=[null];n.push.apply(n,t);var s=new(Function.bind.apply(e,n));return r&&g(s,r.prototype),s}).apply(null,arguments)}function x(e){var t="function"==typeof Map?new Map:void 0;return(x=function(e){if(null===e||-1===Function.toString.call(e).indexOf("[native code]"))return e;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,r)}function r(){return m(e,arguments,h(this).constructor)}return r.prototype=Object.create(e.prototype,{constructor:{value:r,enumerable:!1,writable:!0,configurable:!0}}),g(r,e)})(e)}function y(e,t){y=function(e,t){return new i(e,void 0,t)};var r=x(RegExp),n=RegExp.prototype,s=new WeakMap;function i(e,t,n){var i=r.call(this,e,t);return s.set(i,n||s.get(e)),i}function o(e,t){var r=s.get(t);return Object.keys(r).reduce((function(t,n){return t[n]=e[r[n]],t}),Object.create(null))}return d(i,r),i.prototype.exec=function(e){var t=n.exec.call(this,e);return t&&(t.groups=o(t,this)),t},i.prototype[Symbol.replace]=function(e,t){if("string"==typeof t){var r=s.get(this);return n[Symbol.replace].call(this,e,t.replace(/\$<([^>]+)>/g,(function(e,t){return"$"+r[t]})))}if("function"==typeof t){var i=this;return n[Symbol.replace].call(this,e,(function(){var e=[];return e.push.apply(e,arguments),"object"!=typeof e[e.length-1]&&e.push(o(e,i)),t.apply(this,e)}))}return n[Symbol.replace].call(this,e,t)},y.apply(this,arguments)}const v=/[&<>"]/g,b=new Map([["&","&"],["<","<"],[">",">"],['"',"""]]),k=e=>b.get(e),w=e=>v.test(e)?e.replace(v,k):e;let _,j="";const q=new Set(["rotate","rotate-inv","wiggle","parrot","zoom","inversion","turn","turn-v","happa","pyon","flashy","pull","atsumori","stretch","stretch-v","conga","conga-inv","marquee","marquee-inv","rainbow"]),$=new Set(["ex-large","large","small"]),R=new Map([["marquee","conga"],["marquee-inv","conga-inv"]]),F=(e,t,r,n,s)=>{const i=w(r),o=w(n),a=w(t),l=s.filter(e=>$.has(e)),u=s.filter(e=>q.has(e));if(l.length+u.length<s.length)return e;if(u.length>5)return e;const c=u.map(e=>R.has(e)?R.get(e):e),p=l[l.length-1]||"";return((e,t,r)=>t.map((e,t)=>`<span class="emoji-effect ${e}${0===t&&r?" "+r:""}">`).join("")+e+"</span>".repeat(t.length))(`<i class="emoji s24 message-emoji ${p}" title=":${i}:" style="${o};">:${a}:</i>`,c,p)},M=(e,t,r,n,s)=>F(e,t,r,`background-image: url(${n})`,s),O=/[a-zA-Z0-9+_-]{1,32}/,P=y(/(hsl\([0-9]+,[\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]*[0-9]+(?:\.[0-9]+)?%,[\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]*[0-9]+(?:\.[0-9]+)?%\))(.*)/,{color:1,effects:2}),S=y(/0x([0-9A-Fa-f]{6})(.*)/,{color:1,effects:2}),I=e=>{const{inner:t}={inner:e[1]},r=S.exec(t);if(r)return(e=>{const{color:t,effects:r}=e.groups;return F(`:${e[0]}:`,"0x"+t,"0x"+t,"background-color: #"+t,""===r?[]:r.split(".").slice(1))})(r);const n=P.exec(t);if(n)return(e=>{const{color:t,effects:r}=e.groups;return F(`:${e[0]}:`,t,t,"background-color: "+t,""===r?[]:r.split(".").slice(1))})(n);if(!O.exec(t))return e[0];const[s,...i]=t.split(".");if(s.startsWith("@")){const t=_.getUserByName(s.slice(1));return t?M(e[0],s,s,`${j}/api/v3/files/${t.iconFileId}`,i):e[0]}const o=_.getStampByName(s);return o?M(e[0],s,o.name,`${j}/api/v3/files/${o.fileId}`,i):e[0]},E=/:((?:@?[a-zA-Z0-9+_-]{1,32}|\w+\([^:<>"'=+!?]+\))[\w+-.]*):/;function A(e,t,r){_=t,r&&(j=r),s(E,I)(e)}let C;const T=e=>{if(!(e=>"string"==typeof e.type&&"string"==typeof e.raw&&"string"==typeof e.id)(e))return!1;const{type:t,id:r}=e;return"user"===t||"channel"===t&&!!C.getChannel(r)||"group"===t||"file"===t||"message"===t},z=(e,t)=>{"user"!==t.type?"channel"===t.type&&C.getChannel(t.id)?((e,{type:t,id:r,raw:n})=>{const s=[];s.push(["href",`javascript:changeChannel('${C.getChannelPath(r)}')`]),s.push(["class","message-channel-link"]);let i=e.push("traq_extends_link_open","a",1);i.attrs=s,i.meta={type:t,data:n},i=e.push("text","",0),i.content=n,e.push("traq_extends_link_close","a",-1)})(e,t):"group"!==t.type?"file"!==t.type?(e.push("traq_extends_plain_open","a",1),e.push("text","",0).content=t.raw,e.push("traq_extends_plain_close","a",-1)):((e,{type:t,id:r,raw:n})=>{let s=e.push("traq_extends_link_open","a",1);s.attrs=[["href","/api/v3/files/"+r],["download",r]],s.meta={type:t,data:r},s=e.push("text","",0),s.content=n,e.push("traq_extends_link_close","a",-1)})(e,t):((e,{type:t,id:r,raw:n})=>{var s,i;const o=[],a=C.getUserGroup(r),l=C.getMe();o.push(["href",`javascript:openGroupModal('${r}')`]),null!==(s=null==a||null===(i=a.members)||void 0===i?void 0:i.some(e=>e.id===(null==l?void 0:l.id)))&&void 0!==s&&s?o.push(["class","message-group-link-highlight message-group-link"]):o.push(["class","message-group-link"]);let u=e.push("traq_extends_link_open","a",1);u.attrs=o,u.meta={type:t,data:r},u=e.push("text","",0),u.content=n,e.push("traq_extends_link_close","a",-1)})(e,t):((e,{type:t,id:r,raw:n})=>{const s=[],i=C.getMe();s.push(["href",`javascript:openUserModal('${r}')`]),s.push(r===(null==i?void 0:i.id)?["class","message-user-link-highlight message-user-link"]:["class","message-user-link"]);let o=e.push("traq_extends_link_open","a",1);o.attrs=s,o.meta={type:t,data:r},o=e.push("text","",0),o.content=n,e.push("traq_extends_link_close","a",-1)})(e,t)};function U(e,t){C=t,i(T,z)(e)}var W=["actionscript","awk","bash","basic","bnf","brainfuck","csharp","h","cpp","cmake","coq","css","clojure","coffeescript","crystal","d","dart","delphi","diff","django","dockerfile","elixir","elm","fsharp","fortran","go","gradle","groovy","xml","http","haml","handlebars","haxe","ini","json","java","javascript","kotlin","tex","less","lisp","livescript","lua","makefile","markdown","mathematica","matlab","moonscript","nginx","nimrod","ocaml","objectivec","glsl","php","perl","plaintext","pgsql","powershell","processing","prolog","protobuf","python","k","r","ruby","scss","sql","scheme","shell","stylus","swift","twig","typescript","vbnet","vbscript","verilog","vim","x86asm","xquery","yaml","zephir"];const B=/^(no-?highlight|plain|text)$/i,D=(e,t=!0,r=!0)=>(n,s)=>{let i,o,a="";if(t?([i,o]=s.split(":"),o&&(a=`<cite>${w(o)}</cite>`)):i=s,c.getLanguage(i)){const t=c.highlight(i,n);return`<pre class="${e}">${a}<code class="lang-${t.language}">${t.value}</code></pre>`}if(B.test(i))return`<pre class="${e}">${a}<code>${w(n)}</code></pre>`;{const t=c.highlightAuto(n,r?W:void 0);return`<pre class="${e}">${a}<code class="lang-${t.language}">${t.value}</code></pre>`}};var G=["libra.tokyotech.org","user-images.githubusercontent.com","git.trap.jp","wiki.trapti.tech","wiki.trap.jp","md.trapti.tech","md.trap.jp","trap.jp","traq-dev.tokyotech.org"];const H=(e,t)=>{const r=[],n=new Set,s=e.matchAll(t);let i=0,o=0;for(const e of s){var a,l,u,c,p,d,h;const t=null!==(a=e.index)&&void 0!==a?a:0,s=null!==(l=null===(u=e[0])||void 0===u?void 0:u.length)&&void 0!==l?l:0,g=null!==(c=null===(p=e[3])||void 0===p?void 0:p.length)&&void 0!==c?c:0,f=null!==(d=e[1])&&void 0!==d?d:"",m=null!==(h=e[2])&&void 0!==h?h:"",x=t,y=t+s-g;n.has(m)||("files"===f&&r.push({type:"file",id:m,startIndex:x,endIndex:y}),"messages"===f&&r.push({type:"message",id:m,startIndex:x,endIndex:y}),n.add(m)),x!==o&&(i=x),o=t+s}return{rawText:e,text:o===e.length?e.substring(0,i):e,embeddings:r}},L=["success","info","warning","danger"],N=r,Z=n,J=A,K=U,Q=o;exports.createHighlightFunc=D,exports.default=class{constructor(e,r=G,n){this.md=new t({breaks:!0,linkify:!0,highlight:D("traq-code traq-lang")}),this.embeddingRegExp=(e=>RegExp(e+"/(files|messages)/([\\da-f]{8}-[\\da-f]{4}-[\\da-f]{4}-[\\da-f]{4}-[\\da-f]{12})(\\s*)","g"))(n),this.setRendererRule(),this.setPlugin(e,r)}setPlugin(e,t){this.md.use(r).use(n,!0).use(U,e).use(A,e).use(o,{katex:a,output:"html",strict:e=>"unicodeTextInMathMode"===e?"ignore":"warn",maxSize:100,blockClass:"is-scroll"}).use(l,{attrs:{target:"_blank",rel:"nofollow noopener noreferrer"}}).use(u(t,{httpsOnly:!0}))}setRendererRule(){this.md.block.State.prototype.skipEmptyLines=function(e){for(let t=this.lineMax;e<t&&!(this.bMarks[e]+this.tShift[e]<this.eMarks[e]);e++)this.push("hardbreak","br",0);return e}}render(e){const t=H(e,this.embeddingRegExp);return{...t,renderedText:this.md.render(t.text,{})}}renderInline(e){const t=((e,t)=>{const{text:r,embeddings:n}=H(e,t);let s=r,i=0;for(const e of n){if(r.length<=e.startIndex)break;let t;if("file"===e.type)t="[[添付ファイル]]";else{if("message"!==e.type)throw new Error("embeddingReplacer unknown embedding type: "+e);t="[[添付メッセージ]]"}s=s.slice(0,i+e.startIndex)+t+s.slice(i+e.endIndex),i+=t.length-(e.endIndex-e.startIndex)}return{rawText:e,text:s,embeddings:n}})(e,this.embeddingRegExp),r=this.md.parseInline(t.text,{})[0].children||[],n=[];for(const e of r)n.push("regexp-0"===e.type?I(e.meta.match):"spoiler_open"===e.type?'<span class="spoiler">':"spoiler_close"===e.type?"</span>":"softbreak"===e.type?" ":this.md.utils.escapeHtml(e.content));return{...t,renderedText:n.join("")}}},exports.jsonPlugin=K,exports.katexPlugin=Q,exports.markPlugin=N,exports.spoilerPlugin=Z,exports.stampCssPlugin=(e,t)=>{s(/:([\w-_]+?)[:;]/,([e,r])=>t.includes(r)?`<i class="emoji s${e.endsWith(":")?32:16} e_${r.replace(/\+/g,"_-plus-_")}" title="${e}">${e}</i>`:e)(e)},exports.stampPlugin=J,exports.useContainer=(e,t=L)=>{t.forEach(t=>{e.use(p,t)})}; | ||
//# sourceMappingURL=traq-markdown-it.cjs.production.min.js.map |
@@ -466,4 +466,6 @@ import 'core-js/modules/web.dom-collections.iterator'; | ||
var defaultSubset = ['actionscript', 'awk', 'bash', 'basic', 'bnf', 'brainfuck', 'csharp', 'h', 'cpp', 'cmake', 'coq', 'css', 'clojure', 'coffeescript', 'crystal', 'd', 'dart', 'delphi', 'diff', 'django', 'dockerfile', 'elixir', 'elm', 'fsharp', 'fortran', 'go', 'gradle', 'groovy', 'xml', 'http', 'haml', 'handlebars', 'haxe', 'ini', 'json', 'java', 'javascript', 'kotlin', 'tex', 'less', 'lisp', 'livescript', 'lua', 'makefile', 'markdown', 'mathematica', 'matlab', 'moonscript', 'nginx', 'nimrod', 'ocaml', 'objectivec', 'glsl', 'php', 'perl', 'plaintext', 'pgsql', 'powershell', 'processing', 'prolog', 'protobuf', 'python', 'k', 'r', 'ruby', 'scss', 'sql', 'scheme', 'shell', 'stylus', 'swift', 'twig', 'typescript', 'vbnet', 'vbscript', 'verilog', 'vim', 'x86asm', 'xquery', 'yaml', 'zephir']; | ||
const noHighlightRe = /^(no-?highlight|plain|text)$/i; | ||
const createHighlightFunc = (preClass, withCaption = true) => (code, lang) => { | ||
const createHighlightFunc = (preClass, withCaption = true, useSubsetForAuto = true) => (code, lang) => { | ||
let langName, langCaption; | ||
@@ -488,3 +490,3 @@ let citeTag = ''; | ||
} else { | ||
const result = hljs.highlightAuto(code); | ||
const result = hljs.highlightAuto(code, useSubsetForAuto ? defaultSubset : undefined); | ||
return `<pre class="${preClass}">${citeTag}<code class="lang-${result.language}">${result.value}</code></pre>`; | ||
@@ -496,2 +498,122 @@ } | ||
const createEmbeddingRegexp = embeddingOrigin => RegExp(`${embeddingOrigin}/(files|messages)/([\\da-f]{8}-[\\da-f]{4}-[\\da-f]{4}-[\\da-f]{4}-[\\da-f]{12})(\\s*)`, 'g'); | ||
/** | ||
* markdownから埋め込みURLを抽出する | ||
* | ||
* @param regexp | ||
* マッチに使う正規表現。グループは順に | ||
* | ||
* - 種別 | ||
* - UUID | ||
* - 削除されるスペース | ||
* | ||
* であることを期待する | ||
*/ | ||
const embeddingExtractor = (rawMessage, regexp) => { | ||
const embeddings = []; | ||
const knownIdSet = new Set(); | ||
const matches = rawMessage.matchAll(regexp); | ||
/** 連続したマッチの開始インデックス */ | ||
let sequenceStartIndex = 0; | ||
/** スペースを含んだ、連続したマッチ全体の終了インデックス */ | ||
let sequenceEndIndex = 0; | ||
for (const match of matches) { | ||
var _match$index, _match$0$length, _match$, _match$3$length, _match$2, _match$3, _match$4; | ||
const matchIndex = (_match$index = match.index) !== null && _match$index !== void 0 ? _match$index : 0; | ||
const matchLength = (_match$0$length = (_match$ = match[0]) === null || _match$ === void 0 ? void 0 : _match$.length) !== null && _match$0$length !== void 0 ? _match$0$length : 0; | ||
const spaceLength = (_match$3$length = (_match$2 = match[3]) === null || _match$2 === void 0 ? void 0 : _match$2.length) !== null && _match$3$length !== void 0 ? _match$3$length : 0; | ||
const type = (_match$3 = match[1]) !== null && _match$3 !== void 0 ? _match$3 : ''; | ||
const id = (_match$4 = match[2]) !== null && _match$4 !== void 0 ? _match$4 : ''; | ||
const startIndex = matchIndex; | ||
const endIndex = matchIndex + matchLength - spaceLength; | ||
if (!knownIdSet.has(id)) { | ||
if (type === 'files') { | ||
embeddings.push({ | ||
type: 'file', | ||
id, | ||
startIndex, | ||
endIndex | ||
}); | ||
} | ||
if (type === 'messages') { | ||
embeddings.push({ | ||
type: 'message', | ||
id, | ||
startIndex, | ||
endIndex | ||
}); | ||
} | ||
knownIdSet.add(id); | ||
} | ||
if (startIndex !== sequenceEndIndex) { | ||
// 連続したマッチではなかった | ||
sequenceStartIndex = startIndex; | ||
} | ||
sequenceEndIndex = matchIndex + matchLength; | ||
} | ||
const hasSequenceReachedEos = sequenceEndIndex === rawMessage.length; | ||
return { | ||
rawText: rawMessage, | ||
text: hasSequenceReachedEos ? rawMessage.substring(0, sequenceStartIndex) : rawMessage, | ||
embeddings | ||
}; | ||
}; | ||
/** | ||
* markdownから埋め込みURLを抽出してすべて置換する | ||
* | ||
* @param regexp | ||
* マッチに使う正規表現。グループは順に | ||
* | ||
* - 種別 | ||
* - UUID | ||
* - 削除されるスペース | ||
* | ||
* であることを期待する | ||
*/ | ||
const embeddingReplacer = (rawMessage, regexp) => { | ||
const { | ||
text, | ||
embeddings | ||
} = embeddingExtractor(rawMessage, regexp); | ||
let newText = text; // 置換で文字数がずれるのでずれた数を保持する | ||
let placeDiff = 0; | ||
for (const embedding of embeddings) { | ||
// 末尾のものは抽出で消えているので置換しない | ||
if (text.length <= embedding.startIndex) break; | ||
let replaced; | ||
if (embedding.type === 'file') { | ||
replaced = '[[添付ファイル]]'; | ||
} else if (embedding.type === 'message') { | ||
replaced = '[[添付メッセージ]]'; | ||
} else { | ||
const invalid = embedding; | ||
throw new Error(`embeddingReplacer unknown embedding type: ${invalid}`); | ||
} | ||
newText = newText.slice(0, placeDiff + embedding.startIndex) + replaced + newText.slice(placeDiff + embedding.endIndex); | ||
placeDiff += replaced.length - (embedding.endIndex - embedding.startIndex); | ||
} | ||
return { | ||
rawText: rawMessage, | ||
text: newText, | ||
embeddings | ||
}; | ||
}; | ||
const defaultLabels = ['success', 'info', 'warning', 'danger']; | ||
@@ -512,3 +634,3 @@ const useContainer = (md, labels = defaultLabels) => { | ||
class index { | ||
constructor(store, whitelist = defaultWhitelist) { | ||
constructor(store, whitelist = defaultWhitelist, embeddingOrigin) { | ||
this.md = new MarkdownIt({ | ||
@@ -519,2 +641,3 @@ breaks: true, | ||
}); | ||
this.embeddingRegExp = createEmbeddingRegexp(embeddingOrigin); | ||
this.setRendererRule(); | ||
@@ -542,6 +665,3 @@ this.setPlugin(store, whitelist); | ||
setRendererRule() { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const blockState = this.md.block.State; | ||
blockState.prototype.skipEmptyLines = function skipEmptyLines(from) { | ||
this.md.block.State.prototype.skipEmptyLines = function skipEmptyLines(from) { | ||
for (let max = this.lineMax; from < max; from++) { | ||
@@ -560,7 +680,11 @@ if (this.bMarks[from] + this.tShift[from] < this.eMarks[from]) { | ||
render(text) { | ||
return this.md.render(text, {}); | ||
const data = embeddingExtractor(text, this.embeddingRegExp); | ||
return { ...data, | ||
renderedText: this.md.render(data.text, {}) | ||
}; | ||
} | ||
renderInline(text) { | ||
const parsed = this.md.parseInline(text, {}); | ||
const data = embeddingReplacer(text, this.embeddingRegExp); | ||
const parsed = this.md.parseInline(data.text, {}); | ||
const tokens = parsed[0].children || []; | ||
@@ -585,3 +709,5 @@ const rendered = []; | ||
return rendered.join(''); | ||
return { ...data, | ||
renderedText: rendered.join('') | ||
}; | ||
} | ||
@@ -588,0 +714,0 @@ |
{ | ||
"name": "@traptitech/traq-markdown-it", | ||
"version": "2.2.7", | ||
"version": "2.3.0", | ||
"description": "Markdown parser for traQ.", | ||
@@ -17,6 +17,6 @@ "main": "dist/index.js", | ||
"start": "tsdx watch", | ||
"build": "tsdx build && dart-sass ./src/css/index.sass ./dist/stamp.css", | ||
"build": "tsdx build && dart-sass ./src/css/index.scss ./dist/index.css", | ||
"test": "tsdx test", | ||
"lint": "tsdx lint", | ||
"prepare": "tsdx build && dart-sass ./src/css/index.sass ./dist/stamp.css" | ||
"prepare": "tsdx build && dart-sass ./src/css/index.scss ./dist/index.css" | ||
}, | ||
@@ -34,8 +34,8 @@ "repository": { | ||
"dependencies": { | ||
"@traptitech/markdown-it-katex": "^3.2.3", | ||
"@traptitech/markdown-it-spoiler": "^1.1.3", | ||
"@traptitech/markdown-it-katex": "^3.2.4", | ||
"@traptitech/markdown-it-spoiler": "^1.1.4", | ||
"core-js": "^3.6.5", | ||
"highlight.js": "^10.0.2", | ||
"highlight.js": "^10.0.3", | ||
"katex": "^0.11.1", | ||
"markdown-it": "^10.0.0", | ||
"markdown-it": "^11.0.0", | ||
"markdown-it-container": "^2.0.0", | ||
@@ -50,10 +50,11 @@ "markdown-it-image-filter": "^1.1.0", | ||
"@babel/preset-env": "^7.9.6", | ||
"@traptitech/traq": "3.0.3-0", | ||
"@traptitech/traq": "3.1.2-5", | ||
"@types/highlightjs": "^9.12.0", | ||
"@types/jest": "^25.2.3", | ||
"@types/katex": "^0.11.0", | ||
"@types/markdown-it": "10.0.1", | ||
"@typescript-eslint/eslint-plugin": "^2.31.0", | ||
"@typescript-eslint/parser": "^2.31.0", | ||
"@typescript-eslint/eslint-plugin": "^3.0.0", | ||
"@typescript-eslint/parser": "^3.0.0", | ||
"dart-sass": "^1.25.0", | ||
"eslint": "^6.8.0", | ||
"eslint": "^7.0.0", | ||
"eslint-config-prettier": "^6.11.0", | ||
@@ -64,4 +65,4 @@ "eslint-plugin-prettier": "^3.1.3", | ||
"tsdx": "^0.13.2", | ||
"tslib": "^1.11.2", | ||
"typescript": "^3.8.3" | ||
"tslib": "^2.0.0", | ||
"typescript": "^3.9.3" | ||
}, | ||
@@ -68,0 +69,0 @@ "husky": { |
import hljs from 'highlight.js' | ||
import defaultSubset from './default/language_subset' | ||
import { escapeHtml } from './util' | ||
@@ -6,6 +7,7 @@ | ||
export const createHighlightFunc = (preClass: string, withCaption = true) => ( | ||
code: string, | ||
lang: string | ||
): string => { | ||
export const createHighlightFunc = ( | ||
preClass: string, | ||
withCaption = true, | ||
useSubsetForAuto = true | ||
) => (code: string, lang: string): string => { | ||
let langName: string, langCaption: string | ||
@@ -30,5 +32,8 @@ let citeTag = '' | ||
} else { | ||
const result = hljs.highlightAuto(code) | ||
const result = hljs.highlightAuto( | ||
code, | ||
useSubsetForAuto ? defaultSubset : undefined | ||
) | ||
return `<pre class="${preClass}">${citeTag}<code class="lang-${result.language}">${result.value}</code></pre>` | ||
} | ||
} |
/// <reference types="../src/types/markdown-it-mark" /> | ||
/* eslint-disable @typescript-eslint/camelcase */ | ||
import MarkdownIt from 'markdown-it' | ||
@@ -16,4 +15,20 @@ import MarkdownItMark from 'markdown-it-mark' | ||
import { Store } from './Store' | ||
import { | ||
createEmbeddingRegexp, | ||
embeddingExtractor, | ||
EmbeddingsExtractedMessage, | ||
embeddingReplacer | ||
} from './embeddingExtractor' | ||
export { Store } from './Store' | ||
export { | ||
Embedding, | ||
EmbeddingFile, | ||
EmbeddingMessage, | ||
EmbeddingsExtractedMessage | ||
} from './embeddingExtractor' | ||
export type MarkdownRenderResult = EmbeddingsExtractedMessage & { | ||
renderedText: string | ||
} | ||
export default class { | ||
@@ -25,4 +40,10 @@ readonly md = new MarkdownIt({ | ||
}) | ||
readonly embeddingRegExp: RegExp | ||
constructor(store: Store, whitelist: string[] = defaultWhitelist) { | ||
constructor( | ||
store: Store, | ||
whitelist: string[] = defaultWhitelist, | ||
embeddingOrigin: string | ||
) { | ||
this.embeddingRegExp = createEmbeddingRegexp(embeddingOrigin) | ||
this.setRendererRule() | ||
@@ -56,5 +77,3 @@ this.setPlugin(store, whitelist) | ||
setRendererRule(): void { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const blockState = this.md.block.State | ||
blockState.prototype.skipEmptyLines = function skipEmptyLines( | ||
this.md.block.State.prototype.skipEmptyLines = function skipEmptyLines( | ||
from: number | ||
@@ -72,8 +91,14 @@ ): number { | ||
render(text: string): string { | ||
return this.md.render(text, {}) | ||
render(text: string): MarkdownRenderResult { | ||
const data = embeddingExtractor(text, this.embeddingRegExp) | ||
return { | ||
...data, | ||
renderedText: this.md.render(data.text, {}) | ||
} | ||
} | ||
renderInline(text: string): string { | ||
const parsed = this.md.parseInline(text, {}) | ||
renderInline(text: string): MarkdownRenderResult { | ||
const data = embeddingReplacer(text, this.embeddingRegExp) | ||
const parsed = this.md.parseInline(data.text, {}) | ||
const tokens = parsed[0].children || [] | ||
@@ -96,3 +121,7 @@ const rendered = [] | ||
} | ||
return rendered.join('') | ||
return { | ||
...data, | ||
renderedText: rendered.join('') | ||
} | ||
} | ||
@@ -99,0 +128,0 @@ } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
232862
59
2940
17
+ Addedlinkify-it@3.0.3(transitive)
+ Addedmarkdown-it@11.0.1(transitive)
- Removedlinkify-it@2.2.0(transitive)
- Removedmarkdown-it@10.0.0(transitive)
Updatedhighlight.js@^10.0.3
Updatedmarkdown-it@^11.0.0