Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions docs/memo-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@

- `debug`·`comparison` 같은 **목적/주제는 `type`이 아니라 `tags`**에 넣는다.
- ` ```md ` 처럼 산문을 인용한 펜스는 코드로 세지 않는다.
- `<QuoteLink url="…">` 같은 **링크 컴포넌트도 링크로 센다** — JSX로 걸러버리면 링크 모음이 `note`로 샌다.
- **압축하면 형태가 바뀔 수 있다.** 부풀린 산문을 걷어내면 남는 게 링크뿐일 수 있다.

## status — 공개 상태
Expand All @@ -60,7 +61,7 @@
| `archive` | 저장/보관 (완성 예정 없음) | 비공개 |
| `release` | 완성됨 | 공개 |

- **`bookmarks`는 `draft`를 쓰지 않는다.** 링크는 붙여넣은 순간이 최종형이라 "작성 중"이 없다 → `archive` 아니면 `release`.
- **`bookmarks`는 `draft`를 쓰지 않는다.** 링크는 붙여넣은 순간이 최종형이라 "작성 중"이 없다 → `archive` 아니면 `release`. `lint:memo`가 오류로 잡는다.
- `draft`를 "공개 안 함"으로 쓰면 작성 중 큐가 방치된 메모로 막힌다.
- 비공개 목록은 로컬에서만 보인다: `/memos/draft`, `/memos/archive`. 프로덕션에서는 비어 있다.
- 공개 경로(상세·태그·`/type`·RSS·사이트맵·검색)는 모두 `release`만 포함한다.
Expand Down Expand Up @@ -110,7 +111,7 @@

| 검사 | 대상 | 빌드 | 실패 조건 |
|---|---|---|---|
| `lint:memo` | `type` ↔ 본문 형태, 각주 참조 ↔ 정의, 이 문서 ↔ 스키마 | **게이트** | 논리적 모순은 오류, 휴리스틱 불일치는 경고. `draft`는 경고까지만 |
| `lint:memo` | `type` ↔ 본문 형태, `bookmarks` ↔ `draft`, 각주 참조 ↔ 정의, 이 문서 ↔ 스키마 | **게이트** | 논리적 모순은 오류, 휴리스틱 불일치는 경고. `draft`는 경고까지만 |
| `lint:voice` | 인용 표시 없는 존댓말 (남의 문장) | **게이트** | `release`에서 검출되면 실패. `draft`·`archive`는 경고 |
| `lint:links` | 죽은 링크 | 미연결 | 수동 실행 |

Expand Down
44 changes: 43 additions & 1 deletion scripts/lint-memo.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,16 @@ const strict = process.argv.includes('--strict')

const NON_CODE_FENCE = /^(md|markdown|text|plaintext)$/i

/**
* 링크를 렌더하는 컴포넌트 (`<QuoteLink url="...">제목</QuoteLink>`).
* JSX 로 걸러버리면 링크가 하나도 없는 것으로 보여서 bookmarks 가 note 로 샌다.
*/
const LINK_COMPONENT = /^<([A-Z]\w*)\s[^>]*\b(?:url|href)="(https?:\/\/[^"]+)"/

/**
* 본문에서 형태 신호를 추출한다.
* - 코드 펜스: ```md 처럼 산문을 인용한 펜스는 코드로 세지 않는다
* - 링크: 불릿 링크 + 맨 URL 줄
* - 링크: 불릿 링크 + 맨 URL 줄 + 링크 컴포넌트
* - 산문: 불릿/헤딩/각주정의/JSX/import 를 제외한 줄
*/
const analyze = (raw) => {
Expand All @@ -24,6 +30,7 @@ const analyze = (raw) => {
let inFence = false
let fenceIsCode = true
let codeLines = 0
let linkComponent = null
const kept = []

for (const line of body.split('\n')) {
Expand All @@ -48,6 +55,30 @@ const analyze = (raw) => {
continue
}

// 링크 컴포넌트는 여는 줄부터 닫는 줄까지를 링크 불릿 하나로 접는다.
// 자식(링크 제목)은 산문이 아니라 링크의 일부다 — `- [제목](URL)` 과 같다.
if (linkComponent) {
if (line.includes(`</${linkComponent}>`)) {
linkComponent = null
}

continue
}

const component = line.trim().match(LINK_COMPONENT)

if (component) {
const [, tag, url] = component

kept.push(`- <${url}>`)

if (!line.includes(`</${tag}>`) && !/\/>\s*$/.test(line)) {
linkComponent = tag
}

continue
}

kept.push(line)
}

Expand Down Expand Up @@ -221,6 +252,17 @@ for (const file of files) {
// 작성 중(draft)은 아직 형태가 안 잡혔을 수 있으므로 경고로만 본다
const level = status === 'draft' ? 'warn' : 'error'

// 링크는 붙여넣은 순간이 최종형이라 "작성 중"이 없다.
// draft 를 "공개 안 함"으로 쓰면 작성 중 큐가 방치된 링크로 막힌다.
// 이 규칙 자체가 draft 에 대한 것이므로 level 로 낮추지 않는다.
if (declared === 'bookmarks' && status === 'draft') {
add(
'error',
target,
'type: bookmarks 인데 status: draft — archive 아니면 release 다'
)
}

// 각주 짝 — 참조만 있으면 마커가 깨진 채 렌더되고, 정의만 있으면 렌더되지 않는다
for (const id of analyzed.footnoteRefs) {
if (!analyzed.footnoteDefs.has(id)) {
Expand Down
2 changes: 1 addition & 1 deletion src/content/memo/182.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
type: bookmarks
tags: ['photoshop']
status: draft
status: archive
ctime: 2022-04-09
mtime: 2026-07-27
---
Expand Down
2 changes: 1 addition & 1 deletion src/content/memo/201.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
type: note
tags: ['git']
status: draft
status: archive
ctime: 2022-09-23
mtime: 2024-03-22
---
Expand Down
2 changes: 1 addition & 1 deletion src/content/memo/226.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
type: note
tags: ['api', 'docs']
status: draft
status: archive
ctime: 2022-11-02
mtime: 2024-03-22
---
Expand Down
2 changes: 1 addition & 1 deletion src/content/memo/256.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
type: bookmarks
tags: ['micro-frontend', 'webpack']
status: draft
status: archive
ctime: 2023-03-19
mtime: 2026-07-27
---
Expand Down
2 changes: 1 addition & 1 deletion src/content/memo/372.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
type: note
tags: ['aws']
status: draft
status: archive
ctime: 2025-01-18
mtime: 2025-01-18
---
Expand Down
4 changes: 2 additions & 2 deletions src/content/memo/430.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
type: note
type: bookmarks
tags: ['fp-ts', 'fp']
status: draft
status: archive
ctime: 2025-03-02
mtime: 2025-03-02
---
Expand Down
4 changes: 2 additions & 2 deletions src/content/memo/433.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
type: note
type: bookmarks
tags: ['symbol']
status: draft
status: archive
ctime: 2025-03-03
mtime: 2025-03-03
---
Expand Down
39 changes: 0 additions & 39 deletions src/content/memo/435.md

This file was deleted.

4 changes: 2 additions & 2 deletions src/content/memo/449.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
type: note
type: bookmarks
tags: ['state']
status: draft
status: archive
ctime: 2025-03-04
mtime: 2025-03-04
---
Expand Down
4 changes: 2 additions & 2 deletions src/content/memo/458.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
type: note
type: bookmarks
tags: ['concurrency']
status: draft
status: archive
ctime: 2025-03-04
mtime: 2025-03-04
---
Expand Down
4 changes: 2 additions & 2 deletions src/content/memo/467.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
type: note
type: bookmarks
tags: ['file-reader']
status: draft
status: archive
ctime: 2025-03-04
mtime: 2025-03-04
---
Expand Down
4 changes: 2 additions & 2 deletions src/content/memo/471.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
type: note
type: bookmarks
tags: ['css', 'highlight']
status: draft
status: archive
ctime: 2025-03-04
mtime: 2025-03-04
---
Expand Down
4 changes: 2 additions & 2 deletions src/content/memo/472.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
type: note
type: bookmarks
tags: ['reservation']
status: draft
status: archive
ctime: 2025-03-04
mtime: 2025-03-04
---
Expand Down
4 changes: 2 additions & 2 deletions src/content/memo/474.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
type: note
type: bookmarks
tags: ['state']
status: draft
status: archive
ctime: 2025-03-05
mtime: 2025-03-05
---
Expand Down
4 changes: 2 additions & 2 deletions src/content/memo/487.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
type: note
type: bookmarks
tags: ['typescript', 'react']
status: draft
status: archive
ctime: 2025-03-05
mtime: 2025-03-05
---
Expand Down
Loading