From 10bf6b422ee90905d36972ed51fb94c093f5caff Mon Sep 17 00:00:00 2001 From: zenn Date: Fri, 1 May 2026 18:17:12 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B4=80=EB=A6=AC=EC=9E=90=20=EB=B8=94?= =?UTF-8?q?=EB=A1=9D=ED=98=95=20=EA=B8=80=EC=93=B0=EA=B8=B0=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/admin/AdminBlockEditor.vue | 541 ++++++++++++++++++ components/admin/AdminMarkdownPreview.vue | 152 ----- components/admin/AdminPostForm.vue | 120 +--- .../content/ContentMarkdownRenderer.vue | 123 ++++ docs/convention.md | 1 + docs/history.md | 10 + docs/map.md | 3 +- docs/spec.md | 12 +- docs/todo.md | 1 - docs/update.md | 8 + package-lock.json | 4 +- package.json | 2 +- pages/pages/[slug].vue | 6 +- pages/posts/[slug].vue | 4 +- 14 files changed, 701 insertions(+), 286 deletions(-) create mode 100644 components/admin/AdminBlockEditor.vue delete mode 100644 components/admin/AdminMarkdownPreview.vue create mode 100644 components/content/ContentMarkdownRenderer.vue diff --git a/components/admin/AdminBlockEditor.vue b/components/admin/AdminBlockEditor.vue new file mode 100644 index 0000000..f3f28c1 --- /dev/null +++ b/components/admin/AdminBlockEditor.vue @@ -0,0 +1,541 @@ + + + + + diff --git a/components/admin/AdminMarkdownPreview.vue b/components/admin/AdminMarkdownPreview.vue deleted file mode 100644 index aa27b6c..0000000 --- a/components/admin/AdminMarkdownPreview.vue +++ /dev/null @@ -1,152 +0,0 @@ - - - diff --git a/components/admin/AdminPostForm.vue b/components/admin/AdminPostForm.vue index a1f1462..412da5d 100644 --- a/components/admin/AdminPostForm.vue +++ b/components/admin/AdminPostForm.vue @@ -17,8 +17,6 @@ const props = defineProps({ const emit = defineEmits(['submit']) const slugTouched = ref(Boolean(props.initialPost.slug)) -const editorMode = ref('write') -const contentTextarea = ref(null) const form = reactive({ title: props.initialPost.title || '', @@ -68,77 +66,6 @@ const parseTags = (value) => [...new Set(value .map((tag) => toSlug(tag)) .filter(Boolean))] -/** - * 본문 선택 영역에 마크다운 문법 삽입 - * @param {string} before - 선택 영역 앞에 넣을 문자열 - * @param {string} after - 선택 영역 뒤에 넣을 문자열 - * @param {string} fallback - 선택 영역이 없을 때 넣을 문자열 - * @returns {void} - */ -const insertMarkdown = (before, after = '', fallback = '') => { - const textarea = contentTextarea.value - - if (!textarea) { - form.content += fallback || before - return - } - - const start = textarea.selectionStart - const end = textarea.selectionEnd - const selectedText = form.content.slice(start, end) - const insertText = selectedText - ? `${before}${selectedText}${after}` - : (fallback || `${before}${after}`) - - form.content = `${form.content.slice(0, start)}${insertText}${form.content.slice(end)}` - - nextTick(() => { - textarea.focus() - const cursor = start + insertText.length - textarea.setSelectionRange(cursor, cursor) - }) -} - -/** - * 제목 문법 삽입 - * @returns {void} - */ -const insertHeading = () => { - insertMarkdown('## ', '', '## 제목') -} - -/** - * 굵게 문법 삽입 - * @returns {void} - */ -const insertBold = () => { - insertMarkdown('**', '**', '**강조**') -} - -/** - * 목록 문법 삽입 - * @returns {void} - */ -const insertList = () => { - insertMarkdown('- ', '', '- 목록') -} - -/** - * 인용 문법 삽입 - * @returns {void} - */ -const insertQuote = () => { - insertMarkdown('> ', '', '> 인용') -} - -/** - * 코드 블록 문법 삽입 - * @returns {void} - */ -const insertCodeBlock = () => { - insertMarkdown('```\n', '\n```', '```\n코드\n```') -} - /** * 게시물 입력값 제출 * @returns {void} @@ -178,53 +105,10 @@ const submitPost = () => {
본문 -
- - -
+ / 명령과 마크다운 단축 입력 지원
-
-
- - - - - -
-