textlint-rule-ja-space-between-half-and-full-width
Advanced tools
Comparing version 2.3.1 to 2.4.0
@@ -6,2 +6,3 @@ // LICENSE : MIT | ||
var _matchIndex = require("match-index"); | ||
var _regexpStringMatcher = require("@textlint/regexp-string-matcher"); | ||
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } | ||
@@ -26,3 +27,9 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } | ||
// プレーンテキスト以外を対象とするか See https://github.com/textlint/textlint-rule-helper#rulehelperisplainstrnodenode-boolean | ||
lintStyledNode: false | ||
lintStyledNode: false, | ||
/** | ||
* 例外として無視する文字列 | ||
* RegExp-like Stringの配列を指定 | ||
* https://github.com/textlint/regexp-string-matcher?tab=readme-ov-file#regexp-like-string | ||
*/ | ||
allows: [] | ||
}; | ||
@@ -79,2 +86,3 @@ function reporter(context) { | ||
var lintStyledNode = options.lintStyledNode !== undefined ? options.lintStyledNode : defaultOptions.lintStyledNode; | ||
var allows = options.allows !== undefined ? options.allows : defaultOptions.allows; | ||
/** | ||
@@ -87,2 +95,3 @@ * `text`を対象に例外オプションを取り除くfilter関数を返す | ||
var createFilter = (text, padding) => { | ||
var allowedPatterns = allows.length > 0 ? (0, _regexpStringMatcher.matchPatterns)(text, allows) : []; | ||
/** | ||
@@ -101,3 +110,10 @@ * `PunctuationRegExp`で指定された例外を取り除く | ||
} | ||
return true; | ||
var isAllowed = allowedPatterns.some(allow => { | ||
// start ... end | ||
if (allow.startIndex <= match.index && match.index <= allow.endIndex) { | ||
return true; | ||
} | ||
return false; | ||
}); | ||
return !isAllowed; | ||
}; | ||
@@ -104,0 +120,0 @@ }; |
{ | ||
"name": "textlint-rule-ja-space-between-half-and-full-width", | ||
"version": "2.3.1", | ||
"version": "2.4.0", | ||
"description": "半角文字と全角文字のスペースについてのtextlintルール", | ||
@@ -32,2 +32,3 @@ "main": "lib/index.js", | ||
"devDependencies": { | ||
"@textlint/regexp-string-matcher": "^2.0.2", | ||
"textlint-scripts": "^13.3.3" | ||
@@ -39,3 +40,3 @@ }, | ||
}, | ||
"gitHead": "fdcee300489a613f44215d6a096d240c2336c46a" | ||
"gitHead": "af3f75d0f8ae55566975d8e7a03453151836c9b3" | ||
} |
@@ -52,9 +52,13 @@ # textlint-rule-ja-space-between-half-and-full-width | ||
- `["alphabets"]` | ||
- (非推奨)`exceptPunctuation`: `boolean` | ||
- デフォルト: `true` | ||
- 句読点(、。)を例外として扱うかどうか | ||
- 代わりに `space` オプションを用いて `["alphabets", "numbers"]` と指定する | ||
- `lintStyledNode`: `boolean` | ||
- デフォルト: `false` | ||
- プレーンテキスト以外(リンクや画像のキャプションなど)を lint の対象とするかどうか (プレーンテキストの判断基準は [textlint/textlint-rule-helper: This is helper library for creating textlint rule](https://github.com/textlint/textlint-rule-helper#rulehelperisplainstrnodenode-boolean) を参照してください) | ||
- `allows: string[]` | ||
- デフォルト: `[]` | ||
- 例外として扱う文字列の配列 | ||
- [RegExp-like String](https://github.com/textlint/regexp-string-matcher?tab=readme-ov-file#regexp-like-string)も指定可能 | ||
- (非推奨)`exceptPunctuation`: `boolean` | ||
- デフォルト: `true` | ||
- 句読点(、。)を例外として扱うかどうか | ||
- 代わりに `space` オプションを用いて `["alphabets", "numbers"]` と指定する | ||
@@ -87,3 +91,10 @@ ```json | ||
スペースは必須だが、`Eコーマス`だけはスペースなしを許可する。 | ||
text: "例外的にEコーマスはスペースなしでも通す", | ||
options: { | ||
space: "always", | ||
allows: ["Eコーマス"] | ||
} | ||
## Changelog | ||
@@ -90,0 +101,0 @@ |
141
src/index.js
@@ -7,4 +7,6 @@ // LICENSE : MIT | ||
*/ | ||
import {RuleHelper} from "textlint-rule-helper"; | ||
import {matchCaptureGroupAll} from "match-index"; | ||
import { RuleHelper } from "textlint-rule-helper"; | ||
import { matchCaptureGroupAll } from "match-index"; | ||
import { matchPatterns } from "@textlint/regexp-string-matcher"; | ||
const PunctuationRegExp = /[。、]/; | ||
@@ -15,3 +17,3 @@ const ZenRegExpStr = '[、。]|[\u3400-\u4DBF\u4E00-\u9FFF\uF900-\uFAFF]|[\uD840-\uD87F][\uDC00-\uDFFF]|[ぁ-んァ-ヶ]'; | ||
numbers: false, | ||
punctuation: false | ||
punctuation: false, | ||
}; | ||
@@ -21,40 +23,47 @@ const defaultOptions = { | ||
lintStyledNode: false, | ||
/** | ||
* 例外として無視する文字列 | ||
* RegExp-like Stringの配列を指定 | ||
* https://github.com/textlint/regexp-string-matcher?tab=readme-ov-file#regexp-like-string | ||
*/ | ||
allows: [] | ||
}; | ||
function reporter(context, options = {}) { | ||
/** | ||
* 入力された `space` オプションを内部処理用に成形する | ||
* @param {string|Array|undefined} opt `space` オプションのインプット | ||
* @param {boolean|undefined} exceptPunctuation `exceptPunctuation` オプションのインプット | ||
* @returns {Object} | ||
*/ | ||
/** | ||
* 入力された `space` オプションを内部処理用に成形する | ||
* @param {string|Array|undefined} opt `space` オプションのインプット | ||
* @param {boolean|undefined} exceptPunctuation `exceptPunctuation` オプションのインプット | ||
* @returns {Object} | ||
*/ | ||
const parseSpaceOption = (opt, exceptPunctuation) => { | ||
if (typeof opt === 'string') { | ||
assert(opt === "always" || opt === "never", `"space" options should be "always", "never" or an array.`); | ||
if (opt === "always") { | ||
if (exceptPunctuation === false) { | ||
return {...defaultSpaceOptions, alphabets: true, numbers: true, punctuation: true}; | ||
} else { | ||
return {...defaultSpaceOptions, alphabets: true, numbers: true}; | ||
} | ||
} else if (opt === "never") { | ||
if (exceptPunctuation === false) { | ||
return {...defaultSpaceOptions, punctuation: true}; | ||
} else { | ||
return defaultSpaceOptions; | ||
} | ||
if (typeof opt === 'string') { | ||
assert(opt === "always" || opt === "never", `"space" options should be "always", "never" or an array.`); | ||
if (opt === "always") { | ||
if (exceptPunctuation === false) { | ||
return { ...defaultSpaceOptions, alphabets: true, numbers: true, punctuation: true }; | ||
} else { | ||
return { ...defaultSpaceOptions, alphabets: true, numbers: true }; | ||
} | ||
} else if (opt === "never") { | ||
if (exceptPunctuation === false) { | ||
return { ...defaultSpaceOptions, punctuation: true }; | ||
} else { | ||
return defaultSpaceOptions; | ||
} | ||
} | ||
} else if (Array.isArray(opt)) { | ||
assert( | ||
opt.every((v) => Object.keys(defaultSpaceOptions).includes(v)), | ||
`Only "alphabets", "numbers", "punctuation" can be included in the array.` | ||
); | ||
const userOptions = Object.fromEntries(opt.map(key => [key, true])); | ||
return { ...defaultSpaceOptions, ...userOptions }; | ||
} | ||
} else if (Array.isArray(opt)) { | ||
assert( | ||
opt.every((v) => Object.keys(defaultSpaceOptions).includes(v)), | ||
`Only "alphabets", "numbers", "punctuation" can be included in the array.` | ||
); | ||
const userOptions = Object.fromEntries(opt.map(key => [key, true])); | ||
return {...defaultSpaceOptions, ...userOptions}; | ||
} | ||
return defaultSpaceOptions; | ||
return defaultSpaceOptions; | ||
} | ||
const {Syntax, RuleError, report, fixer, getSource} = context; | ||
const { Syntax, RuleError, report, fixer, getSource } = context; | ||
const helper = new RuleHelper(); | ||
@@ -65,2 +74,3 @@ const spaceOption = parseSpaceOption(options.space, options.exceptPunctuation); | ||
: defaultOptions.lintStyledNode; | ||
const allows = options.allows !== undefined ? options.allows : defaultOptions.allows; | ||
/** | ||
@@ -73,2 +83,3 @@ * `text`を対象に例外オプションを取り除くfilter関数を返す | ||
const createFilter = (text, padding) => { | ||
const allowedPatterns = allows.length > 0 ? matchPatterns(text, allows) : []; | ||
/** | ||
@@ -87,3 +98,10 @@ * `PunctuationRegExp`で指定された例外を取り除く | ||
} | ||
return true; | ||
const isAllowed = allowedPatterns.some((allow) => { | ||
// start ... end | ||
if (allow.startIndex <= match.index && match.index <= allow.endIndex) { | ||
return true; | ||
} | ||
return false | ||
}) | ||
return !isAllowed; | ||
} | ||
@@ -96,3 +114,3 @@ }; | ||
const reportMatch = (match) => { | ||
const {index} = match; | ||
const { index } = match; | ||
report(node, new RuleError("原則として、全角文字と半角文字の間にスペースを入れません。", { | ||
@@ -106,33 +124,33 @@ index: match.index, | ||
}; | ||
// Always: アルファベットと全角の間はスペースを入れる | ||
const needSpaceBetween = (node, text, options) => { | ||
/** | ||
* オプションを元に正規表現オプジェクトを生成する | ||
* @param {Array} opt `space` オプション | ||
* @param {boolean} btwHanAndZen=true 半角全角の間か全角半角の間か | ||
* @returns {Object} | ||
*/ | ||
/** | ||
* オプションを元に正規表現オプジェクトを生成する | ||
* @param {Array} opt `space` オプション | ||
* @param {boolean} btwHanAndZen=true 半角全角の間か全角半角の間か | ||
* @returns {Object} | ||
*/ | ||
const generateRegExp = (opt, btwHanAndZen = true) => { | ||
const alphabets = opt.alphabets ? 'A-Za-z' : ''; | ||
const numbers = opt.numbers ? '0-9' : ''; | ||
let expStr; | ||
if (btwHanAndZen) { | ||
expStr = `([${alphabets}${numbers}])(?:${ZenRegExpStr})`; | ||
} else { | ||
expStr = `(${ZenRegExpStr})[${alphabets}${numbers}]`; | ||
} | ||
return new RegExp(expStr); | ||
const alphabets = opt.alphabets ? 'A-Za-z' : ''; | ||
const numbers = opt.numbers ? '0-9' : ''; | ||
let expStr; | ||
if (btwHanAndZen) { | ||
expStr = `([${alphabets}${numbers}])(?:${ZenRegExpStr})`; | ||
} else { | ||
expStr = `(${ZenRegExpStr})[${alphabets}${numbers}]`; | ||
} | ||
return new RegExp(expStr); | ||
}; | ||
const betweenHanAndZenRegExp = generateRegExp(options); | ||
const betweenZenAndHanRegExp = generateRegExp(options, false); | ||
const errorMsg = '原則として、全角文字と半角文字の間にスペースを入れます。'; | ||
const betweenHanAndZen = matchCaptureGroupAll(text, betweenHanAndZenRegExp); | ||
const betweenZenAndHan = matchCaptureGroupAll(text, betweenZenAndHanRegExp); | ||
const reportMatch = (match) => { | ||
const {index} = match; | ||
const { index } = match; | ||
report(node, new RuleError(errorMsg, { | ||
@@ -147,3 +165,3 @@ index: match.index, | ||
return { | ||
[Syntax.Str](node){ | ||
[Syntax.Str](node) { | ||
if (!lintStyledNode && !helper.isPlainStrNode(node)) { | ||
@@ -153,3 +171,3 @@ return; | ||
const text = getSource(node); | ||
const noSpace = (key) => key === 'punctuation' ? true : !spaceOption[key]; | ||
@@ -164,2 +182,3 @@ if (Object.keys(spaceOption).every(noSpace)) { | ||
} | ||
module.exports = { | ||
@@ -166,0 +185,0 @@ linter: reporter, |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
37203
352
128
2