22"use strict" ;
33import { matchPatterns } from "@textlint/regexp-string-matcher" ;
44import { wrapReportHandler } from "textlint-rule-helper" ;
5- import StringSource from "textlint-util-to-string" ;
6- const { Dictionary, ExpectedType } = require ( "./dictionary.js" )
5+ import { StringSource } from "textlint-util-to-string" ;
6+ import { Dictionary , ExpectedType } from "./dictionary" ;
77
8- const tokenize = require ( "kuromojin" ) . tokenize ;
9-
10- const createMatchAll = require ( "morpheme-match-all" ) ;
8+ import { tokenize , KuromojiToken } from "kuromojin" ;
9+ import { TextlintRuleModule } from "@textlint/types" ;
10+ import { createMatcher } from "morpheme-match-all" ;
1111
1212/**
1313 * textの中身をすべて置換する
@@ -16,11 +16,14 @@ const createMatchAll = require("morpheme-match-all");
1616 * @param {string } to
1717 * @returns {string }
1818 */
19- const replaceAll = ( text , from , to ) => {
19+ const replaceAll = ( text : string , from : string | undefined , to : string ) : string => {
20+ if ( ! from ) {
21+ return text ;
22+ }
2023 return text . split ( from ) . join ( to ) ;
2124} ;
2225
23- const replaceTokenWith = ( matcherToken , actualToken , specialTo ) => {
26+ const replaceTokenWith = ( matcherToken : any , actualToken : KuromojiToken , specialTo : string ) => {
2427 if ( matcherToken [ specialTo ] ) {
2528 return matcherToken [ specialTo ] ( actualToken ) ;
2629 }
@@ -32,7 +35,7 @@ const replaceTokenWith = (matcherToken, actualToken, specialTo) => {
3235 * @param tokens
3336 * @returns {string }
3437 */
35- const tokensToString = tokens => {
38+ const tokensToString = ( tokens : KuromojiToken [ ] ) => {
3639 return tokens . map ( token => token . surface_form ) . join ( "" ) ;
3740} ;
3841
@@ -41,7 +44,7 @@ const tokensToString = tokens => {
4144 * @param {*[] } tokens
4245 * @param {string[] } allows
4346 */
44- const isTokensAllowed = ( tokens , allows ) => {
47+ const isTokensAllowed = ( tokens : KuromojiToken [ ] , allows : string [ ] ) => {
4548 if ( allows . length === 0 ) {
4649 return false ;
4750 }
@@ -59,7 +62,9 @@ const isTokensAllowed = (tokens, allows) => {
5962 * @param {*[] } actualTokens
6063 * @returns {null|string }
6164 */
62- const createExpected = ( { expected, matcherTokens, skipped, actualTokens } ) => {
65+ const createExpected = ( { expected, matcherTokens, skipped, actualTokens } : {
66+ expected ?: string , matcherTokens : any [ ] , skipped : boolean [ ] , actualTokens : KuromojiToken [ ]
67+ } ) : null | string => {
6368 if ( ! expected ) {
6469 return null ;
6570 }
@@ -84,7 +89,7 @@ const createExpected = ({ expected, matcherTokens, skipped, actualTokens }) => {
8489 return resultText ;
8590} ;
8691
87- const createMessage = ( { id, text, matcherTokens, skipped, actualTokens } ) => {
92+ const createMessage = ( { id, text, matcherTokens, skipped, actualTokens } : { id : string , text : string , matcherTokens : any [ ] , skipped : boolean [ ] , actualTokens : KuromojiToken [ ] } ) => {
8893 let resultText = text ;
8994 let actualTokenIndex = 0 ;
9095 matcherTokens . forEach ( ( token , index ) => {
@@ -103,7 +108,22 @@ const createMessage = ({ id, text, matcherTokens, skipped, actualTokens }) => {
103108解説: https://github.com/textlint-ja/textlint-rule-ja-no-redundant-expression#${ id } ` ;
104109} ;
105110
106- const reporter = ( context , options = { } ) => {
111+ export interface Options {
112+ // - それぞれの`dict`に対するオプションを指定する
113+ // - プロパティに`dict`の【dict[id]】を書き、値には次の辞書オプションを指定する
114+ // - 辞書オプション: `object`
115+ dictOptions ?: {
116+ [ index : string ] : {
117+ disabled ?: boolean ;
118+ allows ?: string [ ]
119+ }
120+ } ;
121+ // - 無視したいNode typeを配列で指定
122+ // - Node typeは <https://textlint.github.io/docs/txtnode.html#type> を参照
123+ // - デフォルトでは、`["BlockQuote", "Link", "ReferenceDef", "Code"]`を指定し、引用やリンクのテキストは無視する
124+ }
125+
126+ const reporter : TextlintRuleModule < Options > = ( context , options = { } ) => {
107127 const { Syntax, RuleError, fixer } = context ;
108128 const DefaultOptions = {
109129 // https://textlint.github.io/docs/txtnode.html#type
@@ -117,7 +137,7 @@ const reporter = (context, options = {}) => {
117137 const disabled = typeof dictOption . disabled === "boolean" ? dictOption . disabled : dict . disabled ;
118138 return ! disabled ;
119139 } ) ;
120- const matchAll = createMatchAll ( enabledDictionaryList ) ;
140+ const matchAll = createMatcher ( enabledDictionaryList ) ;
121141 const skipNodeTypes = options . allowNodeTypes || DefaultOptions . allowNodeTypes ;
122142 return wrapReportHandler (
123143 context ,
@@ -130,9 +150,6 @@ const reporter = (context, options = {}) => {
130150 const source = new StringSource ( node ) ;
131151 const text = source . toString ( ) ;
132152 return tokenize ( text ) . then ( currentTokens => {
133- /**
134- * @type {MatchResult[] }
135- */
136153 const matchResults = matchAll ( currentTokens ) ;
137154 matchResults . forEach ( matchResult => {
138155 const dictOption = dictOptions [ matchResult . dict . id ] || { } ;
@@ -147,10 +164,10 @@ const reporter = (context, options = {}) => {
147164 const lastToken = matchResult . tokens [ matchResult . tokens . length - 1 ] ;
148165 const firstWordIndex = source . originalIndexFromIndex (
149166 Math . max ( firstToken . word_position - 1 , 0 )
150- ) ;
167+ ) || 0 ;
151168 const lastWordIndex = source . originalIndexFromIndex (
152169 Math . max ( lastToken . word_position - 1 , 0 )
153- ) ;
170+ ) || 0 ;
154171 // エラーメッセージ
155172 const message =
156173 createMessage ( {
@@ -168,7 +185,7 @@ const reporter = (context, options = {}) => {
168185 actualTokens : matchResult . tokens
169186 } ) ;
170187 const hasFixableResult = expected && tokensToString ( matchResult . tokens ) !== expected ;
171- if ( hasFixableResult ) {
188+ if ( expected && hasFixableResult ) {
172189 const wordLength = lastToken . surface_form . length ;
173190 report (
174191 node ,
@@ -195,7 +212,7 @@ const reporter = (context, options = {}) => {
195212 }
196213 ) ;
197214} ;
198- module . exports = {
215+ export default {
199216 linter : reporter ,
200217 fixer : reporter
201218} ;
0 commit comments