Files
sori.studio/composables/createPostSummary.js

55 lines
1.9 KiB
JavaScript

/** @type {RegExp} 요약에서 표시 텍스트만 남길 인라인 색상 문법 */
const INLINE_COLOR_SUMMARY_RE = /::(?:gray|blue|green|yellow|red|purple)\[((?:\\\]|[^\]\n])*)\]/g
/**
* 인라인 색상 문법을 요약용 일반 텍스트로 바꾼다.
* @param {string} value - 원본 문자열
* @returns {string} 색상 토큰을 제거한 문자열
*/
const stripInlineColorMarkdown = (value) => String(value || '').replace(
INLINE_COLOR_SUMMARY_RE,
(_match, text) => String(text || '').replaceAll('\\]', ']')
)
/**
* 게시물 요약 또는 본문에서 목록·메타용 짧은 텍스트를 만든다.
* @param {string} excerpt - 게시물 요약
* @param {string} content - 게시물 본문(마크다운)
* @param {Object} [options] - 옵션
* @param {number} [options.maxLength=160] - 최대 글자 수
* @param {boolean} [options.appendEllipsis=true] - 잘린 문자열 끝에 말줄임 추가 여부
* @returns {string} 화면 표시용 요약
*/
export function createPostSummary(excerpt = '', content = '', options = {}) {
const maxLength = Number(options.maxLength) > 0 ? Number(options.maxLength) : 160
const appendEllipsis = options.appendEllipsis !== false
const source = String(excerpt || '').trim() || String(content || '')
const plainText = stripInlineColorMarkdown(source)
.replace(/```[\s\S]*?```/g, ' ')
.replace(/:::[\s\S]*?:::/g, ' ')
.replace(/<!--[\s\S]*?-->/g, ' ')
.replace(/<[^>]+>/g, ' ')
.replace(/!\[[^\]]*]\([^)]*\)/g, ' ')
.replace(/\[([^\]]+)]\([^)]*\)/g, '$1')
.replace(/https?:\/\/\S+/g, ' ')
.replace(/(^|\s)::(?:gray|blue|green|yellow|red|purple)(?=\s|$)/g, ' ')
.replace(/[#>*_`~|-]+/g, ' ')
.replace(/\s+/g, ' ')
.trim()
if (!plainText) {
return ''
}
if (plainText.length <= maxLength) {
return plainText
}
if (!appendEllipsis) {
return plainText.slice(0, maxLength).trim()
}
return `${plainText.slice(0, maxLength - 3).trim()}...`
}