Skip to content

Diff of MacroUnlinkedMentions

Changes between revision 1 - Add MacroUnlinkedMentions page and revision 2 - Unlinked mentions count whole names only; Query hides year-month duplicates
--- MacroUnlinkedMentions
+++ MacroUnlinkedMentions
@@ -6,27 +6,28 @@
 `[[UnlinkedMentions]]`
 
 인자는 없습니다. 단추(`Find unlinked mentions`)를 누르면 이 페이지 이름이 본문에 들어 있고 아직 이 페이지로 링크하지 않은 페이지가 이름과 앞뒤 글과 함께 나옵니다.
 
 링크가 걸린 페이지가 있는 페이지에서는 '''Backlinks''' 구역 밑에 저절로 붙습니다. 링크가 없는 페이지에서 쓰려면 원하는 자리에 직접 적습니다.
 
 == 누를 때만 찾는 이유
 찾는 일은 모든 페이지의 본문을 훑는 일입니다. 검색과 같은 일입니다. 페이지를 열 때마다 하면 모든 열람이 검색 한 번의 값을 치르므로, 매크로는 단추만 그리고 `GET /api/unlinkedMentions/<이름>` 은 누른 뒤에야 부릅니다. 단추 때문에 페이지가 느려지지는 않습니다.
 
 == 무엇이 나오고 무엇이 빠지나
- * 나오는 것: 본문에 이 페이지 이름이 대소문자 구분 없이 들어 있고, 이 페이지로 링크하지 않은 페이지. 검색이 준 순서(새로 고친 순) 그대로, 최대 50쪽.
+ * 나오는 것: 본문에 이 페이지 이름이 대소문자 구분 없이 '''따로 서 있고''', 이 페이지로 링크하지 않은 페이지. 검색이 준 순서(최근 수정순) 그대로, 최대 50쪽. 앞뒤 글은 찾은 바로 그 자리를 가운데로 잡습니다.
  * 빠지는 것: 이 페이지 자신, 이미 링크한 페이지, 이름에만 들어 있고 본문에는 없는 페이지(`Foo Bar` 는 `Foo` 의 언급이 아닙니다), 읽을 권한이 없는 페이지.
  * '''너무 짧거나 흔한 이름은 찾지 않습니다.''' 두 글자 이하의 이름은 위키의 절반에 들어 있고, 날짜 페이지(`2026-10-25`·`2026-10`·`2026`·`--10-25`)는 날짜가 적힌 모든 글에 들어 있습니다. 둘 다 잡음만 돌려주면서 전체 본문을 훑는 값을 치르게 합니다. 그 이름에서는 단추가 이유를 알려 줍니다.
 
 == 한계
  * '''검색이 읽는 행을 500개로 막아 두었습니다.''' 이름이 아주 흔하고 이미 링크한 페이지가 많으면, 링크 안 된 언급이 500개 바깥에 있을 수 있습니다. 그럴 수 있으면 «더 있을 수 있다» 고 알려 줍니다. 전문 색인이 아니라 `LIKE` 검색이라, 페이지가 아주 많은 위키에서는 느려질 수 있습니다.
- * '''이름이 그대로 들어 있는 글만 찾습니다.''' 조사가 붙은 한국어(`성운을`)는 `성운` 으로 찾으면 잡히지만, 별칭이나 철자가 다른 같은 대상은 못 찾습니다.
+ * '''더 긴 이름 속의 글자는 언급이 아닙니다.''' `Macro` 는 `MacroInclude`·`MacroPageMap` 에도 들어 있지만 그것은 다른 페이지 이름이므로, 영문자·숫자·밑줄이 이름에 바로 붙어 있으면 세지 않습니다. 괄호·쉼표·마침표·`/`·`-` 가 붙은 것은 셉니다. 한글은 이 규칙에서 뺐습니다 — 한국어는 명사에 조사가 붙어(`성운을`·`성운이`) 쓰므로 막으면 대부분의 언급을 놓칩니다. 그 대가로 더 긴 한국어 낱말 속의 이름은 잡힙니다.
+ * 별칭이나 철자가 다른 같은 대상은 못 찾습니다.
  * '''단추는 링크를 걸어 주지 않습니다.''' 어느 페이지를 열어 고칠지는 사람이 정합니다 — 본문을 자동으로 고치는 것은 사용자가 쓴 글을 바꾸는 일입니다.
 
 == 구현
  * 규칙(`UnlinkedMentions.of`)은 `Page.pageSearch` 가 이미 돌려주는 결과를 거르는 순수 함수입니다. 새 SQL 이 없습니다 — 테스트 데이터베이스(H2)는 검색이 쓰는 `COLLATE` 를 못 돌려서, 새 질의를 만들면 테스트할 수 없는 SQL 이 하나 늘기 때문입니다. `UnlinkedMentionsSpec` 이 규칙을 확인합니다.
  * 앞뒤 글은 `SearchSnippet` — [Api] 의 검색 응답과 같은 것입니다.
  * 결과는 `js.js` 가 `textContent` 로만 그립니다. 앞뒤 글은 다른 페이지의 본문이라, `innerHTML` 로 넣으면 그 페이지에 적힌 마크업이 이 페이지에서 살아납니다.
 
 == 관련
  * [MacroBacklinks]
  * [Api]