hanlint 0.0.18 โ 0.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -16
- package/data/calqueFrame.json +20 -20
- package/data/cliches.json +33 -33
- package/data/confusable.json +20 -20
- package/data/easyWords.json +12 -12
- package/data/exemplars.json +30 -30
- package/data/hiddenDeps.txt +11 -11
- package/data/japaneseLoan.json +27 -27
- package/data/koreanProse.txt +31 -31
- package/data/patterns.json +26 -26
- package/data/phraseRepeat.json +2 -2
- package/data/platformApis.txt +11 -11
- package/data/redundantPair.json +16 -16
- package/data/ruleDocs.json +56 -56
- package/data/screenNarration.json +10 -10
- package/data/screenSentence.json +12 -12
- package/data/screenTone.json +6 -6
- package/data/screenWord.json +70 -70
- package/data/spacing.json +11 -11
- package/data/spelling.json +29 -29
- package/data/translationese.json +23 -24
- package/data/usageCounts.report.json +2 -2
- package/data/version.json +1 -1
- package/package.json +1 -1
- package/src/analysis/grammar/ending.js +1 -1
- package/src/analysis/grammar/hangul.js +4 -4
- package/src/analysis/grammar/josa.js +1 -1
- package/src/analysis/grammar/register.js +1 -1
- package/src/analysis/grammar/voice.js +1 -1
- package/src/analysis/index.js +2 -2
- package/src/analysis/josa.js +1 -1
- package/src/analysis/splitSentences.js +1 -1
- package/src/analysis/tokenize.js +13 -13
- package/src/baseline/store.js +8 -8
- package/src/cli/help.js +11 -11
- package/src/cli/main.js +135 -124
- package/src/cli/walk.js +1 -1
- package/src/cli/welcome.js +8 -8
- package/src/config/loadConfig.js +3 -3
- package/src/config/patch.js +6 -6
- package/src/config/readerContract.js +26 -26
- package/src/config/settings.js +30 -28
- package/src/config/toml.js +9 -9
- package/src/data/exemplars.js +21 -21
- package/src/data/load.js +6 -6
- package/src/data/operations.js +14 -14
- package/src/data/patches.js +10 -10
- package/src/data/patterns.js +5 -5
- package/src/data/profiles.js +5 -5
- package/src/data/prose.js +5 -5
- package/src/document/model.js +4 -4
- package/src/document/parseMarkdown.js +7 -7
- package/src/document/plainText.js +3 -3
- package/src/document/sourceText.js +24 -24
- package/src/edit/applyFixes.js +0 -0
- package/src/fingerprint/build.js +6 -6
- package/src/fingerprint/codeBlocks.js +3 -3
- package/src/fingerprint/codeMarkers.js +4 -4
- package/src/fingerprint/dictionaries.js +7 -7
- package/src/fingerprint/markers.js +7 -7
- package/src/fingerprint/readerState.js +9 -9
- package/src/fingerprint/sourceSentence.js +1 -1
- package/src/fingerprint/topics.js +1 -1
- package/src/guard/contract.js +6 -6
- package/src/guard/editLocality.js +1 -1
- package/src/guard/outline.js +1 -1
- package/src/guard/receipt.js +13 -13
- package/src/guard/surface.js +4 -4
- package/src/index.js +6 -6
- package/src/learn/edits.js +2 -2
- package/src/learn/operations.js +1 -1
- package/src/regex.js +2 -2
- package/src/report/compactReport.js +3 -3
- package/src/report/fingerprintJson.js +2 -2
- package/src/report/githubReport.js +1 -1
- package/src/report/jsonReport.js +2 -2
- package/src/report/registerMatch.js +2 -2
- package/src/report/sheet.js +16 -16
- package/src/report/textReport.js +12 -12
- package/src/report/writingSpec.js +15 -15
- package/src/rules/code/inputFileSource.js +1 -1
- package/src/rules/code/installImport.js +2 -2
- package/src/rules/code/platformApi.js +1 -1
- package/src/rules/document/countMismatch.js +2 -1
- package/src/rules/document/enoughOnce.js +2 -1
- package/src/rules/document/fieldEcho.js +10 -6
- package/src/rules/document/keywordHeading.js +1 -1
- package/src/rules/document/keywordMissing.js +1 -1
- package/src/rules/document/noQuestion.js +2 -2
- package/src/rules/document/promiseRecall.js +1 -1
- package/src/rules/document/tableOddCell.js +1 -1
- package/src/rules/finding.js +4 -4
- package/src/rules/paragraph/factListParagraph.js +1 -1
- package/src/rules/paragraph/paraFragment.js +1 -1
- package/src/rules/readerDebt.js +1 -1
- package/src/rules/registry.js +26 -26
- package/src/rules/sentence/connectorRepeat.js +2 -1
- package/src/rules/sentence/danglingDeixis.js +1 -1
- package/src/rules/sentence/dash.js +1 -1
- package/src/rules/sentence/deixis.js +1 -1
- package/src/rules/sentence/doubleNegative.js +2 -1
- package/src/rules/sentence/doublePassive.js +2 -1
- package/src/rules/sentence/draftHistory.js +2 -1
- package/src/rules/sentence/endingRepeat.js +3 -2
- package/src/rules/sentence/euiChain.js +1 -1
- package/src/rules/sentence/fillerOpener.js +1 -1
- package/src/rules/sentence/imperativePeriod.js +1 -1
- package/src/rules/sentence/longSentence.js +1 -1
- package/src/rules/sentence/negationRedefine.js +1 -1
- package/src/rules/sentence/numberOrphan.js +1 -1
- package/src/rules/sentence/outsideProfile.js +8 -3
- package/src/rules/sentence/phraseRepeat.js +2 -1
- package/src/rules/shared/candidates.js +2 -2
- package/src/rules/shared/dictionaryRule.js +9 -2
- package/src/rules/shared/repeat.js +2 -2
- package/src/rules/structure/bridgeRepeat.js +3 -3
- package/src/rules/structure/emojiBullet.js +1 -1
- package/src/rules/structure/headingSkip.js +1 -1
- package/src/rules/structure/headingUniform.js +2 -1
- package/src/rules/structure/loneSubheading.js +1 -1
- package/src/rules/structure/moreLater.js +1 -1
- package/src/text.js +2 -2
- package/src/usage/counts.js +3 -3
- package/src/usage/index.js +3 -3
- package/src/usage/sentences.js +17 -17
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
/**
|
|
3
3
|
* ์์ค ํ์ผ์ ๊ธ ๋ง๋. ์ฌ๋์ด ์ฝ๋ ํ๊ตญ์ด ๋ฌธ์์ด ๋ฆฌํฐ๋ด๊ณผ JSX ๊ธ์ ์ค ๋ฒํธ์ ํจ๊ป ๋ฝ๋๋ค.
|
|
4
|
-
* ๋ป๊ณผ ๊ท์น์ ํ์ด์ฌ document/sourceText.py
|
|
4
|
+
* ๋ป๊ณผ ๊ท์น์ ํ์ด์ฌ document/sourceText.py๊ฐ ์ ํ๋ค. ์ฌ๊ธฐ๋ ๊ฐ์ ๊ฐ์ ๋ธ๋ค.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
export const SOURCE_SUFFIXES = [".js", ".jsx", ".mjs", ".cjs", ".ts", ".tsx", ".rs", ".py", ".html", ".htm", ".vue", ".svelte"];
|
|
8
|
-
/** ํ๊ทธ ์ฌ์ด ๊ธ๊ณผ ์์ฑ๊ฐ์ JSX
|
|
8
|
+
/** ํ๊ทธ ์ฌ์ด ๊ธ๊ณผ ์์ฑ๊ฐ์ JSX์ ๊ฐ์ ๊ธธ๋ก ์ฝ๋ ํ์ผ. HTML ์ฃผ์ `<!-- -->`์ ๊ฑท์ด๋ธ๋ค. */
|
|
9
9
|
const MARKUP_SUFFIXES = [".html", ".htm", ".vue", ".svelte"];
|
|
10
10
|
|
|
11
11
|
const KOREAN = /[๊ฐ-ํฃ]/;
|
|
12
|
-
// ๋ฌธ์์ด์ ๊ฒฝ๊ณ. ์ค์ ์์์๋ถํฐ ํ์ด ์ฌ๋ ๋ฐ์ดํ์์ ๊ฐ์ ๋ซ๋ ๋ฐ์ดํ๊น์ง๋ฅผ ํ ๋ง๋๋ก ๋ณธ๋ค. ํ์ด์ฌ sourceText.py
|
|
12
|
+
// ๋ฌธ์์ด์ ๊ฒฝ๊ณ. ์ค์ ์์์๋ถํฐ ํ์ด ์ฌ๋ ๋ฐ์ดํ์์ ๊ฐ์ ๋ซ๋ ๋ฐ์ดํ๊น์ง๋ฅผ ํ ๋ง๋๋ก ๋ณธ๋ค. ํ์ด์ฌ sourceText.py์ ๊ฐ๋ค.
|
|
13
13
|
const QUOTES = ["'", '"', "`"];
|
|
14
14
|
const BLOCK_COMMENT = /\/\*[\s\S]*?\*\//g;
|
|
15
15
|
const HTML_COMMENT = /<!--[\s\S]*?-->/g;
|
|
16
16
|
const DEVELOPER_LINE = /new Error\(|console\.|panic!\(|expect\(|assert/;
|
|
17
17
|
const RUST_CONTINUATION = /\\\r?\n[ \t]*/g;
|
|
18
18
|
const RUST_TEST_MARKER = "#[cfg(test)]";
|
|
19
|
-
/** ๋ฌธ์ฅ์ ๋์ง ์๋ HTML ์ธ๋ผ์ธ ํ๊ทธ. ๊ฐ์ ์ค์์ ์ด ํ๊ทธ๋ง ์ฌ์ด์ ๋ ๊ธ ์กฐ๊ฐ์ ํ ๋ง๋๋ก ์๋๋ค. ํ์ด์ฌ INLINE_TAGS
|
|
19
|
+
/** ๋ฌธ์ฅ์ ๋์ง ์๋ HTML ์ธ๋ผ์ธ ํ๊ทธ. ๊ฐ์ ์ค์์ ์ด ํ๊ทธ๋ง ์ฌ์ด์ ๋ ๊ธ ์กฐ๊ฐ์ ํ ๋ง๋๋ก ์๋๋ค. ํ์ด์ฌ INLINE_TAGS์ ๊ฐ๋ค. */
|
|
20
20
|
const INLINE_TAGS = new Set("a abbr b bdi bdo cite code data del dfn em i ins kbd mark q s samp small span strong sub sup time u var wbr br".split(" "));
|
|
21
21
|
const INLINE_TAG = /<\/?([a-zA-Z][a-zA-Z0-9]*)[^<>]*>/g;
|
|
22
22
|
const INLINE_GAP = /^(?:\s*<\/?[a-zA-Z][a-zA-Z0-9]*[^<>]*>)+\s*$/;
|
|
@@ -32,11 +32,11 @@ const HEAD_TEXT = /^\s*[^<\s][^<]*(?=<\/)/;
|
|
|
32
32
|
* @typedef {object} SourceLiteral
|
|
33
33
|
* @property {number} line 1๋ถํฐ ์ธ๋ ์ค ๋ฒํธ. ์ฌ๋ฌ ์ค์ ์ด์ ๋ฌ์คํธ ๋ฌธ์์ด์ ์์ ์ค์ด๋ค
|
|
34
34
|
* @property {string} text ๋ฐ์ดํ์ ํ๊ทธ๋ฅผ ๋บ ๊ธ. ํ์ผ์ ์๋ ๊ทธ๋๋ก๋ผ ๋๋๋ ค ์ธ ๋ ์ฐพ์ ์ ์๋ค
|
|
35
|
-
* @property {string} plain ๊ฒ์ฌ์ ์ฐ๋ ๊ธ. ์
|
|
36
|
-
* @property {number} column 1๋ถํฐ ์ธ๋ ์นธ. ๊ทธ ์ค์์ text
|
|
35
|
+
* @property {string} plain ๊ฒ์ฌ์ ์ฐ๋ ๊ธ. ์(`${...}`, `{...}`)์ ๋น์ฐ๊ณ ๊ณต๋ฐฑ์ ํ๋๋ก ๋ชจ์๋ค
|
|
36
|
+
* @property {number} column 1๋ถํฐ ์ธ๋ ์นธ. ๊ทธ ์ค์์ text๊ฐ ์์ํ๋ ์์น
|
|
37
37
|
*/
|
|
38
38
|
|
|
39
|
-
/** `start
|
|
39
|
+
/** `start`์ `{`๋ฅผ ๋ซ๋ `}`์ ์์น. ๋ป์ ํ์ด์ฌ balancedEnd๊ฐ ์ ํ๋ค. @param {string} line @param {number} start */
|
|
40
40
|
function balancedEnd(line, start) {
|
|
41
41
|
let depth = 0;
|
|
42
42
|
let index = start;
|
|
@@ -58,7 +58,7 @@ function balancedEnd(line, start) {
|
|
|
58
58
|
return -1;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
/** ๊ธ์ ๋ ์ `{...}
|
|
61
|
+
/** ๊ธ์ ๋ ์ `{...}`์ `${...}`์ [์์, ๋ ๋ค์]. ๋ป์ ํ์ด์ฌ expressionSpans๊ฐ ์ ํ๋ค. @param {string} text @returns {[number, number][]} */
|
|
62
62
|
export function expressionSpans(text) {
|
|
63
63
|
/** @type {[number, number][]} */
|
|
64
64
|
const spans = [];
|
|
@@ -77,7 +77,7 @@ export function expressionSpans(text) {
|
|
|
77
77
|
return spans;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
/** ํ
ํ๋ฆฟ ๋ฆฌํฐ๋ด์ `${ ... }` ์์ ๊ฐ์ ๊ธธ์ด์ ๋น์นธ์ผ๋ก ๋ฐ๊พผ๋ค. ๋ป์ ํ์ด์ฌ withoutTemplateExpressions
|
|
80
|
+
/** ํ
ํ๋ฆฟ ๋ฆฌํฐ๋ด์ `${ ... }` ์์ ๊ฐ์ ๊ธธ์ด์ ๋น์นธ์ผ๋ก ๋ฐ๊พผ๋ค. ๋ป์ ํ์ด์ฌ withoutTemplateExpressions๊ฐ ์ ํ๋ค. @param {string} source */
|
|
81
81
|
export function withoutTemplateExpressions(source) {
|
|
82
82
|
let output = source;
|
|
83
83
|
for (const [start, end] of expressionSpans(source)) {
|
|
@@ -107,8 +107,8 @@ export function userFacingSource(source, path) {
|
|
|
107
107
|
|
|
108
108
|
|
|
109
109
|
/**
|
|
110
|
-
* ๋ฐ์ดํ ๋ฐ์
|
|
111
|
-
* ๋ป์ ํ์ด์ฌ document/sourceText.py
|
|
110
|
+
* ๋ฐ์ดํ ๋ฐ์ `//`๋ถํฐ ์๋ฅธ๋ค. `https://`์ฒ๋ผ `:` ๋ค์ `//`๋ ์ฃผ์๋ผ ๋๊ณ , ๋ฌธ์์ด ์์ `//`๋ ๋๋ค.
|
|
111
|
+
* ๋ป์ ํ์ด์ฌ document/sourceText.py์ withoutLineComment๊ฐ ์ ํ๋ค.
|
|
112
112
|
*/
|
|
113
113
|
export function withoutLineComment(line) {
|
|
114
114
|
let quote = null;
|
|
@@ -132,12 +132,12 @@ export function plainText(text) {
|
|
|
132
132
|
cursor = end;
|
|
133
133
|
}
|
|
134
134
|
plain += text.slice(cursor);
|
|
135
|
-
// ์ธ๋ผ์ธ ํ๊ทธ๋ฅผ ๋น์ด๋ค. ์ด๋ฆ์ด ์๋ฌธ์๋ก ์์ํ๋ ๊ฒ๋ง์ด๋ผ `<๋์>
|
|
135
|
+
// ์ธ๋ผ์ธ ํ๊ทธ๋ฅผ ๋น์ด๋ค. ์ด๋ฆ์ด ์๋ฌธ์๋ก ์์ํ๋ ๊ฒ๋ง์ด๋ผ `<๋์> ํ์`์ ๊บพ์ ๋ ๋จ๋๋ค.
|
|
136
136
|
plain = plain.replace(INLINE_TAG, (tag, name) => (INLINE_TAGS.has(name.toLowerCase()) ? "" : tag));
|
|
137
137
|
return plain.replace(/\s+/g, " ").trim();
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
/** `start
|
|
140
|
+
/** `start`์ ๋ฐ์ดํ๋ฅผ ๋ซ๋ ์์น. ๋ฐฑํฑ ์์ `${...}`์ ํต์งธ๋ก ๊ฑด๋๋ด๋ค. ๋ป์ ํ์ด์ฌ closingQuote๊ฐ ์ ํ๋ค. @param {string} line @param {number} start */
|
|
141
141
|
function closingQuote(line, start) {
|
|
142
142
|
const quote = line[start];
|
|
143
143
|
let index = start + 1;
|
|
@@ -159,14 +159,14 @@ function closingQuote(line, start) {
|
|
|
159
159
|
return -1;
|
|
160
160
|
}
|
|
161
161
|
|
|
162
|
-
/** `index
|
|
162
|
+
/** `index`์ `>`๊ฐ JSX ์ฌ๋ ํ๊ทธ์ ๋์ธ๊ฐ. ๋ป์ ํ์ด์ฌ tagCloses๊ฐ ์ ํ๋ค. @param {string} line @param {number} index */
|
|
163
163
|
function tagCloses(line, index) {
|
|
164
164
|
if (index === 0 || line[index + 1] === "=") return false;
|
|
165
165
|
const before = line[index - 1];
|
|
166
166
|
return "\"'}".includes(before) || /[A-Za-z0-9]/.test(before);
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
-
/** `start
|
|
169
|
+
/** `start`๋ถํฐ์ JSX ๊ธ์ด ๋๋๋ `<`์ ์์น. ์ ์์ `<`๋ ๊ธ์ ๋์ด ์๋๋ค. ๋ป์ ํ์ด์ฌ jsxTextEnd๊ฐ ์ ํ๋ค. @param {string} line @param {number} start */
|
|
170
170
|
function jsxTextEnd(line, start) {
|
|
171
171
|
let index = start;
|
|
172
172
|
while (index < line.length) {
|
|
@@ -183,7 +183,7 @@ function jsxTextEnd(line, start) {
|
|
|
183
183
|
return -1;
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
-
/** ๊ธ์ ๋ ์ ์์ ๊ธ ๋ง๋. ๋ป์ ํ์ด์ฌ innerLiterals
|
|
186
|
+
/** ๊ธ์ ๋ ์ ์์ ๊ธ ๋ง๋. ๋ป์ ํ์ด์ฌ innerLiterals๊ฐ ์ ํ๋ค. @param {string} text @param {number} offset @returns {[number, string][]} */
|
|
187
187
|
function innerLiterals(text, offset) {
|
|
188
188
|
/** @type {[number, string][]} */
|
|
189
189
|
const found = [];
|
|
@@ -194,10 +194,10 @@ function innerLiterals(text, offset) {
|
|
|
194
194
|
return found;
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
-
/** ํ ์ค์ ๊ธ ๋ง๋๋ฅผ [์์
|
|
197
|
+
/** ํ ์ค์ ๊ธ ๋ง๋๋ฅผ [์์ ์์น, ๊ธ]๋ก ๋์จ ์ฐจ๋ก๋ก. ๋ป์ ํ์ด์ฌ lineLiterals๊ฐ ์ ํ๋ค. @param {string} line @param {number} [offset] @returns {[number, string][]} */
|
|
198
198
|
/**
|
|
199
|
-
* openEnded
|
|
200
|
-
* ๋ป์ ํ์ด์ฌ lineLiterals
|
|
199
|
+
* openEnded(๋งํฌ์
ํ์ผ)์ด๋ฉด ์ฌ๋ ํ๊ทธ ๋ค ์ค ๋๊น์ง์ ๊ธ๊ณผ ์ค ์ฒ์๋ถํฐ ๋ซ๋ ํ๊ทธ ์๊น์ง์ ๊ธ๋ ๋ง๋๋ค.
|
|
200
|
+
* ๋ป์ ํ์ด์ฌ lineLiterals๊ฐ ์ ํ๋ค.
|
|
201
201
|
* @param {string} line @param {number} [offset] @param {boolean} [openEnded]
|
|
202
202
|
*/
|
|
203
203
|
export function lineLiterals(line, offset = 0, openEnded = false) {
|
|
@@ -239,7 +239,7 @@ export function lineLiterals(line, offset = 0, openEnded = false) {
|
|
|
239
239
|
|
|
240
240
|
/**
|
|
241
241
|
* ์ฌ์ด๊ฐ ์ธ๋ผ์ธ ํ๊ทธ๋ฟ์ธ ํ๊ทธ ์ฌ์ด ๊ธ ์กฐ๊ฐ์ ํ ๋ง๋๋ก ์๋๋ค. ํ๊ทธ ์์ ์์ฑ ๋ฌธ์์ด์ ์๊ธฐ์ ๋ผ์ง ์๊ณ ์ ๋ง๋๋ก ๋จ๋๋ค.
|
|
242
|
-
* ๋ป์ ํ์ด์ฌ joinInline
|
|
242
|
+
* ๋ป์ ํ์ด์ฌ joinInline์ด ์ ํ๋ค.
|
|
243
243
|
* @param {string} line @param {[number, string][]} found @param {number} offset @returns {[number, string][]}
|
|
244
244
|
*/
|
|
245
245
|
function joinInline(line, found, offset) {
|
|
@@ -263,13 +263,13 @@ function joinInline(line, found, offset) {
|
|
|
263
263
|
return [...joined, ...attributes].sort((a, b) => a[0] - b[0]);
|
|
264
264
|
}
|
|
265
265
|
|
|
266
|
-
/** position
|
|
266
|
+
/** position์ด ํ๊ทธ ์(`<` ๋ค, `>` ์)์ธ๊ฐ. @param {string} line @param {number} position */
|
|
267
267
|
function insideTag(line, position) {
|
|
268
268
|
const opened = line.lastIndexOf("<", position - 1);
|
|
269
269
|
return opened >= 0 && line.lastIndexOf(">", position - 1) < opened;
|
|
270
270
|
}
|
|
271
271
|
|
|
272
|
-
/** ์ฌ์ด๊ฐ ์ธ๋ผ์ธ ํ๊ทธ๋ฟ์ด๊ณ ํ์
|
|
272
|
+
/** ์ฌ์ด๊ฐ ์ธ๋ผ์ธ ํ๊ทธ๋ฟ์ด๊ณ ํ์ (`</a><a>`)๊ฐ ์๋๋ค. @param {string} gap */
|
|
273
273
|
function inlineOnly(gap) {
|
|
274
274
|
if (!INLINE_GAP.test(gap) || SIBLING_GAP.test(gap)) return false;
|
|
275
275
|
return [...gap.matchAll(INLINE_TAG)].every((match) => INLINE_TAGS.has(match[1].toLowerCase()));
|
|
@@ -280,7 +280,7 @@ export function sourceLiterals(source, path = "") {
|
|
|
280
280
|
/** @type {SourceLiteral[]} */
|
|
281
281
|
const found = [];
|
|
282
282
|
const markup = MARKUP_SUFFIXES.some((suffix) => path.endsWith(suffix));
|
|
283
|
-
// ๋งํฌ์
์ ์ฃผ์ ์ง์ฐ๊ธฐ๊ฐ ์ค ์๋ฅผ ์งํค๋ฏ๋ก ์๋ฌธ ์ค๊ณผ ๋๋ํ ๊ฐ๋ค. script ๋ธ๋ก ํ์ ์ ์๋ฌธ ์ค๋ก ํ๋ค (`// ์ฃผ์</script
|
|
283
|
+
// ๋งํฌ์
์ ์ฃผ์ ์ง์ฐ๊ธฐ๊ฐ ์ค ์๋ฅผ ์งํค๋ฏ๋ก ์๋ฌธ ์ค๊ณผ ๋๋ํ ๊ฐ๋ค. script ๋ธ๋ก ํ์ ์ ์๋ฌธ ์ค๋ก ํ๋ค (`// ์ฃผ์</script>`๊ฐ ์ง์์ ธ๋).
|
|
284
284
|
const rawLines = markup ? source.split("\n") : [];
|
|
285
285
|
let inCode = false;
|
|
286
286
|
userFacingSource(source, path).split("\n").forEach((line, index) => {
|
|
@@ -304,7 +304,7 @@ export function sourceLiterals(source, path = "") {
|
|
|
304
304
|
}
|
|
305
305
|
|
|
306
306
|
/**
|
|
307
|
-
* ํ ์ค ์์์ ๊ธ `old
|
|
307
|
+
* ํ ์ค ์์์ ๊ธ `old`๋ฅผ `new`๋ก ๋ฐ๊พผ๋ค. ๋ช ๋ฒ ๋์๋์ง ๊ฐ์ด ์ค๋ค (ํ ๋ฒ์ผ ๋๋ง ๋ฐ๊พผ ๊ฒ์ด ํ์ ์ด๋ค).
|
|
308
308
|
* @param {string} lineText @param {string} oldText @param {string} newText @returns {[string, number]}
|
|
309
309
|
*/
|
|
310
310
|
export function replaceLiteral(lineText, oldText, newText) {
|
package/src/edit/applyFixes.js
CHANGED
|
Binary file
|
package/src/fingerprint/build.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
-
/** ๋ฌธ์ ๋ชจ๋ธ์ ํ ๋ฒ ํ์ด ๊ธ
|
|
2
|
+
/** ๋ฌธ์ ๋ชจ๋ธ์ ํ ๋ฒ ํ์ด ๊ธ ๋ถ์ ๊ฒฐ๊ณผ๋ฅผ ๋ง๋ ๋ค. ํ
์คํธ๋ฅผ ์ฝ๋ ๊ณณ์ ์ฌ๊ธฐ ํ๋๋ค. ํ์ด์ฌ fingerprint/build.py์ ๊ฐ๋ค. */
|
|
3
3
|
import { defaultConfig } from "../config/settings.js";
|
|
4
4
|
import { NONE as NO_REGISTER, documentRegister, lastWord, registerOfWord } from "../analysis/grammar/register.js";
|
|
5
5
|
import { doublePassiveSpans, euiCount, longestNounRun, splitSentences } from "../analysis/index.js";
|
|
@@ -88,9 +88,9 @@ import { overlap, topicsOf, unionOf } from "./topics.js";
|
|
|
88
88
|
* @property {number} readerCallCount
|
|
89
89
|
* @property {[number, string, number, string][]} countPromises (์, ๋จ์, ์ค, ์๋ฌธ)
|
|
90
90
|
* @property {import("./codeBlocks.js").CodeBlock[]} codeBlocks ์ฝ๋ ํ์ค๋ฅผ ์ธ์ด์ ๋ณธ๋ฌธ ์ค๋ก ํผ ๊ฒ
|
|
91
|
-
* @property {import("./readerState.js").ReaderTrail} reader
|
|
91
|
+
* @property {import("./readerState.js").ReaderTrail} reader ์์น๋ง๋ค์ ๋
์ ์ํ. ์ฝ์ํ๋ ๋ง๊ณผ ๋ค์ ๋ค๋ฃจ๋ ๋ง์ final์ ์๋ค
|
|
92
92
|
* @property {[string, number, number][]} disabled
|
|
93
|
-
* @property {import("../document/model.js").Block[]} ignored ์ค์ ์ด
|
|
93
|
+
* @property {import("../document/model.js").Block[]} ignored ์ค์ ์ด ๊ธ ๋ถ์์์ ๋บ ํ์ค
|
|
94
94
|
* @property {string} register
|
|
95
95
|
* @property {number} registerShare
|
|
96
96
|
* @property {SectionPrint} intro
|
|
@@ -131,7 +131,7 @@ function makeSentencePrint(build, text, line, block, sectionIndex, quoted) {
|
|
|
131
131
|
const { entries } = build;
|
|
132
132
|
const ending = markers.endingOf(text);
|
|
133
133
|
const protectedSpans = markers.termSpans(text, build.protectedTerms);
|
|
134
|
-
// ์ธ์ฉ ์์ ๊ฒ๊ณผ ๋ณดํธํ ์ฉ์ด์ ๊ฑธ์น ๊ฒ์ ๋บ๋ค. ๋ป์ ํ์ด์ฌ fingerprint/build.py
|
|
134
|
+
// ์ธ์ฉ ์์ ๊ฒ๊ณผ ๋ณดํธํ ์ฉ์ด์ ๊ฑธ์น ๊ฒ์ ๋บ๋ค. ๋ป์ ํ์ด์ฌ fingerprint/build.py์ kept๊ฐ ์ ํ๋ค.
|
|
135
135
|
/** @param {number} start @param {number} end */
|
|
136
136
|
const kept = (start, end) => !markers.insideAny(start, end, quoted) && !markers.overlapsAny(start, end, protectedSpans);
|
|
137
137
|
const deixis = markers
|
|
@@ -233,7 +233,7 @@ function buildSection(build, section, sectionIndex) {
|
|
|
233
233
|
const line = block.startLine + countIn(text, "\n", sentence.start);
|
|
234
234
|
const quoted = quotedIn(sentence, blockSpans);
|
|
235
235
|
const made = makeSentencePrint(build, sentence.text, line, block, sectionIndex, quoted);
|
|
236
|
-
// ๋ง๋
|
|
236
|
+
// ๋ง๋ ๊ณณ์์ ๋ฐ๋ก ์๋๋ค. ๋ค์ ๋ฌธ์ฅ์ index๊ฐ ์ด ๊ธธ์ด์์ ๋์ค๋ฏ๋ก ๋ฏธ๋ฃจ๋ฉด ์
์ด ์ด๊ธ๋๋ค.
|
|
237
237
|
sentences.push(made);
|
|
238
238
|
blockSentences.push(made);
|
|
239
239
|
}
|
|
@@ -269,7 +269,7 @@ function buildSection(build, section, sectionIndex) {
|
|
|
269
269
|
* @returns {DocumentPrint}
|
|
270
270
|
*/
|
|
271
271
|
export function buildFingerprint(doc, config = defaultConfig()) {
|
|
272
|
-
// ์ฝ๋๋ ์ฐ๋ฌธ๋ ์๋ ํ์ค๋
|
|
272
|
+
// ์ฝ๋๋ ์ฐ๋ฌธ๋ ์๋ ํ์ค๋ ๋ถ์์ ๋ค์ด์ค๊ธฐ ์ ์ ๋บ๋ค. ๋ชจ๋ ์ง์
์ ์ด ์ฌ๊ธฐ๋ฅผ ์ง๋๋ฏ๋ก ํ ๊ณณ์ด๋ฉด ๋๋ค.
|
|
273
273
|
doc = dropFences(doc, config.ignoreFences);
|
|
274
274
|
const build = {
|
|
275
275
|
entries: entriesFor(config),
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
/**
|
|
3
|
-
* ์ฝ๋ ๋ธ๋ก์ ์ธ์ด์ ๋ณธ๋ฌธ์ผ๋ก ๋๋๋ค.
|
|
4
|
-
* ์ฝ๋๋ค. ํ์ด์ฌ fingerprint/codeBlocks.py
|
|
5
|
-
* ํ์ค ์ฒซ ์ค์ ์ธ์ด ํ๊ธฐ
|
|
3
|
+
* ์ฝ๋ ๋ธ๋ก์ ์ธ์ด์ ๋ณธ๋ฌธ์ผ๋ก ๋๋๋ค. ๊ธ ๋ถ์์ด ํ ๋ฒ ๋ง๋ค๊ณ (DocumentPrint.codeBlocks) code ๋ฌถ์ ๊ท์น๊ณผ ๋
์ ์ํ๊ฐ
|
|
4
|
+
* ์ฝ๋๋ค. ํ์ด์ฌ fingerprint/codeBlocks.py์ ๊ฐ๋ค.
|
|
5
|
+
* ํ์ค ์ฒซ ์ค์ ์ธ์ด ํ๊ธฐ(```python)๋ฅผ ์ฝ๊ณ ๋ณธ๋ฌธ ์ค์ ์๋ฌธ ์ค ๋ฒํธ๋ฅผ ๋ถ์ธ๋ค. text ํ์ค๋ ์ถ๋ ฅ์ด๋ค.
|
|
6
6
|
*/
|
|
7
7
|
import { CODE } from "../document/model.js";
|
|
8
8
|
import { fenceLanguage } from "../document/parseMarkdown.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
/**
|
|
3
3
|
* ์ฝ๋ ์ค์์ ํ์ผ์ ๊ณต๊ธ๊ณผ ์์๋ฅผ ์ฝ๋๋ค. ์ด๋ค ์ค์ด ํ์ผ์ ๋ง๋ค๊ณ (์ฐ๊ธฐ, ํด๋ ๋ง๋ค๊ธฐ) ์ด๋ค ์ค์ด ํ์ผ์ ์ฝ๋๊ฐ.
|
|
4
|
-
* ํ์ด์ฌ fingerprint/codeMarkers.py
|
|
4
|
+
* ํ์ด์ฌ fingerprint/codeMarkers.py์ ๊ฐ๋ค. ์ค๋ง๋ค ๋์กฐํ๋ฏ๋ก ์ฌ๋ฌ ์ค์ ๊ฑธ์น ํธ์ถ์ ๋ณด์ง ์๋๋ค.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
const QUOTED = "\\(\\s*[\"']([^\"'\\n]+)[\"']";
|
|
@@ -19,7 +19,7 @@ const WRITES = new RegExp(
|
|
|
19
19
|
const SHELL_WRITES = /(?:>>?|-o|-O|--output|Out-File)\s*["']?([\w./\\-]+\.[A-Za-z0-9]+)/g;
|
|
20
20
|
const SQL_PATHS = /FROM\s+'([^']+\.(?:csv|parquet|json|xlsx))'/gi;
|
|
21
21
|
const MAKES_DIR = /(?:mkdir(?:\s+-p)?|makedirs|md)\s*\(?\s*["']?([\w./\\-]+)|Path\(\s*["']([^"']+)["']\s*\)\.mkdir/g;
|
|
22
|
-
/** open
|
|
22
|
+
/** open์ ๋ชจ๋์ ์ด ๊ธ์๊ฐ ์์ผ๋ฉด ์ฐ๊ธฐ๋ค. ์์ผ๋ฉด (๊ธฐ๋ณธ r) ์ฝ๊ธฐ๋ค. */
|
|
23
23
|
const WRITE_MODES = [..."wax"];
|
|
24
24
|
|
|
25
25
|
/** @param {string} path */
|
|
@@ -41,7 +41,7 @@ function all(pattern, text, group) {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
|
-
* ์ฝ๋ ์ค๋ค์ด ๋ง๋๋ [ํ์ผ ์ด๋ฆ, ํด๋ ์ด๋ฆ]. ์ฐ๊ธฐ ํจ์, ์
ธ ๋ฆฌ๋ค์ด๋ ์
, ์ฐ๊ธฐ ๋ชจ๋์ open, mkdir
|
|
44
|
+
* ์ฝ๋ ์ค๋ค์ด ๋ง๋๋ [ํ์ผ ์ด๋ฆ, ํด๋ ์ด๋ฆ]. ์ฐ๊ธฐ ํจ์, ์
ธ ๋ฆฌ๋ค์ด๋ ์
, ์ฐ๊ธฐ ๋ชจ๋์ open, mkdir ํธ์ถ์ ๋ณธ๋ค.
|
|
45
45
|
* @param {string[]} lines
|
|
46
46
|
* @returns {[Set<string>, Set<string>]}
|
|
47
47
|
*/
|
|
@@ -59,7 +59,7 @@ export function createdIn(lines) {
|
|
|
59
59
|
return [files, dirs];
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
/** ํ ์ค์ด ์ฝ๋ ๊ฒฝ๋ก. ์ฝ๊ธฐ ํจ์, ์ฝ๊ธฐ ๋ชจ๋์ open, SQL
|
|
62
|
+
/** ํ ์ค์ด ์ฝ๋ ๊ฒฝ๋ก. ์ฝ๊ธฐ ํจ์, ์ฝ๊ธฐ ๋ชจ๋์ open, SQL์ FROM ์ฐจ๋ก๋ค. @param {string} code */
|
|
63
63
|
export function readsIn(code) {
|
|
64
64
|
const reads = all(READS, code, 1);
|
|
65
65
|
for (const match of code.matchAll(OPENS)) if (!isWriteMode(match[2])) reads.push(match[1]);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
-
/** ์ฌ์ ๋ค์ ํ ๋ฒ ์ปดํ์ผํ๊ณ ๋ฌธ์ฅ์์ ๋ง๋
|
|
2
|
+
/** ์ฌ์ ๋ค์ ํ ๋ฒ ์ปดํ์ผํ๊ณ ๋ฌธ์ฅ์์ ๋ง๋ ๋ถ๋ถ์ ์ฐพ๋๋ค. ์ค์ ์ dictionary ํญ๋ชฉ์ ๋ํ๋ค. */
|
|
3
3
|
import { loadEntries } from "../data/load.js";
|
|
4
4
|
import { compile } from "../regex.js";
|
|
5
5
|
|
|
@@ -20,11 +20,11 @@ export const DICTIONARY_FILES = {
|
|
|
20
20
|
};
|
|
21
21
|
const GROUP_REF = /\$(\d)/g;
|
|
22
22
|
const FINALS = { ใด: 4, ใน: 8 };
|
|
23
|
-
// {์กฐ์ฌ} ์๋ฆฌํ์์.
|
|
23
|
+
// {์กฐ์ฌ} ์๋ฆฌํ์์. ๋จ์ด ๋ค์ ์กฐ์ฌ๊ฐ ๋ถ์๊ฑฐ๋ ๋จ์ด๊ฐ ๋๋๋ ๊ณณ. ํ์ด์ฌ dictionaries.py์ ๊ฐ์ ๊ธ์๋ค.
|
|
24
24
|
const JOSA_TAIL = "(?=(?:์์๋|์ผ๋ก๋|์์|์๊ฒ|๊น์ง|๋ถํฐ|๋ณด๋ค|์ฒ๋ผ|์ผ๋ก|์ด๋|์|๋|์ด|๊ฐ|์|๋ฅผ|์|์|๋ก|์|๊ณผ|๋|๋ง)?(?![๊ฐ-ํฃ]))";
|
|
25
25
|
const PLACEHOLDER = /\{(ใด|ใน|์กฐ์ฌ)\}/g;
|
|
26
26
|
|
|
27
|
-
/** ๋ฐ์นจ์ผ๋ก ๋๋๋ ์์ 399๊ฐ์
|
|
27
|
+
/** ๋ฐ์นจ์ผ๋ก ๋๋๋ ์์ 399๊ฐ์ ๊ธ์ ์งํฉ. @param {"ใด" | "ใน"} final */
|
|
28
28
|
function syllableClass(final) {
|
|
29
29
|
let chars = "";
|
|
30
30
|
for (let initial = 0; initial < 19; initial++) {
|
|
@@ -46,8 +46,8 @@ export function expandClasses(pattern) {
|
|
|
46
46
|
* @property {string} source
|
|
47
47
|
* @property {string | null} fix
|
|
48
48
|
* @property {{ pattern: import("../regex.js").Pattern, into: string }[]} to ๋ฌธ์ฅ ์ ์ฒด๋ฅผ ๋ค์ ์ฐ๋ ๊ท์น. ์์ ๊ฒ๋ถํฐ ์๋ํ๋ค
|
|
49
|
-
* @property {string} raw pattern
|
|
50
|
-
* @property {import("../regex.js").Pattern | null} unless ๋ฌธ์ฅ ์ ์ฒด์์ ์ด๊ฒ์ด ๋ง์ผ๋ฉด ๊ทธ ๋ฌธ์ฅ์์๋ ํญ๋ชฉ์ด ๋ง์ง ์๋๋ค. ํ์ด์ฌ Entry.unless
|
|
49
|
+
* @property {string} raw pattern์ ์๋ฌธ. ๋ด์ฅ ํญ๋ชฉ๋ง ๊ฐ๊ณ ์ค์ ํญ๋ชฉ์ ๋น ๊ธ์๋ผ ๊ด์ฉ์ผ๋ก ์ ํ์ง ์๋๋ค
|
|
50
|
+
* @property {import("../regex.js").Pattern | null} unless ๋ฌธ์ฅ ์ ์ฒด์์ ์ด๊ฒ์ด ๋ง์ผ๋ฉด ๊ทธ ๋ฌธ์ฅ์์๋ ํญ๋ชฉ์ด ๋ง์ง ์๋๋ค. ํ์ด์ฌ Entry.unless์ ๊ฐ๋ค
|
|
51
51
|
*/
|
|
52
52
|
|
|
53
53
|
/**
|
|
@@ -96,7 +96,7 @@ export function entriesFor(config) {
|
|
|
96
96
|
const extra = [];
|
|
97
97
|
for (const [dictionary, items] of Object.entries(config.dictionary)) {
|
|
98
98
|
if (!(dictionary in DICTIONARY_FILES)) {
|
|
99
|
-
throw new Error(`๋ชจ๋ฅด๋ ์ฌ์ : ${dictionary}. ${Object.keys(DICTIONARY_FILES).join(", ")}
|
|
99
|
+
throw new Error(`๋ชจ๋ฅด๋ ์ฌ์ : ${dictionary}. ์ธ ์ ์๋ ์ด๋ฆ: ${Object.keys(DICTIONARY_FILES).join(", ")}`);
|
|
100
100
|
}
|
|
101
101
|
for (const raw of items) extra.push(entryFrom(dictionary, /** @type {Record<string, unknown> | string} */ (raw)));
|
|
102
102
|
}
|
|
@@ -110,7 +110,7 @@ export function applyFix(match, fix) {
|
|
|
110
110
|
|
|
111
111
|
/**
|
|
112
112
|
* to ๊ท์น์ผ๋ก ๋ฌธ์ฅ์ ๋ค์ ์ด๋ค. ๋น ๊ทธ๋ฃน์ด ๋จ๊ธด ๊ฒน ๊ณต๋ฐฑ์ ํ๋๋ก ์ค์ด๊ณ ์๋์ ๋ค๋ฌ๋๋ค. ์๋ฌธ๊ณผ ๊ฐ์ผ๋ฉด null.
|
|
113
|
-
* ๋ป์ ํ์ด์ฌ fingerprint/dictionaries.py
|
|
113
|
+
* ๋ป์ ํ์ด์ฌ fingerprint/dictionaries.py์ rewriteBy๊ฐ ์ ํ๋ค.
|
|
114
114
|
* @param {string} text @param {Entry["to"]} rules
|
|
115
115
|
*/
|
|
116
116
|
export function rewriteBy(text, rules) {
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
/**
|
|
3
|
-
* ๋ฌธ์ฅ์์
|
|
4
|
-
*
|
|
3
|
+
* ๋ฌธ์ฅ์์ ์ ํด ๋ ๋ง์ ์ผ๋ค. ์ข
๊ฒฐ์ด๋ฏธ ๋ฌถ์, ์๋ฒ, ์ ์๋ถ์ฌ, ์ธ๊ณผ ์ ์์ฌ, ์ง์์ด, ์ผ๋ฒ๋ฌด๋ฆฌ๋ ๋ง, ์ฝ์ํ๋ ๋ง๊ณผ ๋ค์ ๋ค๋ฃจ๋ ๋ง, ๋
์ ํธ์ถ, ์ ์ฝ์.
|
|
4
|
+
* ๋จ์ด ๋ชฉ๋ก์ ๋ชจ๋ data/์ ์๋ค. ํ์ด์ฌ fingerprint/markers.py์ ๊ฐ๋ค.
|
|
5
5
|
*/
|
|
6
6
|
import { loadLines, loadPatterns } from "../data/load.js";
|
|
7
7
|
import { compile, escape } from "../regex.js";
|
|
8
8
|
|
|
9
9
|
const TRAILING = /[\s.?!"'โโ)\]]+$/;
|
|
10
10
|
const NUMBER = /\d+(?:[.,]\d+)*/g;
|
|
11
|
-
/** ๊ฐ์ผ๋ก
|
|
11
|
+
/** ๊ฐ์ผ๋ก ๋น๊ตํ๋ ์. NUMBER๋ ์์ ๊ฐ์๋ฅผ ์ธ๊ณ ์ด๊ฒ์ ์์ ์ ์ฒด๋ฅผ ์ผ๋ค. ์ฒ ๋จ์ ์ผํ๊น์ง ํ ์๋ก ์ฝ๋๋ค. */
|
|
12
12
|
const NUMERAL = /\d[\d,]*(?:\.\d+)?/g;
|
|
13
13
|
const COMMA = /,/g;
|
|
14
14
|
// ๋ฐ์ดํ ์. ์์ ์ฌ์ฉ์ด ์๋๋ผ ์ธ์ฉ์ด๋ค. ์์๋ฐ์ดํ๋ ์์ด ๋ฌธ์ฅ ์ฒซ๋จธ๋ฆฌ๋ ๊ณต๋ฐฑ์ด๋ ์ฌ๋ ๊ดํธ์ผ ๋๋ง.
|
|
@@ -27,7 +27,7 @@ const OPTIONAL_SPACE = /\s?/.source;
|
|
|
27
27
|
|
|
28
28
|
/** @type {Record<string, number> | null} */
|
|
29
29
|
let numberCache = null;
|
|
30
|
-
/** ์์ฌ โ ๊ฐ.
|
|
30
|
+
/** ์์ฌ โ ๊ฐ. ๋ชฉ๋ก์ data/koreanNumbers.txt์ ์๋ค. */
|
|
31
31
|
export function koreanNumbers() {
|
|
32
32
|
if (!numberCache) {
|
|
33
33
|
numberCache = {};
|
|
@@ -148,7 +148,7 @@ export function quoteSpans(text) {
|
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
/**
|
|
151
|
-
* ์ค์ ์ protectedTerms
|
|
151
|
+
* ์ค์ ์ protectedTerms๊ฐ ๊ธ์ ๋์จ [์์, ๋] ์ ๋ถ. ๊ฒน์ณ ๋์จ ๊ฒ๋ ๋ฐ๋ก ์ผ๋ค. ํ์ด์ฌ termSpans์ ๊ฐ๋ค.
|
|
152
152
|
* @param {string} text @param {string[]} terms @returns {[number, number][]}
|
|
153
153
|
*/
|
|
154
154
|
export function termSpans(text, terms) {
|
|
@@ -164,7 +164,7 @@ export function termSpans(text, terms) {
|
|
|
164
164
|
return found.sort((a, b) => a[0] - b[0] || a[1] - b[1]);
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
-
/** ๋ ๊ตฌ๊ฐ์ด ํ ๊ธ์๋ผ๋ ๊ฒน์น๋๊ฐ. ํ์ด์ฌ overlapsAny
|
|
167
|
+
/** ๋ ๊ตฌ๊ฐ์ด ํ ๊ธ์๋ผ๋ ๊ฒน์น๋๊ฐ. ํ์ด์ฌ overlapsAny์ ๊ฐ๋ค. @param {number} start @param {number} end @param {[number, number][]} spans */
|
|
168
168
|
export function overlapsAny(start, end, spans) {
|
|
169
169
|
return spans.some(([spanStart, spanEnd]) => spanStart < end && start < spanEnd);
|
|
170
170
|
}
|
|
@@ -189,7 +189,7 @@ export function countPromisesIn(text) {
|
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
/** @param {string} text */
|
|
192
|
-
/** ๊ธ์ ๋์จ ์์ ์ ์ฒด (์ฒ ๋จ์ ์ผํ๋ฅผ ๋ ๊ผด). ๋
์ ์ํ๊ฐ ์๊ณ numberOrphan
|
|
192
|
+
/** ๊ธ์ ๋์จ ์์ ์ ์ฒด (์ฒ ๋จ์ ์ผํ๋ฅผ ๋ ๊ผด). ๋
์ ์ํ๊ฐ ์๊ณ numberOrphan์ด ๋น๊ตํ๋ค. @param {string} text @returns {Set<string>} */
|
|
193
193
|
export function numeralsIn(text) {
|
|
194
194
|
const found = new Set();
|
|
195
195
|
for (const match of text.matchAll(NUMERAL)) found.add(match[0].replaceAll(",", ""));
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
/**
|
|
3
|
-
* ๋
์ ์ํ. ๊ธ์ ์์์ ์๋๋ก ์ฝ๋ ๋
์๊ฐ ์ด๋
|
|
4
|
-
* ํ์ด์ฌ fingerprint/readerState.py
|
|
5
|
-
*
|
|
3
|
+
* ๋
์ ์ํ. ๊ธ์ ์์์ ์๋๋ก ์ฝ๋ ๋
์๊ฐ ์ด๋ ์์น์์ ๋ฌด์์ ์ด๋ฏธ ์๊ณ ๋ฌด์์ ์ด๋ฏธ ๋ณด์๋๊ฐ.
|
|
4
|
+
* ํ์ด์ฌ fingerprint/readerState.py์ ๊ฐ๋ค. ๋
์ ์ํ๋ฅผ ๋ณด๋ ๊ท์น(reader)์ ํ ์์น๊ฐ ํ์๋ก ํ๋ ๊ฒ์ ๊ทธ ์์น์
|
|
5
|
+
* ์ํ์ ๋์กฐํ๋ค. ์ํ๋ ๋ธ๋ก๊ณผ ๋ฌธ์ฅ ์์๋ก ์์ด๊ณ ํ ๋ฒ ์์ ๊ฒ์ ๋ฐ๋์ง ์๋๋ค. ์งํฉ์ ๊ณ ์น์ง ์๋๋ค.
|
|
6
6
|
*/
|
|
7
7
|
import { CODE, PROSE } from "../document/model.js";
|
|
8
8
|
import { createdIn } from "./codeMarkers.js";
|
|
9
9
|
import { numeralsIn } from "./markers.js";
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
* ํ
|
|
12
|
+
* ํ ์์น(๋ฌธ์ฅ ํ๋ ๋๋ ๋ธ๋ก ํ๋)๋ฅผ ์ฝ๊ธฐ ์ง์ ์ ๋
์.
|
|
13
13
|
* @typedef {object} ReaderState
|
|
14
14
|
* @property {import("./build.js").SentencePrint | null} previous ๋ฐ๋ก ์์ ์ฝ์ ์ฐ๋ฌธ ๋ฌธ์ฅ
|
|
15
15
|
* @property {Set<string>} recent ์์ ๋ ํ์ ์ด. ๋ฐ๋ก ์ ๋ฌธ์ฅ์ ๊ฒ์ด๊ณ ์ ๋ฌธ์ฅ์ด ์์ผ๋ฉด ๋น ์งํฉ
|
|
16
|
-
* @property {Set<string>} known ์ด
|
|
16
|
+
* @property {Set<string>} known ์ด ์์น ์๊น์ง ์ฐ๋ฌธ์ ๋์จ ํ์ ์ด ์ ๋ถ
|
|
17
17
|
* @property {Set<string>} numerals ์ง๊ธ๊น์ง ์ฐ๋ฌธ๊ณผ ๋ธ๋ก์ ๋์จ ์ (์ฒ ๋จ์ ์ผํ๋ฅผ ๋ ๊ผด)
|
|
18
18
|
* @property {Set<string>} files ์์ ์ฝ๋ ๋ธ๋ก์ด ๋ง๋ ํ์ผ ์ด๋ฆ๊ณผ ํด๋
|
|
19
19
|
* @property {number} sentencesRead ์ง๊ธ๊น์ง ์ฝ์ ์ฐ๋ฌธ ๋ฌธ์ฅ ์
|
|
20
|
-
* @property {[number, string][]} promises ์ง๊ธ๊น์ง ๋ค๋ก ๋ฏธ๋ฃฌ
|
|
21
|
-
* @property {[number, string][]} recalls ์ง๊ธ๊น์ง
|
|
20
|
+
* @property {[number, string][]} promises ์ง๊ธ๊น์ง ๋ค๋ก ๋ฏธ๋ฃฌ ๋ง(์ค, ์๋ฌธ)
|
|
21
|
+
* @property {[number, string][]} recalls ์ง๊ธ๊น์ง ์์ ์ด์ผ๊ธฐ๋ฅผ ๋ค์ ๋ค๋ฃฌ ๋ง(์ค, ์๋ฌธ)
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
|
-
*
|
|
25
|
+
* ์์น๋ง๋ค์ ๋
์ ์ํ. ๋ฌธ์ฅ์ index๋ก, ๋ธ๋ก์ index๋ก ์ฐพ๋๋ค.
|
|
26
26
|
* @typedef {object} ReaderTrail
|
|
27
27
|
* @property {ReaderState[]} beforeSentence
|
|
28
28
|
* @property {ReaderState[]} beforeBlock
|
|
@@ -84,7 +84,7 @@ function afterBlock(state, block, code) {
|
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
/**
|
|
87
|
-
* ๋ธ๋ก ์์๋ก ํ ๋ฒ ์ง๋๋ฉฐ
|
|
87
|
+
* ๋ธ๋ก ์์๋ก ํ ๋ฒ ์ง๋๋ฉฐ ์์น๋ง๋ค์ ์ํ๋ฅผ ์ ๋๋ค. ์ฐ๋ฌธ ๋ธ๋ก์ ๋ฌธ์ฅ ํ๋์ฉ, ๋๋จธ์ง๋ ๋ธ๋ก์งธ ์ฝ๋๋ค.
|
|
88
88
|
* @param {import("../document/model.js").Block[]} blocks
|
|
89
89
|
* @param {import("./codeBlocks.js").CodeBlock[]} codeBlocks
|
|
90
90
|
* @param {import("./build.js").SentencePrint[]} sentences
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
-
/** ํ๋ฌธ
|
|
2
|
+
/** ํ๋ฌธ ๋ถ์ ๊ฒฐ๊ณผ์ ๋ฌธ์ฅ์ ๋งํฌ๋ค์ด ํ์์ ๋ณด์กดํ ์๋ฌธ ๋ฌธ์ฅ์ ๋ค์ ๋ง์ถ๋ค. */
|
|
3
3
|
import { splitSentences } from "../analysis/splitSentences.js";
|
|
4
4
|
import { plainText } from "../document/plainText.js";
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
-
/** ํ์ ์ด ์งํฉ. ์กฐ์ฌ๋ฅผ ๋ ๋ช
์ฌ ์ด์ ์
|
|
2
|
+
/** ํ์ ์ด ์งํฉ. ์กฐ์ฌ๋ฅผ ๋ ๋ช
์ฌ ์ด์ ์ ์ด๋ฆผ. ํ์ด์ฌ fingerprint/topics.py์ ๊ฐ๋ค. */
|
|
3
3
|
import { stripJosa, tailOf, words } from "../analysis/tokenize.js";
|
|
4
4
|
import { loadLines } from "../data/load.js";
|
|
5
5
|
|
package/src/guard/contract.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
-
/** Reader Contract
|
|
2
|
+
/** Reader Contract ๊ฒ์ฌ์, ์ด์ ๋ฅผ ๋ถ์ฌ ํ ๊ณณ๋ง ๋ฐ๊พธ๋ Patch์ ๊ฒ์ฆ. */
|
|
3
3
|
import { sha256 } from "../digest.js";
|
|
4
4
|
|
|
5
5
|
import { Patch } from "../config/patch.js";
|
|
@@ -19,7 +19,7 @@ function digest(text) {
|
|
|
19
19
|
return sha256(text);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
/** ์๋ฌธ์
|
|
22
|
+
/** ์๋ฌธ์ ์ง์ผ์ผ ํ ์ซ์ยท๋งํฌยท์ฝ๋๋ฅผ ๋ชจ๋ ๋ด๋ version 1 Contract ์ด์์ ๋ง๋ ๋ค. @param {string} text @param {string} reader @param {string} goal */
|
|
23
23
|
export function contractFromText(text, reader, goal) {
|
|
24
24
|
const contract = new Contract(reader, goal, factLines(text));
|
|
25
25
|
const result = surfaceDiff(contract.text, text);
|
|
@@ -27,15 +27,15 @@ export function contractFromText(text, reader, goal) {
|
|
|
27
27
|
for (const kind of ["missingNumbers", "missingUrls", "missingCode", "missingLinks"]) {
|
|
28
28
|
for (const value of result[/** @type {keyof typeof result} */ (kind)]) missing.push(`${kind}=${value}`);
|
|
29
29
|
}
|
|
30
|
-
if (missing.length) throw new Error(`reader
|
|
30
|
+
if (missing.length) throw new Error(`reader๋ goal์ ์๋ฌธ์ ์๋ ์ซ์ยท๋งํฌยท์ฝ๋๊ฐ ๋ค์๋ค: ${missing.join(", ")}`);
|
|
31
31
|
if (surfaceViolationCount(result)) {
|
|
32
32
|
const issues = Object.entries(result).flatMap(([kind, values]) => values.map((value) => `${kind}=${value}`));
|
|
33
|
-
throw new Error(`๊ณ์ฝ ์ด์์ด ์๋ฌธ์
|
|
33
|
+
throw new Error(`๊ณ์ฝ ์ด์์ด ์๋ฌธ์ ์ง์ผ์ผ ํ ์ซ์ยท๋งํฌยท์ฝ๋๋ฅผ ๋ชจ๋ ๋ด์ง ๋ชปํ๋ค: ${issues.join(", ")}`);
|
|
34
34
|
}
|
|
35
35
|
return contract;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
/**
|
|
38
|
+
/** ์๋ฌธ์์ ์๋์ผ๋ก ์ฐพ์ ์ซ์ยท๋งํฌยท์ฝ๋์ ํ ์์ค์ ์ ๋ชฉ์ ๋ฐ๋ก ๋ด์ version 2 Contract ์ด์์ ๋ง๋ ๋ค. @param {string} text @param {string} reader @param {string} goal @param {number} [outlineLevel] @param {string[]} [facts] */
|
|
39
39
|
export function contractFromTextV2(text, reader, goal, outlineLevel = 2, facts = []) {
|
|
40
40
|
const doc = parseMarkdown(text);
|
|
41
41
|
const headings = headingsOf(doc, outlineLevel).map((heading) => heading.text);
|
|
@@ -50,7 +50,7 @@ export function contractFromTextV2(text, reader, goal, outlineLevel = 2, facts =
|
|
|
50
50
|
const result = surfaceDiff(contract.text, text);
|
|
51
51
|
if (surfaceViolationCount(result)) {
|
|
52
52
|
const issues = Object.entries(result).flatMap(([kind, values]) => values.map((value) => `${kind}=${value}`));
|
|
53
|
-
throw new Error(`reader, goal
|
|
53
|
+
throw new Error(`reader, goal, facts์ ์๋ฌธ์ ์๋ ์ซ์ยท๋งํฌยท์ฝ๋๊ฐ ๋ค์๋ค: ${issues.join(", ")}`);
|
|
54
54
|
}
|
|
55
55
|
return contract;
|
|
56
56
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
-
/**
|
|
2
|
+
/** ๊ณ ๋ฅธ ๊ท์น์ ์ง์ ์ด ์๋ ์ค๊ณผ ์๋ฌธ์์ ๋ฐ๋ ๋ฒ์๋ฅผ ๋์กฐํ๋ค. */
|
|
3
3
|
export function editIssues(text, patch, findings, policy) {
|
|
4
4
|
if (!Object.keys(policy).length) return [];
|
|
5
5
|
const limits = policy[patch.reason];
|
package/src/guard/outline.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
-
/** Reader Contract๊ฐ
|
|
2
|
+
/** Reader Contract๊ฐ ๊ณ ์ ํ ์ ๋ชฉ ์์์, ๊ธ ๋ถ์ ๊ฒฐ๊ณผ์์ ๋ฝ์ ๊ตฌ์กฐ ์์ฝ. */
|
|
3
3
|
|
|
4
4
|
/** @typedef {{position: number, expected: string | null, actual: string | null}} OutlineMismatch */
|
|
5
5
|
/** @typedef {{matches: boolean, level: number, expected: string[], actual: string[], mismatches: OutlineMismatch[]}} OutlineDiff */
|
package/src/guard/receipt.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
-
/** Reader Contract ๊ฒ์ฌ์ Patch ๊ฒ์ฆ์
|
|
2
|
+
/** Reader Contract ๊ฒ์ฌ์ Patch ๊ฒ์ฆ์ ๊ฒฐ๊ณผ ๊ธฐ๋ก. ๊ฐ์ ์
๋ ฅ์ด๋ฉด ๋ ๊ฐ์ ๊ฒฐ๊ณผ๋ค. */
|
|
3
3
|
|
|
4
4
|
import { findingAsDict } from "../rules/finding.js";
|
|
5
5
|
import { readerDebts } from "../rules/readerDebt.js";
|
|
6
6
|
import { compareText, surfaceViolationCount } from "./surface.js";
|
|
7
7
|
|
|
8
8
|
export const CHECK_MEANING = "violationCount๋ ์ ์ธํ ๋ณดํธ ์์์ hanlint error์ ์๋ค. facts์ ๊ด๊ณ์ ์ง์ค, ๋น ์ง ์๋ฏธ, ๋
์ ํจ์ฉ๊ณผ ์์ฐ์ค๋ฌ์์ ๊ฒ์ฆํ์ง ์๋๋ค";
|
|
9
|
-
export const CHECK_MEANING_V2 = "violationCount๋
|
|
9
|
+
export const CHECK_MEANING_V2 = "violationCount๋ ๊ณ์ฝ์ ์ ์ ์ซ์ยท๋งํฌยท์ฝ๋์ ์ด๊ธ๋จ, ์ ๋ชฉ ๊ตฌ์กฐ์ ์ด๊ธ๋จ, ๋น ์ง ๊ณ ์ ๋ฌธ๊ตฌ, hanlint ์ค๋ฅ๋ฅผ ๋ํ ์๋ค. facts ์ฌ์ด์ ๊ด๊ณ์ ์ฌ์ค ์ฌ๋ถ, ๋น ์ง ๋ป, ๋
์์๊ฒ ์ธ๋ชจ ์๋์ง์ ์์ฐ์ค๋ฌ์ด์ง๋ ๊ฒ์ฌํ์ง ์๋๋ค";
|
|
10
10
|
export const PATCH_MEANING = "verified๋ ์ ํํ ํ ์๋ฆฌ๋ฅผ ๋ฐ๊พธ๊ณ ๋ช
์ํ ๊ธฐ์กด ์๋ฐ์ ์ค์ด๋ฉฐ ์ ๋ณดํธ ์์ ์๋ฐ๊ณผ ์ error๋ฅผ ๋ง๋ค์ง ์์๋ค๋ ๋ป๋ฟ์ด๋ค. ์์ ๋ฌธ์ ์๋ฏธ์ ์ง์ค, ์์ฐ์ค๋ฌ์์ ์น์ธํ์ง ์๋๋ค";
|
|
11
|
-
export const PATCH_MEANING_V2 = "verified๋ ์ ํํ ํ
|
|
11
|
+
export const PATCH_MEANING_V2 = "verified๋ ์ ํํ ํ ๊ณณ์ ๋ฐ๊พธ๊ณ , ์ ์ด ๋ ๊ธฐ์กด ์๋ฐ์ ์ค์ด๊ณ , ์ ๊ณ์ฝ ์๋ฐ๊ณผ ์ ์ค๋ฅ๋ฅผ ๋ง๋ค์ง ์๊ณ , ๊ณ ๋ฅธ ์์ ์์ฐ์ ์ง์ผฐ๋ค๋ ๋ป๋ฟ์ด๋ค. ๊ณ ์น ๋ฌธ์ฅ์ ๋ป์ด ๋ง๋์ง, ์ฌ์ค์ธ์ง, ์์ฐ์ค๋ฌ์ด์ง๋ ๋ณด์ฆํ์ง ์๋๋ค";
|
|
12
12
|
|
|
13
13
|
/** @param {import("../rules/finding.js").Finding[]} findings */
|
|
14
14
|
function errorRules(findings) {
|
|
@@ -32,7 +32,7 @@ export class CheckResult {
|
|
|
32
32
|
this.document = document;
|
|
33
33
|
this.missingFacts = missingFacts;
|
|
34
34
|
if (![1, 2].includes(contractVersion)) {
|
|
35
|
-
throw new Error(`check result contractVersion
|
|
35
|
+
throw new Error(`check result์ contractVersion์ 1์ด๋ 2์ฌ์ผ ํ๋ค. ๋ฐ์ ๊ฐ: ${contractVersion}`);
|
|
36
36
|
}
|
|
37
37
|
const hasStructure = outline !== null && document !== null;
|
|
38
38
|
if (hasStructure !== (contractVersion === 2)) {
|
|
@@ -89,7 +89,7 @@ export class PatchResult {
|
|
|
89
89
|
this.resultText = values.resultText;
|
|
90
90
|
this.contractVersion = values.contractVersion;
|
|
91
91
|
if (![1, 2].includes(values.contractVersion)) {
|
|
92
|
-
throw new Error(`patch result contractVersion
|
|
92
|
+
throw new Error(`patch result์ contractVersion์ 1์ด๋ 2์ฌ์ผ ํ๋ค. ๋ฐ์ ๊ฐ: ${values.contractVersion}`);
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
|
|
@@ -137,7 +137,7 @@ export class PatchResult {
|
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
/** ์ฌ๋์ด ๊ฒฐ๋ก , ๊ทผ๊ฑฐ, ๋ค์
|
|
140
|
+
/** ์ฌ๋์ด ๊ฒฐ๋ก , ๊ทผ๊ฑฐ, ๋ค์ ํ ์ผ์ ์์๋ก ์ฝ๋ ๊ฒ์ฌ ๊ฒฐ๊ณผ. @param {CheckResult} result */
|
|
141
141
|
export function renderCheck(result) {
|
|
142
142
|
const lines = [result.violationCount === 0 ? "๊ณ์ฝ ์๋ฐ ์์" : `๊ณ์ฝ ์๋ฐ ${result.violationCount}๊ฑด`];
|
|
143
143
|
const labels = [
|
|
@@ -162,19 +162,19 @@ export function renderCheck(result) {
|
|
|
162
162
|
if (result.document) {
|
|
163
163
|
lines.push(`- ๊ธ: ๋ฌธ์ฅ ${result.document.sentenceCount}, ๋ฌธ๋จ ${result.document.paragraphCount}, ์ ${result.document.sectionCount}`);
|
|
164
164
|
result.document.sections.forEach((section, index) => {
|
|
165
|
-
lines.push(` ${index + 1}. ${section.heading} (${section.line}
|
|
165
|
+
lines.push(` ${index + 1}. ${section.heading} (${section.line}์ค, ๋ฌธ๋จ ${section.paragraphCount}, ์ฝ๋ ${section.codeBlockCount})`);
|
|
166
166
|
});
|
|
167
167
|
}
|
|
168
|
-
lines.push(`- lint:
|
|
168
|
+
lines.push(`- lint: ์ค๋ฅ ${result.errorCount}๊ฑด, ๊ฒฝ๊ณ ${result.noticeCount}๊ฑด`);
|
|
169
169
|
if (result.errorCount) {
|
|
170
170
|
lines.push(` ${Object.entries(errorRules(result.findings)).map(([rule, count]) => `${rule} ${count}`).join(", ")}`);
|
|
171
171
|
}
|
|
172
172
|
const debts = readerDebts(result.findings);
|
|
173
|
-
lines.push(debts.length ? `-
|
|
174
|
-
for (const debt of debts) lines.push(` ${debt.line}
|
|
175
|
-
if (result.violationCount) lines.push("\n๋ค์: ๊ณ์ฝ๊ณผ ๊ธ ๊ฐ์ด๋ฐ ํ๋ฆฐ ์ชฝ์
|
|
176
|
-
else if (result.noticeCount) lines.push("\n๋ค์:
|
|
177
|
-
else lines.push("\n๋ค์:
|
|
173
|
+
lines.push(debts.length ? `- ๋
์๊ฐ ๋งํ ๊ณณ: ${debts.length}๊ฑด` : "- ๋
์๊ฐ ๋งํ ๊ณณ: ์์");
|
|
174
|
+
for (const debt of debts) lines.push(` ${debt.line}์ค [${debt.rule}] ${debt.why}`);
|
|
175
|
+
if (result.violationCount) lines.push("\n๋ค์: ๊ณ์ฝ๊ณผ ๊ธ ๊ฐ์ด๋ฐ ํ๋ฆฐ ์ชฝ์ ๊ณ ์น๊ณ ๊ฐ์ check๋ฅผ ๋ค์ ๋๋ฆฐ๋ค");
|
|
176
|
+
else if (result.noticeCount) lines.push("\n๋ค์: ๊ฒฝ๊ณ ๋ฅผ ์ฝ๊ณ ๊ณ ์น ์ง ๊ทธ๋๋ก ๋์ง ์ ํ๋ค");
|
|
177
|
+
else lines.push("\n๋ค์: ๊ท์น์ผ๋ก ์
์ ์๋ ๊ณ์ฝ ์๋ฐ์ ์๋ค. ๋ป๊ณผ ์์ฐ์ค๋ฌ์์ ์ฌ๋์ด ์ฝ๊ณ ํ๋จํ๋ค");
|
|
178
178
|
lines.push("", result.contractVersion === 1 ? CHECK_MEANING : CHECK_MEANING_V2);
|
|
179
179
|
return lines.join("\n");
|
|
180
180
|
}
|
package/src/guard/surface.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
-
/** ๊ณ์ฝ ๋ณธ๋ฌธ๊ณผ ๊ฒฐ๊ณผ ๊ธ
|
|
2
|
+
/** ๊ณ์ฝ ๋ณธ๋ฌธ๊ณผ ๊ฒฐ๊ณผ ๊ธ ์ฌ์ด์์ ์ง์ผ์ผ ํ ์ซ์ยท๋งํฌยท์ฝ๋์ ์ฐจ์ด. */
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @typedef {object} SurfaceDiff
|
|
@@ -107,7 +107,7 @@ export function surfaceViolationCount(diff) {
|
|
|
107
107
|
return Object.values(diff).reduce((total, values) => total + values.length, 0);
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
/** ์๋ฌธ์
|
|
110
|
+
/** ์๋ฌธ์ ์ง์ผ์ผ ํ ์ซ์ยท๋งํฌยท์ฝ๋๋ฅผ ๋ป๊ณผ ์๊ด์์ด ์ ๋ ฌํ ์งํฉ์ผ๋ก ๋๋๋ค. @param {string} text */
|
|
111
111
|
export function protectedSurface(text) {
|
|
112
112
|
const surfaceText = text.normalize("NFC");
|
|
113
113
|
return {
|
|
@@ -118,7 +118,7 @@ export function protectedSurface(text) {
|
|
|
118
118
|
};
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
-
/** ์๋ฌธ์
|
|
121
|
+
/** ์๋ฌธ์ ์ง์ผ์ผ ํ ์ซ์ยท๋งํฌยท์ฝ๋๋ฅผ ๋ชจ๋ ๋ด๋ Contract ์ฌ์ค ํ๋ณด ์ค. @param {string} text */
|
|
122
122
|
export function factLines(text) {
|
|
123
123
|
const surfaceText = text.normalize("NFC");
|
|
124
124
|
const seen = new Set();
|
|
@@ -144,7 +144,7 @@ export function factLines(text) {
|
|
|
144
144
|
),
|
|
145
145
|
);
|
|
146
146
|
if (!uncovered.size) {
|
|
147
|
-
throw new Error("์๋ฌธ์ ์๋์ผ๋ก
|
|
147
|
+
throw new Error("์๋ฌธ์ ์๋์ผ๋ก ์งํฌ ์ซ์, URL, ์ธ๋ผ์ธ ์ฝ๋, ๋งํฌ ๋ชฉ์ ์ง๊ฐ ์๋ค. facts๋ฅผ ์ง์ ์์ฑํ๋ค");
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
const selected = new Set();
|