From a39317f25c68502bdd92584c18e7151e776b86b8 Mon Sep 17 00:00:00 2001 From: zenn Date: Fri, 26 Jun 2026 16:52:47 +0900 Subject: [PATCH] =?UTF-8?q?=EC=9E=90=EB=8F=99=20=EC=9A=94=EC=95=BD=20?= =?UTF-8?q?=EB=AC=B8=EB=B2=95=20=EB=85=B8=EC=B6=9C=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- composables/createPostSummary.js | 17 ++++++++++++++++- docs/changelog.md | 4 ++++ docs/deploy.md | 7 ++++++- docs/map.md | 2 +- docs/spec.md | 2 +- docs/update.md | 4 ++++ package-lock.json | 4 ++-- package.json | 2 +- 8 files changed, 35 insertions(+), 7 deletions(-) diff --git a/composables/createPostSummary.js b/composables/createPostSummary.js index 3c798e6..fe78bbc 100644 --- a/composables/createPostSummary.js +++ b/composables/createPostSummary.js @@ -1,3 +1,16 @@ +/** @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 - 게시물 요약 @@ -12,13 +25,15 @@ export function createPostSummary(excerpt = '', content = '', options = {}) { const appendEllipsis = options.appendEllipsis !== false const source = String(excerpt || '').trim() || String(content || '') - const plainText = source + const plainText = stripInlineColorMarkdown(source) .replace(/```[\s\S]*?```/g, ' ') .replace(/:::[\s\S]*?:::/g, ' ') .replace(//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() diff --git a/docs/changelog.md b/docs/changelog.md index f109662..7ec1b7f 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,5 +1,9 @@ # 업데이트 요약 +## v1.8.5 + +- 요약글이 비어 있어 본문으로 카드 설명을 만들 때 `::red` 같은 색상 문법과 HTML 태그가 노출되지 않도록 정리했다. + ## v1.8.4 - 글쓰기에서 새 태그를 추가할 때 배지에 슬러그 대신 입력한 이름을 보여주도록 수정했다. diff --git a/docs/deploy.md b/docs/deploy.md index 15495b1..b8ebd49 100644 --- a/docs/deploy.md +++ b/docs/deploy.md @@ -1,6 +1,6 @@ # 배포 가이드 -> 로컬 기준 v1.8.4에서 `npm run verify` 검증을 통과했다. NAS 실제 컨테이너 기동과 도메인/프록시 접속 검증은 운영 배포 단계에서 진행한다. +> 로컬 기준 v1.8.5에서 `npm run verify` 검증을 통과했다. NAS 실제 컨테이너 기동과 도메인/프록시 접속 검증은 운영 배포 단계에서 진행한다. ## 빌드 유형 @@ -16,6 +16,11 @@ ## 로컬 개발 +### v1.8.5 참고 + +- 추가 DB 마이그레이션은 없다. +- 요약이 비어 있는 게시물 본문 첫머리에 인라인 색상 문법이나 HTML 태그가 있어도 공개 목록 설명에는 일반 텍스트만 표시되는지 확인한다. + ### v1.8.4 참고 - 추가 DB 마이그레이션은 없다. diff --git a/docs/map.md b/docs/map.md index dad18a7..0e28f77 100644 --- a/docs/map.md +++ b/docs/map.md @@ -18,7 +18,7 @@ | 파일 | 용도 | |------|------| | composables/formatPostDate.js | 공개 게시일 `YYYY.MM.DD`, 관리자·수정일 보조 `formatPostDateTime`, `wasPostUpdatedAfterPublish` | -| composables/createPostSummary.js | 게시물 요약·본문에서 목록·SEO용 짧은 설명 텍스트 생성 | +| composables/createPostSummary.js | 게시물 요약·본문에서 목록·SEO용 짧은 설명 텍스트 생성, 본문 대체 요약의 표시용 마크다운·HTML 토큰 제거 | | composables/useAdminToast.js | 관리자 우측 상단 토스트(성공·오류·안내; 모달보다 위 z-index) | ## 공유 라이브러리(서버·클라이언트 공통) diff --git a/docs/spec.md b/docs/spec.md index 14734ef..219064f 100644 --- a/docs/spec.md +++ b/docs/spec.md @@ -90,7 +90,7 @@ - 공유 모달은 게시물 썸네일/제목/요약 미리보기, X/Bluesky/Facebook/LinkedIn/Email 링크, 링크 복사 액션을 제공한다. - 공유·SEO 설명은 SEO 설명이 있으면 우선 사용하고, 없으면 게시물 요약, 요약도 없으면 본문에서 마크다운 기호를 제거한 짧은 텍스트를 사용한다. - 공개 페이지 ``은 개별 페이지 제목이 있으면 제목만 사용하고, 제목이 없는 기본 화면에서만 사이트 이름을 사용한다. 게시물 상세 제목 뒤에 사이트 이름을 자동으로 붙이지 않는다. -- 홈 Latest·게시물 목록·태그 목록의 카드 설명도 동일하게 요약이 비어 있으면 본문에서 `createPostSummary`로 짧은 텍스트를 만든다. 목록용 설명은 문자열에 수동 말줄임을 붙이지 않고 `post-summary-clamp` 전용 클래스가 실제 표시 줄 끝에서 말줄임을 처리한다. +- 홈 Latest·게시물 목록·태그 목록의 카드 설명도 동일하게 요약이 비어 있으면 본문에서 `createPostSummary`로 짧은 텍스트를 만든다. 이때 코드·HTML/iframe 블록, HTML 태그, 인라인 색상 토큰 같은 표시용 문법은 목록 설명에 노출하지 않는다. 목록용 설명은 문자열에 수동 말줄임을 붙이지 않고 `post-summary-clamp` 전용 클래스가 실제 표시 줄 끝에서 말줄임을 처리한다. - 게시물 상세 제목 아래 대표 이미지는 관리자 글쓰기 오른쪽 사이드의 `대표 이미지 표시` 옵션이 켜진 게시물에서만 표시한다. 해당 토글은 대표 이미지 유무와 상관없이 항상 활성 상태이며, 대표 이미지를 나중에 추가할 경우에도 미리 저장한 표시 설정을 유지한다. 대표 이미지는 목록·공유용으로는 계속 사용할 수 있으며, 본문 상단 표시 기본값은 꺼짐이다. ### 게시물 업로드 이미지 썸네일 diff --git a/docs/update.md b/docs/update.md index ea558a5..c0a32aa 100644 --- a/docs/update.md +++ b/docs/update.md @@ -1,5 +1,9 @@ # 업데이트 이력 +## v1.8.5 + +- 게시물 요약 자동 생성 시 인라인 색상 토큰과 HTML 태그가 목록 설명에 노출되지 않도록 수정. + ## v1.8.4 - 게시물 글쓰기에서 새 태그 배지에 슬러그 대신 입력한 태그명을 표시하도록 수정. diff --git a/package-lock.json b/package-lock.json index c88c52d..cb26126 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "sori.studio", - "version": "1.8.4", + "version": "1.8.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "sori.studio", - "version": "1.8.4", + "version": "1.8.5", "hasInstallScript": true, "dependencies": { "@nuxtjs/tailwindcss": "^6.14.0", diff --git a/package.json b/package.json index a894740..620da2d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sori.studio", - "version": "1.8.4", + "version": "1.8.5", "private": true, "type": "module", "imports": {