├── .github └── workflows │ └── test.yml ├── .gitignore ├── LICENSE ├── README.md ├── lerna.json ├── package.json ├── packages ├── textlint-rule-kana-english-fo-pho │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ └── textlint-rule-kana-english-fo-pho.ts │ ├── test │ │ └── textlint-rule-kana-english-fo-pho.test.ts │ └── tsconfig.json ├── textlint-rule-kana-english-suffix-er │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ └── textlint-rule-kana-english-suffix-er.ts │ ├── test │ │ └── textlint-rule-kana-english-suffix-er.test.ts │ └── tsconfig.json ├── textlint-rule-kana-english-suffix-re │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ └── textlint-rule-kana-english-suffix-re.ts │ ├── test │ │ └── textlint-rule-kana-english-suffix-re.test.ts │ └── tsconfig.json ├── textlint-rule-kana-english-suffix-ware │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ └── textlint-rule-kana-english-suffix-ware.ts │ ├── test │ │ └── textlint-rule-kana-english-suffix-ware.test.ts │ └── tsconfig.json ├── textlint-rule-kana-english-suffix-y │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ └── textlint-rule-kana-english-suffix-y.ts │ ├── test │ │ └── textlint-rule-kana-english-suffix-y.test.ts │ └── tsconfig.json ├── textlint-rule-no-kana-english-v │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ └── textlint-rule-no-kana-english-v.ts │ ├── test │ │ └── textlint-rule-no-kana-english-v.test.ts │ └── tsconfig.json └── textlint-rule-preset-foreign-language-writing-helper │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ ├── create-katakana-english-index.ts │ └── textlint-rule-preset-foreign-language-writing-helper.ts │ ├── test │ ├── create-katakana-english-index.test.ts │ ├── mocha.opts │ └── tsconfig.json │ └── tsconfig.json ├── tools └── update-readme.ts ├── tsconfig.json └── yarn.lock /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | 3 | on: [push, pull_request] 4 | env: 5 | CI: true 6 | 7 | jobs: 8 | build: 9 | name: Test on node ${{ matrix.node_version }} 10 | runs-on: ubuntu-latest 11 | strategy: 12 | matrix: 13 | node_version: [10, 12] 14 | 15 | steps: 16 | - uses: actions/checkout@v1 17 | - name: Use Node.js ${{ matrix.node_version }} 18 | uses: actions/setup-node@v1 19 | with: 20 | node-version: ${{ matrix.node_version }} 21 | - run: yarn install 22 | - run: yarn bootstrap 23 | - run: yarn test 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### https://raw.github.com/github/gitignore/d2c1bb2b9c72ead618c9f6a48280ebc7a8e0dff6/Node.gitignore 2 | 3 | # Logs 4 | logs 5 | *.log 6 | npm-debug.log* 7 | yarn-debug.log* 8 | yarn-error.log* 9 | 10 | # Runtime data 11 | pids 12 | *.pid 13 | *.seed 14 | *.pid.lock 15 | 16 | # Directory for instrumented libs generated by jscoverage/JSCover 17 | lib-cov 18 | 19 | # Coverage directory used by tools like istanbul 20 | coverage 21 | 22 | # nyc test coverage 23 | .nyc_output 24 | 25 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 26 | .grunt 27 | 28 | # Bower dependency directory (https://bower.io/) 29 | bower_components 30 | 31 | # node-waf configuration 32 | .lock-wscript 33 | 34 | # Compiled binary addons (https://nodejs.org/api/addons.html) 35 | build/Release 36 | 37 | # Dependency directories 38 | node_modules/ 39 | jspm_packages/ 40 | 41 | # TypeScript v1 declaration files 42 | typings/ 43 | 44 | # Optional npm cache directory 45 | .npm 46 | 47 | # Optional eslint cache 48 | .eslintcache 49 | 50 | # Optional REPL history 51 | .node_repl_history 52 | 53 | # Output of 'npm pack' 54 | *.tgz 55 | 56 | # Yarn Integrity file 57 | .yarn-integrity 58 | 59 | # dotenv environment variables file 60 | .env 61 | .env.test 62 | 63 | # parcel-bundler cache (https://parceljs.org/) 64 | .cache 65 | 66 | # next.js build output 67 | .next 68 | 69 | # nuxt.js build output 70 | .nuxt 71 | 72 | # vuepress build output 73 | .vuepress/dist 74 | 75 | # Serverless directories 76 | .serverless/ 77 | 78 | # FuseBox cache 79 | .fusebox/ 80 | 81 | # DynamoDB Local files 82 | .dynamodb/ 83 | 84 | 85 | ### https://raw.github.com/github/gitignore/d2c1bb2b9c72ead618c9f6a48280ebc7a8e0dff6/Global/JetBrains.gitignore 86 | 87 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm 88 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 89 | 90 | # User-specific stuff 91 | .idea/**/workspace.xml 92 | .idea/**/tasks.xml 93 | .idea/**/usage.statistics.xml 94 | .idea/**/dictionaries 95 | .idea/**/shelf 96 | 97 | # Generated files 98 | .idea/**/contentModel.xml 99 | 100 | # Sensitive or high-churn files 101 | .idea/**/dataSources/ 102 | .idea/**/dataSources.ids 103 | .idea/**/dataSources.local.xml 104 | .idea/**/sqlDataSources.xml 105 | .idea/**/dynamic.xml 106 | .idea/**/uiDesigner.xml 107 | .idea/**/dbnavigator.xml 108 | 109 | # Gradle 110 | .idea/**/gradle.xml 111 | .idea/**/libraries 112 | 113 | # Gradle and Maven with auto-import 114 | # When using Gradle or Maven with auto-import, you should exclude module files, 115 | # since they will be recreated, and may cause churn. Uncomment if using 116 | # auto-import. 117 | # .idea/modules.xml 118 | # .idea/*.iml 119 | # .idea/modules 120 | 121 | # CMake 122 | cmake-build-*/ 123 | 124 | # Mongo Explorer plugin 125 | .idea/**/mongoSettings.xml 126 | 127 | # File-based project format 128 | *.iws 129 | 130 | # IntelliJ 131 | out/ 132 | 133 | # mpeltonen/sbt-idea plugin 134 | .idea_modules/ 135 | 136 | # JIRA plugin 137 | atlassian-ide-plugin.xml 138 | 139 | # Cursive Clojure plugin 140 | .idea/replstate.xml 141 | 142 | # Crashlytics plugin (for Android Studio and IntelliJ) 143 | com_crashlytics_export_strings.xml 144 | crashlytics.properties 145 | crashlytics-build.properties 146 | fabric.properties 147 | 148 | # Editor-based Rest Client 149 | .idea/httpRequests 150 | 151 | # Android studio 3.1+ serialized cache file 152 | .idea/caches/build_file_checksums.ser 153 | 154 | /packages/*/lib/ 155 | /lib/ 156 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019 azu 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # @textlint-ja/textlint-rule-preset-foreign-language-writing [![Actions Status](https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing/workflows/test/badge.svg)](https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing/actions?query=workflow%3A"test") 2 | 3 | 外来語のカタカナ表記などについて扱うtextlintルールプリセットです。 4 | 5 | カタカナ表記については正解がないため、表記ゆれの統一のためにOpinionatedなルールが含まれます。 6 | 7 | ## ルール一覧 8 | 9 | ### [@textlint-ja/textlint-rule-kana-english-fo-pho](packages/textlint-rule-kana-english-fo-pho) 10 | 11 | > 原語が「fo」または「pho」の場合は、カタカナでは「フォ」とするのを原則とするtextlintルール 12 | 13 | ### [@textlint-ja/textlint-rule-kana-english-suffix-er](packages/textlint-rule-kana-english-suffix-er) 14 | 15 | > 原語の語尾の-er,-or,-arをカタカナでは長音記号「ー」で表わすの原則とするtextlintルール 16 | 17 | ### [@textlint-ja/textlint-rule-kana-english-suffix-re](packages/textlint-rule-kana-english-suffix-re) 18 | 19 | > 原語の語尾が-reの場合は長音記号「ー」を付けない、原語の語尾が-ture,-sureの場合は原則として長音記号「ー」を付けるtextlintルール 20 | 21 | ### [@textlint-ja/textlint-rule-kana-english-suffix-ware](packages/textlint-rule-kana-english-suffix-ware) 22 | 23 | > 原語の語尾が-ware, -wearの場合は、原則として「ウェア」とするtextlintルール。 24 | 25 | ### [@textlint-ja/textlint-rule-kana-english-suffix-y](packages/textlint-rule-kana-english-suffix-y) 26 | 27 | > 原語の語尾が-yの場合は、カタカナを長音記号「ー」で表わすのを原則とするtextlintルール 28 | 29 | ### [@textlint-ja/textlint-rule-no-kana-english-v](packages/textlint-rule-no-kana-english-v) 30 | 31 | > 原語が「v」の場合はカタカナに「ヴ」を使わないのが原則とするtextlintルール 32 | 33 | ## References 34 | 35 | - [文化庁 | 国語施策・日本語教育 | 国語施策情報 | 内閣告示・内閣訓令 | 外来語の表記](https://www.bunka.go.jp/kokugo_nihongo/sisaku/joho/joho/kijun/naikaku/gairai/index.html) 36 | - [JIS Z 8301:2011 規格票の様式及び作成方法](https://kikakurui.com/z8/Z8301-2011-01.html) 37 | - [記者ハンドブック 第13版](https://www.kyodo.co.jp/books/isbn/978-4-7641-0687-1/) 38 | - [テクニカルコミュニケーター協会 > 標準規格](https://www.jtca.org/standardization/) 39 | - [外来語(カタカナ)表記ガイドライン](https://www.jtca.org/standardization/katakana_guide_3_20171222.pdf) 40 | 41 | ## Changelog 42 | 43 | See [Releases page](https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing/releases). 44 | 45 | ## Running tests 46 | 47 | Install devDependencies and Run `npm test`: 48 | 49 | npm i -d && npm test 50 | 51 | ## Contributing 52 | 53 | Pull requests and stars are always welcome. 54 | 55 | For bugs and feature requests, [please create an issue](https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing/issues). 56 | 57 | 1. Fork it! 58 | 2. Create your feature branch: `git checkout -b my-new-feature` 59 | 3. Commit your changes: `git commit -am 'Add some feature'` 60 | 4. Push to the branch: `git push origin my-new-feature` 61 | 5. Submit a pull request :D 62 | 63 | ## Author 64 | 65 | - [github/azu](https://github.com/azu) 66 | - [twitter/azu_re](https://twitter.com/azu_re) 67 | 68 | ## License 69 | 70 | MIT © azu 71 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | "packages/*" 4 | ], 5 | "useWorkspaces": true, 6 | "npmClient": "yarn", 7 | "includeMergedTags": true, 8 | "version": "0.0.0" 9 | } 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "root", 4 | "version": "1.0.0", 5 | "description": "外来語(カタナカ)の書き方を扱うtextlintルールプリセット", 6 | "license": "MIT", 7 | "author": "azu", 8 | "workspaces": { 9 | "packages": [ 10 | "packages/*" 11 | ] 12 | }, 13 | "scripts": { 14 | "bootstrap": "lerna bootstrap", 15 | "versionup": "lerna version --conventional-commits", 16 | "versionup:patch": "lerna version patch --conventional-commits", 17 | "versionup:minor": "lerna version minor --conventional-commits", 18 | "versionup:major": "lerna version major --conventional-commits", 19 | "release": "lerna publish from-package", 20 | "build": "lerna run build", 21 | "build:lib": "lerna run --scope \"@textlint-ja/*-helper\" build", 22 | "test": "yarn run build:lib && lerna run test", 23 | "clean": "lerna run clean", 24 | "prettier": "prettier --write '**/*.{js,jsx,ts,tsx,css}'", 25 | "update:readme": "ts-node tools/update-readme.ts" 26 | }, 27 | "husky": { 28 | "hooks": { 29 | "pre-commit": "lint-staged" 30 | } 31 | }, 32 | "lint-staged": { 33 | "*.{js,jsx,ts,tsx,css}": [ 34 | "prettier --write", 35 | "git add" 36 | ] 37 | }, 38 | "prettier": { 39 | "printWidth": 120, 40 | "singleQuote": false, 41 | "tabWidth": 4 42 | }, 43 | "devDependencies": { 44 | "@monorepo-utils/package-utils": "^2.0.3", 45 | "add-text-to-markdown": "^2.0.0", 46 | "husky": "^3.1.0", 47 | "lerna": "^3.20.0", 48 | "lint-staged": "^9.5.0", 49 | "prettier": "^1.19.1", 50 | "ts-node": "^8.5.4", 51 | "ts-node-test-register": "^8.0.1", 52 | "typescript": "^3.7.4" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /packages/textlint-rule-kana-english-fo-pho/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019 azu 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /packages/textlint-rule-kana-english-fo-pho/README.md: -------------------------------------------------------------------------------- 1 | # @textlint-ja/textlint-rule-kana-english-fo-pho 2 | 3 | 原語が「fo」または「pho」の場合は、カタカナでは「フォ」とするのを原則とするtextlintルール。 4 | 5 | **OK**: 6 | 7 | ``` 8 | インフォ(info) 9 | インフォメーション(information) 10 | フォーム(form) 11 | フォント(font) 12 | ハイホン(hyphon) 13 | フォロー(follow) 14 | アイフォン(iPhone) 15 | フォト(photo) 16 | フォトグラファー(photology) 17 | フォビア(phobia) 18 | プラットホーム(platform)は例外で、プラットフォームでもいい 19 | ホーム(homu)は例外、フォームと区別できない 20 | テレホン(telephone)は例外 21 | イヤホン(earphone)は例外 22 | メガホン(megaphon)は例外 23 | ``` 24 | 25 | **NG**: 26 | 27 | ``` 28 | インホメーションは-fo-なのでフォを使う 29 | パホーマンスは-fo-なのでフォを使う 30 | ``` 31 | 32 | ## Install 33 | 34 | Install with [npm](https://www.npmjs.com/): 35 | 36 | npm install @textlint-ja/textlint-rule-kana-english-fo-pho 37 | 38 | ## Usage 39 | 40 | Via `.textlintrc`(Recommended) 41 | 42 | ```json 43 | { 44 | "rules": { 45 | "@textlint-ja/kana-english-fo-pho": true 46 | } 47 | } 48 | ``` 49 | 50 | Via CLI 51 | 52 | ``` 53 | textlint --rule @textlint-ja/kana-english-fo-pho README.md 54 | ``` 55 | 56 | ## Options 57 | 58 | ```ts 59 | { 60 | /** 61 | * 許可する単語を指定できます 62 | */ 63 | allows?: string[]; 64 | /** 65 | * 慣用的に例外とされる単語も不許可にするかどうか 66 | * デフォルト: false 67 | */ 68 | disableBuiltinAllows: boolean; 69 | } 70 | ``` 71 | 72 | Example: 73 | 74 | ```json 75 | { 76 | "rules": { 77 | "@textlint-ja/kana-english-fo-pho": { 78 | "allows": ["イヤフォン"], 79 | "disableDefaultAllows": true 80 | } 81 | } 82 | } 83 | ``` 84 | 85 | ## References 86 | 87 | - [テクニカルコミュニケーター協会 > 標準規格](https://www.jtca.org/standardization/) 88 | - [「スマートホン」か「スマートフォン」か|NHK放送文化研究所](https://www.nhk.or.jp/bunken/research/kotoba/20161001_1.html) 89 | 90 | ## Changelog 91 | 92 | See [Releases page](https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing/releases). 93 | 94 | ## Running tests 95 | 96 | Install devDependencies and Run `npm test`: 97 | 98 | yarn install && yarn test 99 | 100 | ## Contributing 101 | 102 | Pull requests and stars are always welcome. 103 | 104 | For bugs and feature requests, [please create an issue](https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing/issues). 105 | 106 | 1. Fork it! 107 | 2. Create your feature branch: `git checkout -b my-new-feature` 108 | 3. Commit your changes: `git commit -am 'Add some feature'` 109 | 4. Push to the branch: `git push origin my-new-feature` 110 | 5. Submit a pull request :D 111 | 112 | ## Author 113 | 114 | - [github/azu](https://github.com/azu) 115 | - [twitter/azu_re](https://twitter.com/azu_re) 116 | 117 | ## License 118 | 119 | MIT © azu 120 | -------------------------------------------------------------------------------- /packages/textlint-rule-kana-english-fo-pho/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@textlint-ja/textlint-rule-kana-english-fo-pho", 3 | "version": "1.0.0", 4 | "description": "原語が「fo」または「pho」の場合は、カタカナでは「フォ」とするのを原則とするtextlintルール", 5 | "keywords": [ 6 | "textlintrule" 7 | ], 8 | "homepage": "https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing/tree/master/packages/textlint-rule-kana-english-fo-pho/", 9 | "bugs": { 10 | "url": "https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing/issues" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing.git" 15 | }, 16 | "license": "MIT", 17 | "author": "azu", 18 | "files": [ 19 | "bin/", 20 | "lib/", 21 | "src/" 22 | ], 23 | "main": "lib/textlint-rule-kana-english-fo-pho.js", 24 | "directories": { 25 | "lib": "lib", 26 | "test": "test" 27 | }, 28 | "scripts": { 29 | "build": "textlint-scripts build", 30 | "prettier": "prettier --write \"**/*.{js,jsx,ts,tsx,css}\"", 31 | "prepublish": "npm run --if-present build", 32 | "test": "textlint-scripts test", 33 | "watch": "textlint-scripts build --watch" 34 | }, 35 | "prettier": { 36 | "printWidth": 120, 37 | "singleQuote": false, 38 | "tabWidth": 4 39 | }, 40 | "devDependencies": { 41 | "@textlint/types": "^1.2.3", 42 | "@types/node": "^13.1.1", 43 | "prettier": "^1.19.1", 44 | "textlint-scripts": "^3.0.0", 45 | "textlint-tester": "^5.1.11", 46 | "ts-node": "^8.5.4", 47 | "typescript": "^3.7.4", 48 | "sudachi-synonyms-dictionary": "^4.1.0" 49 | }, 50 | "peerDependencies": { 51 | "sudachi-synonyms-dictionary": "*" 52 | }, 53 | "publishConfig": { 54 | "access": "public" 55 | }, 56 | "dependencies": { 57 | "textlint-rule-helper": "^2.1.1", 58 | "string.prototype.matchall": "^4.0.2", 59 | "@textlint-ja/textlint-rule-preset-foreign-language-writing-helper": "^1.0.0" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /packages/textlint-rule-kana-english-fo-pho/src/textlint-rule-kana-english-fo-pho.ts: -------------------------------------------------------------------------------- 1 | import { TextlintRuleOptions, TextlintRuleReporter } from "@textlint/types"; 2 | import { wrapReportHandler } from "textlint-rule-helper"; 3 | import { 4 | createKatakanaEnglishIndex, 5 | KatakanEnglishIndexType 6 | } from "@textlint-ja/textlint-rule-preset-foreign-language-writing-helper"; 7 | import { TxtNodeType } from "@textlint/ast-node-types"; 8 | 9 | const matchAll = require("string.prototype.matchall"); 10 | // ・を含む場合はそれぞれ単語として見る 11 | const KATAKANA = /[ァ-ヴ][ァ-ヴー]*/g; 12 | export type Options = { 13 | /** 14 | * 許可する単語を指定できます 15 | */ 16 | allows?: string[]; 17 | /** 18 | * 慣用的に例外とされる単語も不許可にするかどうか 19 | * ビルトインでいくつかの例外が定義されています 20 | * デフォルト: false 21 | */ 22 | disableBuiltinAllows?: boolean; 23 | /** 24 | * 無視したいTxtNodeのTypesを指定します 25 | * See https://textlint.github.io/docs/txtnode.html#type 26 | * Default: ["Link", "BlockQuote", "Emphasis", "Strong", "Code", "Comment", "Html"] 27 | */ 28 | ignoreNodeTypes?: TxtNodeType[]; 29 | }; 30 | /** 31 | * 慣用的に例外とされる単語 32 | */ 33 | const BUILTIN_ALLOW_WORDS: string[] = [ 34 | "ホルマリン", 35 | "メガホン", 36 | "テレホン", 37 | "イヤホン", 38 | "インターホン", 39 | "マイクロホン", 40 | "スピーカーホン", 41 | "ヘッドホン", 42 | // フォームと区別できない 43 | "ホーム", 44 | // 同じカタカナで示すものが違うときに、表記揺れがある単語なので限定しない 45 | // ソフトウェアについてはプラットフォームが使われる 46 | "プラットホーム" 47 | ]; 48 | 49 | export const DEFAULT_OPTIONS = { 50 | allows: [], 51 | disableBuiltinAllows: false, 52 | ignoreNodeTypes: ["Link", "BlockQuote", "Emphasis", "Strong", "Code", "Comment", "Html"] 53 | }; 54 | export const report: TextlintRuleReporter> = (context, options = {}) => { 55 | const { Syntax, getSource, RuleError, fixer } = context; 56 | const indexPromise: Promise = createKatakanaEnglishIndex(); 57 | const allows = options.allows || DEFAULT_OPTIONS.allows; 58 | const ignoreNodeTypes = options.ignoreNodeTypes || DEFAULT_OPTIONS.ignoreNodeTypes; 59 | const disableBuiltinAllows = 60 | options.disableBuiltinAllows !== undefined 61 | ? options.disableBuiltinAllows 62 | : DEFAULT_OPTIONS.disableBuiltinAllows; 63 | return wrapReportHandler( 64 | context, 65 | { 66 | ignoreNodeTypes: ignoreNodeTypes 67 | }, 68 | report => { 69 | return { 70 | async [Syntax.Str](node) { 71 | const { midashiMap } = await indexPromise; 72 | const text = getSource(node); 73 | const katakanaItems = matchAll(text, KATAKANA); 74 | for (const katakanaItem of katakanaItems) { 75 | // カタカナの原語を取得する 76 | const matchKatakana = katakanaItem[0]; 77 | if (!matchKatakana) { 78 | continue; 79 | } 80 | const foWord = matchKatakana.includes("ホ") ? matchKatakana.replace("ホ", "フォ") : ""; 81 | const englishItems = (midashiMap.get(matchKatakana) || []).concat(midashiMap.get(foWord) || []); 82 | if (!englishItems) { 83 | continue; 84 | } 85 | // # 判定 86 | // 英単語が -fo-, -pho- 87 | const matchEnglishWords = englishItems.filter(item => { 88 | return item.includes("fo") || item.endsWith("pho"); 89 | }); 90 | if (matchEnglishWords.length === 0) { 91 | continue; 92 | } 93 | // 元のカタカナが「フォ」になっているならOK 94 | if (matchKatakana.includes("フォ")) { 95 | continue; 96 | } 97 | // 例外は除外する 98 | if (allows.includes(matchKatakana)) { 99 | continue; 100 | } 101 | // ビルトイン例外を除外する if disableBuiltinAllows:false 102 | if (!disableBuiltinAllows) { 103 | if (BUILTIN_ALLOW_WORDS.includes(matchKatakana)) { 104 | continue; 105 | } 106 | } 107 | const index = katakanaItem.index; 108 | if (index === undefined) { 109 | continue; 110 | } 111 | // 単語中に"ホ"が複数ある場合に位置を特定できない問題があるので、1つの場合のみをfixにする 112 | const hoCount = matchKatakana.split("ホ").length - 1; 113 | // 2つ以上ある場合は修正はしない 114 | if (hoCount >= 2) { 115 | return report( 116 | node, 117 | new RuleError( 118 | "原語が「fo」または「pho」の場合はカタカナでは「フォ」とするのが原則です", 119 | { 120 | index: index 121 | } 122 | ) 123 | ); 124 | } else { 125 | const startIndex = matchKatakana.indexOf("ホ"); 126 | report( 127 | node, 128 | new RuleError( 129 | "原語が「fo」または「pho」の場合はカタカナでは「フォ」とするのが原則です", 130 | { 131 | index: index, 132 | fix: fixer.replaceTextRange([startIndex, startIndex + 1], "フォ") 133 | } 134 | ) 135 | ); 136 | } 137 | } 138 | } 139 | }; 140 | } 141 | ); 142 | }; 143 | export default { 144 | linter: report, 145 | fixer: report 146 | }; 147 | -------------------------------------------------------------------------------- /packages/textlint-rule-kana-english-fo-pho/test/textlint-rule-kana-english-fo-pho.test.ts: -------------------------------------------------------------------------------- 1 | import TextLintTester from "textlint-tester"; 2 | 3 | const tester = new TextLintTester(); 4 | // rule 5 | import rule from "../src/textlint-rule-kana-english-fo-pho"; 6 | // ruleName, rule, { valid, invalid } 7 | tester.run("textlint-rule-kana-english-fo-pho", rule, { 8 | valid: [ 9 | // -fo- 10 | "インフォ(info)", 11 | "インフォメーション(information)", 12 | "フォーム(form)", 13 | "フォント(font)", 14 | "ハイホン(hyphon)", 15 | "フォロー(follow)", 16 | "フォロワー(follower)", 17 | "フォワード(forward)", 18 | "フォーク ダンス(folk dance)", 19 | "フォルダー(folder)", 20 | "ユニフォーム(uniform)", 21 | // -pho- 22 | "アイフォン(iPhone)", 23 | "フォト(photo)", 24 | "フォトグラファー(photology)", 25 | "フォビア(phobia)", 26 | // 例外 27 | "プラットホーム(platform)は例外で、プラットフォームでもいい", 28 | "ホーム(homu)は例外、フォームと区別できない", 29 | "テレホン(telephone)は例外", 30 | "イヤホン(earphone)は例外", 31 | "メガホン(megaphon)は例外", 32 | // オプション 33 | { 34 | text: "インホーメーション", 35 | options: { 36 | allows: ["インホーメーション"] 37 | } 38 | } 39 | ], 40 | invalid: [ 41 | { 42 | text: "インホメーションは-fo-なのでフォを使う", 43 | output: "インフォメーションは-fo-なのでフォを使う", 44 | errors: [ 45 | { 46 | index: 0, 47 | message: "原語が「fo」または「pho」の場合はカタカナでは「フォ」とするのが原則です" 48 | } 49 | ] 50 | }, 51 | { 52 | text: "パホーマンスは-fo-なのでフォを使う", 53 | output: "パフォーマンスは-fo-なのでフォを使う", 54 | errors: [ 55 | { 56 | index: 0, 57 | message: "原語が「fo」または「pho」の場合はカタカナでは「フォ」とするのが原則です" 58 | } 59 | ] 60 | } 61 | ] 62 | }); 63 | -------------------------------------------------------------------------------- /packages/textlint-rule-kana-english-fo-pho/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Basic Options */ 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "esModuleInterop": true, 7 | "newLine": "LF", 8 | "outDir": "./lib/", 9 | "target": "es2015", 10 | "sourceMap": true, 11 | "declaration": true, 12 | "jsx": "preserve", 13 | "lib": [ 14 | "esnext", 15 | "dom" 16 | ], 17 | /* Strict Type-Checking Options */ 18 | "strict": true, 19 | /* Additional Checks */ 20 | /* Report errors on unused locals. */ 21 | "noUnusedLocals": true, 22 | /* Report errors on unused parameters. */ 23 | "noUnusedParameters": true, 24 | /* Report error when not all code paths in function return a value. */ 25 | "noImplicitReturns": true, 26 | /* Report errors for fallthrough cases in switch statement. */ 27 | "noFallthroughCasesInSwitch": true 28 | }, 29 | "include": [ 30 | "src/**/*" 31 | ], 32 | "exclude": [ 33 | ".git", 34 | "node_modules" 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /packages/textlint-rule-kana-english-suffix-er/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019 azu 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /packages/textlint-rule-kana-english-suffix-er/README.md: -------------------------------------------------------------------------------- 1 | # @textlint-ja/textlint-rule-kana-english-suffix-er 2 | 3 | 原語の語尾の-er,-or,-arはカタカナでは長音にするtextlintルール 4 | 5 | **OK**: 6 | 7 | ``` 8 | エディターはOK 9 | エントリーはOK 10 | サーバーはOK 11 | マネージャーはOK 12 | メーカーはOK 13 | モーターはOK 14 | プロジェクターはOK 15 | リボルバーはOK 16 | レーダーはOK 17 | モジュラーはOK 18 | カレンダーはOK 19 | エンジニアは例外 20 | ギアは例外 21 | ジュニアは例外 22 | ``` 23 | 24 | **NG**: 25 | 26 | ``` 27 | エディタは-erなので長音 28 | サーバは-erなので長音 29 | ユーザは-erなので長音 30 | ローカル・サーバは-erなので長音 31 | ネットでコンピュータを買う 32 | ``` 33 | 34 | ## Install 35 | 36 | Install with [npm](https://www.npmjs.com/): 37 | 38 | npm install @textlint-ja/textlint-rule-kana-english-suffix-er 39 | 40 | ## Usage 41 | 42 | Via `.textlintrc`(Recommended) 43 | 44 | ```json 45 | { 46 | "rules": { 47 | "@textlint-ja/kana-english-suffix-er": true 48 | } 49 | } 50 | ``` 51 | 52 | Via CLI 53 | 54 | ``` 55 | textlint --rule @textlint-ja/kana-english-suffix-er README.md 56 | ``` 57 | 58 | ## Options 59 | 60 | ```ts 61 | { 62 | /** 63 | * 許可する単語を指定できます 64 | */ 65 | allows?: string[]; 66 | /** 67 | * 慣用的に長音が省略される単語も不許可にするかどうか 68 | * デフォルト: false 69 | */ 70 | disableBuiltinAllows: boolean; 71 | } 72 | ``` 73 | 74 | Example: 75 | 76 | ```json 77 | { 78 | "rules": { 79 | "@textlint-ja/kana-english-suffix-er": { 80 | "allows": ["エディタ"], 81 | "disableDefaultAllows": true 82 | } 83 | } 84 | } 85 | ``` 86 | 87 | ## Changelog 88 | 89 | See [Releases page](https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing/releases). 90 | 91 | ## Running tests 92 | 93 | Install devDependencies and Run `npm test`: 94 | 95 | npm i -d && npm test 96 | 97 | ## Contributing 98 | 99 | Pull requests and stars are always welcome. 100 | 101 | For bugs and feature requests, [please create an issue](https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing/issues). 102 | 103 | 1. Fork it! 104 | 2. Create your feature branch: `git checkout -b my-new-feature` 105 | 3. Commit your changes: `git commit -am 'Add some feature'` 106 | 4. Push to the branch: `git push origin my-new-feature` 107 | 5. Submit a pull request :D 108 | 109 | ## Author 110 | 111 | - [github/azu](https://github.com/azu) 112 | - [twitter/azu_re](https://twitter.com/azu_re) 113 | 114 | ## License 115 | 116 | MIT © azu 117 | -------------------------------------------------------------------------------- /packages/textlint-rule-kana-english-suffix-er/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@textlint-ja/textlint-rule-kana-english-suffix-er", 3 | "version": "1.0.0", 4 | "description": "原語の語尾の-er,-or,-arをカタカナでは長音記号「ー」で表わすの原則とするtextlintルール", 5 | "keywords": [ 6 | "textlintrule" 7 | ], 8 | "homepage": "https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing/tree/master/packages/textlint-rule-kana-english-suffix-er/", 9 | "bugs": { 10 | "url": "https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing/issues" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing.git" 15 | }, 16 | "license": "MIT", 17 | "author": "azu", 18 | "files": [ 19 | "bin/", 20 | "lib/", 21 | "src/" 22 | ], 23 | "main": "lib/textlint-rule-kana-english-suffix-er.js", 24 | "directories": { 25 | "lib": "lib", 26 | "test": "test" 27 | }, 28 | "scripts": { 29 | "build": "textlint-scripts build", 30 | "prettier": "prettier --write \"**/*.{js,jsx,ts,tsx,css}\"", 31 | "prepublish": "npm run --if-present build", 32 | "test": "textlint-scripts test", 33 | "watch": "textlint-scripts build --watch" 34 | }, 35 | "prettier": { 36 | "printWidth": 120, 37 | "singleQuote": false, 38 | "tabWidth": 4 39 | }, 40 | "devDependencies": { 41 | "@textlint/types": "^1.2.3", 42 | "@types/node": "^13.1.1", 43 | "prettier": "^1.19.1", 44 | "textlint-scripts": "^3.0.0", 45 | "textlint-tester": "^5.1.11", 46 | "ts-node": "^8.5.4", 47 | "typescript": "^3.7.4", 48 | "sudachi-synonyms-dictionary": "^4.1.0" 49 | }, 50 | "peerDependencies": { 51 | "sudachi-synonyms-dictionary": "*" 52 | }, 53 | "publishConfig": { 54 | "access": "public" 55 | }, 56 | "dependencies": { 57 | "textlint-rule-helper": "^2.1.1", 58 | "string.prototype.matchall": "^4.0.2", 59 | "@textlint-ja/textlint-rule-preset-foreign-language-writing-helper": "^1.0.0" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /packages/textlint-rule-kana-english-suffix-er/src/textlint-rule-kana-english-suffix-er.ts: -------------------------------------------------------------------------------- 1 | import { TextlintRuleOptions, TextlintRuleReporter } from "@textlint/types"; 2 | import { wrapReportHandler } from "textlint-rule-helper"; 3 | import { 4 | createKatakanaEnglishIndex, 5 | KatakanEnglishIndexType 6 | } from "@textlint-ja/textlint-rule-preset-foreign-language-writing-helper"; 7 | import { TxtNodeType } from "@textlint/ast-node-types"; 8 | 9 | const matchAll = require("string.prototype.matchall"); 10 | // ・を含む場合はそれぞれ単語として見る 11 | const KATAKANA = /[ァ-ヴ][ァ-ヴー]*/g; 12 | export type Options = { 13 | /** 14 | * 許可する単語を指定できます 15 | */ 16 | allows?: string[]; 17 | /** 18 | * 慣用的に長音が省略される単語も不許可にするかどうか 19 | * ビルトインでいくつかの例外が定義されています 20 | * デフォルト: false 21 | */ 22 | disableBuiltinAllows?: boolean; 23 | /** 24 | * 無視したいTxtNodeのTypesを指定します 25 | * See https://textlint.github.io/docs/txtnode.html#type 26 | * Default: ["Link", "BlockQuote", "Emphasis", "Strong", "Code", "Comment", "Html"] 27 | */ 28 | ignoreNodeTypes?: TxtNodeType[]; 29 | }; 30 | /** 31 | * 慣用的に長音が省略される単語 32 | */ 33 | const BUILTIN_ALLOW_WORDS = [ 34 | "ギア", 35 | // wear 36 | "ウェア", 37 | "ジュニア", 38 | "エンジニア" 39 | ]; 40 | 41 | export const DEFAULT_OPTIONS = { 42 | allows: [], 43 | disableBuiltinAllows: false, 44 | ignoreNodeTypes: ["Link", "BlockQuote", "Emphasis", "Strong", "Code", "Comment", "Html"] 45 | }; 46 | export const report: TextlintRuleReporter> = (context, options = {}) => { 47 | const { Syntax, getSource, RuleError, fixer } = context; 48 | const indexPromise: Promise = createKatakanaEnglishIndex(); 49 | const allows = options.allows || DEFAULT_OPTIONS.allows; 50 | const ignoreNodeTypes = options.ignoreNodeTypes || DEFAULT_OPTIONS.ignoreNodeTypes; 51 | const disableBuiltinAllows = 52 | options.disableBuiltinAllows !== undefined 53 | ? options.disableBuiltinAllows 54 | : DEFAULT_OPTIONS.disableBuiltinAllows; 55 | return wrapReportHandler( 56 | context, 57 | { 58 | ignoreNodeTypes: ignoreNodeTypes 59 | }, 60 | report => { 61 | return { 62 | async [Syntax.Str](node) { 63 | const { midashiMap } = await indexPromise; 64 | const text = getSource(node); 65 | const katakanaItems = matchAll(text, KATAKANA); 66 | for (const katakanaItem of katakanaItems) { 67 | // カタカナの原語を取得する 68 | const matchKatakana = katakanaItem[0]; 69 | if (!matchKatakana) { 70 | continue; 71 | } 72 | const englishItems = midashiMap.get(matchKatakana); 73 | if (!englishItems) { 74 | continue; 75 | } 76 | // # 判定 77 | // 英単語が -er, -or, -ar 78 | const isErEnglish = englishItems.some(item => { 79 | return item.endsWith("er") || item.endsWith("or") || item.endsWith("ar"); 80 | }); 81 | if (!isErEnglish) { 82 | continue; 83 | } 84 | // 元のカタカナがー(長音)で終わっていない 85 | if (matchKatakana.endsWith("ー")) { 86 | continue; 87 | } 88 | // 例外は除外する 89 | if (allows.includes(matchKatakana)) { 90 | continue; 91 | } 92 | // ビルトイン例外を除外する if disableBuiltinAllows:false 93 | if (!disableBuiltinAllows) { 94 | if (BUILTIN_ALLOW_WORDS.includes(matchKatakana)) { 95 | continue; 96 | } 97 | } 98 | const index = katakanaItem.index; 99 | if (index === undefined) { 100 | continue; 101 | } 102 | const endIndex = index + matchKatakana.length - 1; 103 | report( 104 | node, 105 | new RuleError( 106 | "原語の語尾が-er,-or,-ar場合はカタカナでは長音記号「ー」で表わすのが原則です", 107 | { 108 | index: index, 109 | fix: fixer.insertTextAfterRange([endIndex, endIndex + 1], "ー") 110 | } 111 | ) 112 | ); 113 | } 114 | } 115 | }; 116 | } 117 | ); 118 | }; 119 | export default { 120 | linter: report, 121 | fixer: report 122 | }; 123 | -------------------------------------------------------------------------------- /packages/textlint-rule-kana-english-suffix-er/test/textlint-rule-kana-english-suffix-er.test.ts: -------------------------------------------------------------------------------- 1 | import TextLintTester from "textlint-tester"; 2 | 3 | const tester = new TextLintTester(); 4 | // rule 5 | import rule from "../src/textlint-rule-kana-english-suffix-er"; 6 | // ruleName, rule, { valid, invalid } 7 | tester.run("textlint-rule-kana-english-suffix-er", rule, { 8 | valid: [ 9 | "エディターはOK", 10 | "エントリーはOK", 11 | "サーバーはOK", 12 | "マネージャーはOK", 13 | "メーカーはOK", 14 | "モーターはOK", 15 | "プロジェクターはOK", 16 | "リボルバーはOK", 17 | "レーダーはOK", 18 | "モジュラーはOK", 19 | "カレンダーはOK", 20 | // 一般的に長音記号を使わない単語は例外とする 21 | "エンジニアは例外", 22 | "ウェアは例外", 23 | "ギアは例外", 24 | "ジュニアは例外", 25 | // オプション 26 | { 27 | text: "エディタ", 28 | options: { 29 | allows: ["エディタ"] 30 | } 31 | } 32 | ], 33 | invalid: [ 34 | { 35 | text: "エディタは-erなので長音", 36 | output: "エディターは-erなので長音", 37 | errors: [ 38 | { 39 | index: 0, 40 | message: "原語の語尾が-er,-or,-ar場合はカタカナでは長音記号「ー」で表わすのが原則です" 41 | } 42 | ] 43 | }, 44 | { 45 | text: "サーバは-erなので長音", 46 | output: "サーバーは-erなので長音", 47 | errors: [ 48 | { 49 | index: 0, 50 | message: "原語の語尾が-er,-or,-ar場合はカタカナでは長音記号「ー」で表わすのが原則です" 51 | } 52 | ] 53 | }, 54 | { 55 | text: "ユーザは-erなので長音", 56 | output: "ユーザーは-erなので長音", 57 | errors: [ 58 | { 59 | index: 0, 60 | message: "原語の語尾が-er,-or,-ar場合はカタカナでは長音記号「ー」で表わすのが原則です" 61 | } 62 | ] 63 | }, 64 | { 65 | text: "フィルタは-erなので長音", 66 | output: "フィルターは-erなので長音", 67 | errors: [ 68 | { 69 | index: 0, 70 | message: "原語の語尾が-er,-or,-ar場合はカタカナでは長音記号「ー」で表わすのが原則です" 71 | } 72 | ] 73 | }, 74 | { 75 | text: "ローカル・サーバは-erなので長音", 76 | output: "ローカル・サーバーは-erなので長音", 77 | errors: [ 78 | { 79 | index: 5, 80 | message: "原語の語尾が-er,-or,-ar場合はカタカナでは長音記号「ー」で表わすのが原則です" 81 | } 82 | ] 83 | }, 84 | { 85 | text: "ネットでコンピュータを買う", 86 | output: "ネットでコンピューターを買う", 87 | errors: [ 88 | { 89 | index: 4, 90 | message: "原語の語尾が-er,-or,-ar場合はカタカナでは長音記号「ー」で表わすのが原則です" 91 | } 92 | ] 93 | } 94 | ] 95 | }); 96 | -------------------------------------------------------------------------------- /packages/textlint-rule-kana-english-suffix-er/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Basic Options */ 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "esModuleInterop": true, 7 | "newLine": "LF", 8 | "outDir": "./lib/", 9 | "target": "es2015", 10 | "sourceMap": true, 11 | "declaration": true, 12 | "jsx": "preserve", 13 | "lib": [ 14 | "esnext", 15 | "dom" 16 | ], 17 | /* Strict Type-Checking Options */ 18 | "strict": true, 19 | /* Additional Checks */ 20 | /* Report errors on unused locals. */ 21 | "noUnusedLocals": true, 22 | /* Report errors on unused parameters. */ 23 | "noUnusedParameters": true, 24 | /* Report error when not all code paths in function return a value. */ 25 | "noImplicitReturns": true, 26 | /* Report errors for fallthrough cases in switch statement. */ 27 | "noFallthroughCasesInSwitch": true 28 | }, 29 | "include": [ 30 | "src/**/*" 31 | ], 32 | "exclude": [ 33 | ".git", 34 | "node_modules" 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /packages/textlint-rule-kana-english-suffix-re/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019 azu 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /packages/textlint-rule-kana-english-suffix-re/README.md: -------------------------------------------------------------------------------- 1 | # @textlint-ja/textlint-rule-kana-english-suffix-re 2 | 3 | - 原語の語尾が-reの場合は、原則として長音記号「ー」を付けないのが原則です 4 | - 原語の語尾が-ture,-sureの場合は、原則として長音記号「ー」を付けるのが原則です 5 | 6 | **OK**: 7 | 8 | ``` 9 | ファームウェア(firmware) 10 | ハードウェア(hardware) 11 | ピュア(pure) 12 | スコア(score) 13 | シェア(share) 14 | ソフトウェア(software) 15 | ... -ture, -sure 16 | アドベンチャー(adventure) 17 | カルチャー(culture) 18 | フィーチャー(feature) 19 | ネイチャー(nature) 20 | プレッシャー(pressure) 21 | ミニチュアは例外 22 | ``` 23 | 24 | **NG**: 25 | 26 | ``` 27 | フリーウェアー(freeware) 28 | スクエアー(square) 29 | ストアー(store) 30 | カルチャ(culture) 31 | プレッシャ(pressure) 32 | ``` 33 | 34 | ## Install 35 | 36 | Install with [npm](https://www.npmjs.com/): 37 | 38 | npm install @textlint-ja/textlint-rule-kana-english-suffix-re 39 | 40 | ## Usage 41 | 42 | Via `.textlintrc`(Recommended) 43 | 44 | ```json 45 | { 46 | "rules": { 47 | "@textlint-ja/kana-english-suffix-re": true 48 | } 49 | } 50 | ``` 51 | 52 | Via CLI 53 | 54 | ``` 55 | textlint --rule @textlint-ja/kana-english-suffix-re README.md 56 | ``` 57 | 58 | ## Options 59 | 60 | ```ts 61 | { 62 | /** 63 | * 許可する単語を指定できます 64 | */ 65 | allows?: string[]; 66 | /** 67 | * 慣用的に例外として扱われる単語も不許可にするかどうか 68 | * デフォルト: false 69 | */ 70 | disableBuiltinAllows: boolean; 71 | } 72 | ``` 73 | 74 | Example: 75 | 76 | ```json 77 | { 78 | "rules": { 79 | "@textlint-ja/kana-english-suffix-re": { 80 | "allows": ["フリーウェア"], 81 | "disableDefaultAllows": true 82 | } 83 | } 84 | } 85 | ``` 86 | 87 | ## Changelog 88 | 89 | See [Releases page](https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing/releases). 90 | 91 | ## Running tests 92 | 93 | Install devDependencies and Run `npm test`: 94 | 95 | npm i -d && npm test 96 | 97 | ## Contributing 98 | 99 | Pull requests and stars are always welcome. 100 | 101 | For bugs and feature requests, [please create an issue](https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing/issues). 102 | 103 | 1. Fork it! 104 | 2. Create your feature branch: `git checkout -b my-new-feature` 105 | 3. Commit your changes: `git commit -am 'Add some feature'` 106 | 4. Push to the branch: `git push origin my-new-feature` 107 | 5. Submit a pull request :D 108 | 109 | ## Author 110 | 111 | - [github/azu](https://github.com/azu) 112 | - [twitter/azu_re](https://twitter.com/azu_re) 113 | 114 | ## License 115 | 116 | MIT © azu 117 | -------------------------------------------------------------------------------- /packages/textlint-rule-kana-english-suffix-re/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@textlint-ja/textlint-rule-kana-english-suffix-re", 3 | "version": "1.0.0", 4 | "description": "原語の語尾が-reの場合は長音記号「ー」を付けない、原語の語尾が-ture,-sureの場合は原則として長音記号「ー」を付けるtextlintルール", 5 | "keywords": [ 6 | "textlintrule" 7 | ], 8 | "homepage": "https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing/tree/master/packages/textlint-rule-kana-english-suffix-re/", 9 | "bugs": { 10 | "url": "https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing/issues" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing.git" 15 | }, 16 | "license": "MIT", 17 | "author": "azu", 18 | "files": [ 19 | "bin/", 20 | "lib/", 21 | "src/" 22 | ], 23 | "main": "lib/textlint-rule-kana-english-suffix-re.js", 24 | "directories": { 25 | "lib": "lib", 26 | "test": "test" 27 | }, 28 | "scripts": { 29 | "build": "textlint-scripts build", 30 | "prettier": "prettier --write \"**/*.{js,jsx,ts,tsx,css}\"", 31 | "prepublish": "npm run --if-present build", 32 | "test": "textlint-scripts test", 33 | "watch": "textlint-scripts build --watch" 34 | }, 35 | "prettier": { 36 | "printWidth": 120, 37 | "singleQuote": false, 38 | "tabWidth": 4 39 | }, 40 | "devDependencies": { 41 | "@textlint/types": "^1.2.3", 42 | "@types/node": "^13.1.1", 43 | "prettier": "^1.19.1", 44 | "textlint-scripts": "^3.0.0", 45 | "textlint-tester": "^5.1.11", 46 | "ts-node": "^8.5.4", 47 | "typescript": "^3.7.4", 48 | "sudachi-synonyms-dictionary": "^4.1.0" 49 | }, 50 | "peerDependencies": { 51 | "sudachi-synonyms-dictionary": "*" 52 | }, 53 | "publishConfig": { 54 | "access": "public" 55 | }, 56 | "dependencies": { 57 | "textlint-rule-helper": "^2.1.1", 58 | "string.prototype.matchall": "^4.0.2", 59 | "@textlint-ja/textlint-rule-preset-foreign-language-writing-helper": "^1.0.0" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /packages/textlint-rule-kana-english-suffix-re/src/textlint-rule-kana-english-suffix-re.ts: -------------------------------------------------------------------------------- 1 | import { TextlintRuleOptions, TextlintRuleReporter } from "@textlint/types"; 2 | import { wrapReportHandler } from "textlint-rule-helper"; 3 | import { 4 | createKatakanaEnglishIndex, 5 | KatakanEnglishIndexType 6 | } from "@textlint-ja/textlint-rule-preset-foreign-language-writing-helper"; 7 | import { TxtNodeType } from "@textlint/ast-node-types"; 8 | 9 | const matchAll = require("string.prototype.matchall"); 10 | // ・を含む場合はそれぞれ単語として見る 11 | const KATAKANA = /[ァ-ヴ][ァ-ヴー]*/g; 12 | export type Options = { 13 | /** 14 | * 許可する単語を指定できます 15 | */ 16 | allows?: string[]; 17 | /** 18 | * 慣用的に例外として扱われる単語も不許可にするかどうか 19 | * ビルトインでいくつかの例外が定義されています 20 | * デフォルト: false 21 | */ 22 | disableBuiltinAllows?: boolean; 23 | /** 24 | * 無視したいTxtNodeのTypesを指定します 25 | * See https://textlint.github.io/docs/txtnode.html#type 26 | * Default: ["Link", "BlockQuote", "Emphasis", "Strong", "Code", "Comment", "Html"] 27 | */ 28 | ignoreNodeTypes?: TxtNodeType[]; 29 | }; 30 | /** 31 | * 慣用的に長音が省略される単語 32 | */ 33 | const BUILTIN_ALLOW_WORDS = ["ミニチュア"]; 34 | 35 | export const DEFAULT_OPTIONS = { 36 | allows: [], 37 | disableBuiltinAllows: false, 38 | ignoreNodeTypes: ["Link", "BlockQuote", "Emphasis", "Strong", "Code", "Comment", "Html"] 39 | }; 40 | export const report: TextlintRuleReporter> = (context, options = {}) => { 41 | const { Syntax, getSource, RuleError, fixer } = context; 42 | const indexPromise: Promise = createKatakanaEnglishIndex(); 43 | const allows = options.allows || DEFAULT_OPTIONS.allows; 44 | const ignoreNodeTypes = options.ignoreNodeTypes || DEFAULT_OPTIONS.ignoreNodeTypes; 45 | const disableBuiltinAllows = 46 | options.disableBuiltinAllows !== undefined 47 | ? options.disableBuiltinAllows 48 | : DEFAULT_OPTIONS.disableBuiltinAllows; 49 | return wrapReportHandler( 50 | context, 51 | { 52 | ignoreNodeTypes: ignoreNodeTypes 53 | }, 54 | report => { 55 | return { 56 | async [Syntax.Str](node) { 57 | const { midashiMap } = await indexPromise; 58 | const text = getSource(node); 59 | const katakanaItems = matchAll(text, KATAKANA); 60 | for (const katakanaItem of katakanaItems) { 61 | // カタカナの原語を取得する 62 | const matchKatakana: string | undefined = katakanaItem[0]; 63 | if (!matchKatakana) { 64 | continue; 65 | } 66 | // 辞書には ー が含まれてない場合があるので両方試す 67 | const suffixPyhonWord = matchKatakana.endsWith("ー") ? "" : matchKatakana + "ー"; 68 | const nonSuffixPyhonWord = matchKatakana.endsWith("ー") 69 | ? matchKatakana.slice(0, matchKatakana.length - 1) 70 | : ""; 71 | const englishItems = (midashiMap.get(matchKatakana) || []) 72 | .concat(midashiMap.get(suffixPyhonWord) || []) 73 | .concat(midashiMap.get(nonSuffixPyhonWord) || []); 74 | if (!englishItems) { 75 | continue; 76 | } 77 | // # 判定 78 | const isReEnglish = englishItems.some(item => { 79 | return item.endsWith("re"); 80 | }); 81 | if (!isReEnglish) { 82 | continue; 83 | } 84 | // 末尾が -ture, -sure の場合は長音記号「ー」を付ける 85 | const shouldHyphon = englishItems.some(item => { 86 | return item.endsWith("ture") || item.endsWith("sure"); 87 | }); 88 | if (shouldHyphon) { 89 | // # ただし、末尾が -ture, -sure の場合は長音記号「ー」を付ける 90 | // 元のカタカナがー(長音)で終わっていないならOK 91 | if (matchKatakana.endsWith("ー")) { 92 | continue; 93 | } 94 | // 例外は除外する 95 | if (allows.includes(matchKatakana)) { 96 | continue; 97 | } 98 | // ビルトイン例外を除外する if disableBuiltinAllows:false 99 | if (!disableBuiltinAllows) { 100 | if (BUILTIN_ALLOW_WORDS.includes(matchKatakana)) { 101 | continue; 102 | } 103 | } 104 | const index = katakanaItem.index; 105 | if (index === undefined) { 106 | continue; 107 | } 108 | const endIndex = index + matchKatakana.length - 1; 109 | report( 110 | node, 111 | new RuleError( 112 | "原語の語尾が-ture,-sureの場合は、原則として長音記号「ー」を付けるのが原則です", 113 | { 114 | index: index, 115 | fix: fixer.insertTextAfterRange([endIndex, endIndex + 1], "ー") 116 | } 117 | ) 118 | ); 119 | } else { 120 | // # 英単語がの末尾が -re の場合は長音記号を付けない 121 | // 元のカタカナがー(長音)で終わって終わってるならOK 122 | if (!matchKatakana.endsWith("ー")) { 123 | continue; 124 | } 125 | // 例外は除外する 126 | if (allows.includes(matchKatakana)) { 127 | continue; 128 | } 129 | // ビルトイン例外を除外する if disableBuiltinAllows:false 130 | if (!disableBuiltinAllows) { 131 | if (BUILTIN_ALLOW_WORDS.includes(matchKatakana)) { 132 | continue; 133 | } 134 | } 135 | const index = katakanaItem.index; 136 | if (index === undefined) { 137 | continue; 138 | } 139 | const endIndex = index + matchKatakana.length - 1; 140 | report( 141 | node, 142 | new RuleError( 143 | "原語の語尾が-reの場合は、原則として長音記号「ー」を付けないのが原則です", 144 | { 145 | index: index, 146 | fix: fixer.removeRange([endIndex, endIndex + 1]) 147 | } 148 | ) 149 | ); 150 | } 151 | } 152 | } 153 | }; 154 | } 155 | ); 156 | }; 157 | export default { 158 | linter: report, 159 | fixer: report 160 | }; 161 | -------------------------------------------------------------------------------- /packages/textlint-rule-kana-english-suffix-re/test/textlint-rule-kana-english-suffix-re.test.ts: -------------------------------------------------------------------------------- 1 | import TextLintTester from "textlint-tester"; 2 | 3 | const tester = new TextLintTester(); 4 | // rule 5 | import rule from "../src/textlint-rule-kana-english-suffix-re"; 6 | // ruleName, rule, { valid, invalid } 7 | tester.run("textlint-rule-kana-english-suffix-re", rule, { 8 | valid: [ 9 | // -reは「ー」を付けない 10 | "ラビア(gravure)", 11 | "ケア(care)", 12 | "コア(core)", 13 | "フィギュア(figure)", 14 | "ファームウェア(firmware)", 15 | "フリーウェア(freeware)", 16 | "グループウェア(groupware)", 17 | "ハードウェア(hardware)", 18 | "ミドルウェア(middleware)", 19 | "ピュア(pure)", 20 | "リタイア(retire)", 21 | "スコア(score)", 22 | "サファイア(sapphire)", 23 | "シビア(severe)", 24 | "シェア(share)", 25 | "ソフトウェア(software)", 26 | "スペア(spare)", 27 | "スクエア(square)", 28 | "ストア(store)", 29 | "ワイヤ(wire)", 30 | // ただし、-ture, -sureは「ー」を付ける 31 | "アドベンチャー(adventure)", 32 | "アーキテクチャー(architecture)", 33 | "カルチャー(culture)", 34 | "ディスクロージャー(disclosure)", 35 | "フィーチャー(feature)", 36 | "ファニチャー(furniture)", 37 | "ジェスチャー(gesture)", 38 | "インフラストラクチャー(infrastructure)", 39 | "レクチャー(lecture)", 40 | "レジャー(leisure)", 41 | "マニュファクチャー(manufacture)", 42 | "ネイチャー(nature)", 43 | "ピクチャー(picture)", 44 | "プレッシャー(pressure)", 45 | "シグネチャー(signature)", 46 | "ストラクチャー(structure)", 47 | "テクスチャー(texture)", 48 | // 一般的に長音記号を使わない単語は例外とする 49 | "ミニチュアは例外", 50 | // オプション 51 | { 52 | text: "テクスチャ", 53 | options: { 54 | allows: ["テクスチャ"] 55 | } 56 | } 57 | ], 58 | invalid: [ 59 | // -re は「ー」を付けない 60 | { 61 | text: "フリーウェアー(freeware)", 62 | output: "フリーウェア(freeware)", 63 | errors: [ 64 | { 65 | index: 0, 66 | message: "原語の語尾が-reの場合は、原則として長音記号「ー」を付けないのが原則です" 67 | } 68 | ] 69 | }, 70 | { 71 | text: "スクエアー(square)", 72 | output: "スクエア(square)", 73 | errors: [ 74 | { 75 | index: 0, 76 | message: "原語の語尾が-reの場合は、原則として長音記号「ー」を付けないのが原則です" 77 | } 78 | ] 79 | }, 80 | { 81 | text: "ストアー(store)", 82 | output: "ストア(store)", 83 | errors: [ 84 | { 85 | index: 0, 86 | message: "原語の語尾が-reの場合は、原則として長音記号「ー」を付けないのが原則です" 87 | } 88 | ] 89 | }, 90 | // -ture,-sureは「ー」をつける 91 | { 92 | text: "カルチャ(culture)", 93 | output: "カルチャー(culture)", 94 | errors: [ 95 | { 96 | index: 0, 97 | message: "原語の語尾が-ture,-sureの場合は、原則として長音記号「ー」を付けるのが原則です" 98 | } 99 | ] 100 | }, 101 | { 102 | text: "プレッシャ(pressure)", 103 | output: "プレッシャー(pressure)", 104 | errors: [ 105 | { 106 | index: 0, 107 | message: "原語の語尾が-ture,-sureの場合は、原則として長音記号「ー」を付けるのが原則です" 108 | } 109 | ] 110 | } 111 | ] 112 | }); 113 | -------------------------------------------------------------------------------- /packages/textlint-rule-kana-english-suffix-re/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Basic Options */ 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "esModuleInterop": true, 7 | "newLine": "LF", 8 | "outDir": "./lib/", 9 | "target": "es2015", 10 | "sourceMap": true, 11 | "declaration": true, 12 | "jsx": "preserve", 13 | "lib": [ 14 | "esnext", 15 | "dom" 16 | ], 17 | /* Strict Type-Checking Options */ 18 | "strict": true, 19 | /* Additional Checks */ 20 | /* Report errors on unused locals. */ 21 | "noUnusedLocals": true, 22 | /* Report errors on unused parameters. */ 23 | "noUnusedParameters": true, 24 | /* Report error when not all code paths in function return a value. */ 25 | "noImplicitReturns": true, 26 | /* Report errors for fallthrough cases in switch statement. */ 27 | "noFallthroughCasesInSwitch": true 28 | }, 29 | "include": [ 30 | "src/**/*" 31 | ], 32 | "exclude": [ 33 | ".git", 34 | "node_modules" 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /packages/textlint-rule-kana-english-suffix-ware/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019 azu 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /packages/textlint-rule-kana-english-suffix-ware/README.md: -------------------------------------------------------------------------------- 1 | # @textlint-ja/textlint-rule-kana-english-suffix-ware 2 | 3 | 原語の語尾が-ware, -wearの場合は、原則として「ウェア」とするtextlintルール。 4 | 5 | **OK**: 6 | 7 | ``` 8 | ソフトウェア(software) 9 | スパイウェア(spyware) 10 | マルウェア(malware) 11 | スポーツウェア(sports wear) 12 | ゴルフウェア(gold wear) 13 | マウンテンウェア(mountain wear) 14 | カジュアルウェア(casual wear) 15 | ``` 16 | 17 | **NG**: 18 | 19 | ``` 20 | ソフトウエアは-wareなので小文字 21 | ゴルフウエアは-wareなので小文字 22 | ``` 23 | 24 | 25 | ## Install 26 | 27 | Install with [npm](https://www.npmjs.com/): 28 | 29 | npm install @textlint-ja/textlint-rule-kana-english-suffix-ware 30 | 31 | ## Usage 32 | 33 | Via `.textlintrc`(Recommended) 34 | 35 | ```json 36 | { 37 | "rules": { 38 | "@textlint-ja/kana-english-suffix-ware": true 39 | } 40 | } 41 | ``` 42 | 43 | Via CLI 44 | 45 | ``` 46 | textlint --rule @textlint-ja/kana-english-suffix-ware README.md 47 | ``` 48 | 49 | ## Options 50 | 51 | ```ts 52 | { 53 | /** 54 | * 許可する単語を指定できます 55 | */ 56 | allows?: string[]; 57 | /** 58 | * 慣用的に例外とされる単語も不許可にするかどうか 59 | * デフォルト: false 60 | */ 61 | disableBuiltinAllows: boolean; 62 | } 63 | ``` 64 | 65 | Example: 66 | 67 | ```json 68 | { 69 | "rules": { 70 | "@textlint-ja/kana-english-suffix-ware": { 71 | "allows": ["マルウエア"], 72 | "disableDefaultAllows": true 73 | } 74 | } 75 | } 76 | ``` 77 | 78 | ## References 79 | 80 | - [ウェア - Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%A6%E3%82%A7%E3%82%A2) 81 | - Google検索: `ウエア` -> `ウェア` 82 | 83 | ## Changelog 84 | 85 | See [Releases page](https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing/releases). 86 | 87 | ## Running tests 88 | 89 | Install devDependencies and Run `npm test`: 90 | 91 | yarn install && yarn test 92 | 93 | ## Contributing 94 | 95 | Pull requests and stars are always welcome. 96 | 97 | For bugs and feature requests, [please create an issue](https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing/issues). 98 | 99 | 1. Fork it! 100 | 2. Create your feature branch: `git checkout -b my-new-feature` 101 | 3. Commit your changes: `git commit -am 'Add some feature'` 102 | 4. Push to the branch: `git push origin my-new-feature` 103 | 5. Submit a pull request :D 104 | 105 | ## Author 106 | 107 | - [github/azu](https://github.com/azu) 108 | - [twitter/azu_re](https://twitter.com/azu_re) 109 | 110 | ## License 111 | 112 | MIT © azu 113 | -------------------------------------------------------------------------------- /packages/textlint-rule-kana-english-suffix-ware/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@textlint-ja/textlint-rule-kana-english-suffix-ware", 3 | "version": "1.0.0", 4 | "description": "原語の語尾が-ware, -wearの場合は、原則として「ウェア」とするtextlintルール。", 5 | "keywords": [ 6 | "textlintrule" 7 | ], 8 | "homepage": "https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing/tree/master/packages/textlint-rule-kana-english-suffix-ware/", 9 | "bugs": { 10 | "url": "https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing/issues" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing.git" 15 | }, 16 | "license": "MIT", 17 | "author": "azu", 18 | "files": [ 19 | "bin/", 20 | "lib/", 21 | "src/" 22 | ], 23 | "main": "lib/textlint-rule-kana-english-suffix-ware.js", 24 | "directories": { 25 | "lib": "lib", 26 | "test": "test" 27 | }, 28 | "scripts": { 29 | "build": "textlint-scripts build", 30 | "prettier": "prettier --write \"**/*.{js,jsx,ts,tsx,css}\"", 31 | "prepublish": "npm run --if-present build", 32 | "test": "textlint-scripts test", 33 | "watch": "textlint-scripts build --watch" 34 | }, 35 | "prettier": { 36 | "printWidth": 120, 37 | "singleQuote": false, 38 | "tabWidth": 4 39 | }, 40 | "devDependencies": { 41 | "@textlint/types": "^1.2.3", 42 | "@types/node": "^13.1.1", 43 | "prettier": "^1.19.1", 44 | "textlint-scripts": "^3.0.0", 45 | "textlint-tester": "^5.1.11", 46 | "ts-node": "^8.5.4", 47 | "typescript": "^3.7.4", 48 | "sudachi-synonyms-dictionary": "^4.1.0" 49 | }, 50 | "peerDependencies": { 51 | "sudachi-synonyms-dictionary": "*" 52 | }, 53 | "publishConfig": { 54 | "access": "public" 55 | }, 56 | "dependencies": { 57 | "textlint-rule-helper": "^2.1.1", 58 | "string.prototype.matchall": "^4.0.2", 59 | "@textlint-ja/textlint-rule-preset-foreign-language-writing-helper": "^1.0.0" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /packages/textlint-rule-kana-english-suffix-ware/src/textlint-rule-kana-english-suffix-ware.ts: -------------------------------------------------------------------------------- 1 | import { TextlintRuleOptions, TextlintRuleReporter } from "@textlint/types"; 2 | import { wrapReportHandler } from "textlint-rule-helper"; 3 | import { 4 | createKatakanaEnglishIndex, 5 | KatakanEnglishIndexType 6 | } from "@textlint-ja/textlint-rule-preset-foreign-language-writing-helper"; 7 | import { TxtNodeType } from "@textlint/ast-node-types"; 8 | 9 | const matchAll = require("string.prototype.matchall"); 10 | // ・を含む場合はそれぞれ単語として見る 11 | const KATAKANA = /[ァ-ヴ][ァ-ヴー]*/g; 12 | export type Options = { 13 | /** 14 | * 許可する単語を指定できます 15 | */ 16 | allows?: string[]; 17 | /** 18 | * 慣用的に例外とされる単語も不許可にするかどうか 19 | * ビルトインでいくつかの例外が定義されています 20 | * デフォルト: false 21 | */ 22 | disableBuiltinAllows?: boolean; 23 | /** 24 | * 無視したいTxtNodeのTypesを指定します 25 | * See https://textlint.github.io/docs/txtnode.html#type 26 | * Default: ["Link", "BlockQuote", "Emphasis", "Strong", "Code", "Comment", "Html"] 27 | */ 28 | ignoreNodeTypes?: TxtNodeType[]; 29 | }; 30 | /** 31 | * 慣用的に例外とされる単語 32 | */ 33 | const BUILTIN_ALLOW_WORDS: string[] = []; 34 | 35 | export const DEFAULT_OPTIONS = { 36 | allows: [], 37 | disableBuiltinAllows: false, 38 | ignoreNodeTypes: ["Link", "BlockQuote", "Emphasis", "Strong", "Code", "Comment", "Html"] 39 | }; 40 | export const report: TextlintRuleReporter> = (context, options = {}) => { 41 | const { Syntax, getSource, RuleError, fixer } = context; 42 | const indexPromise: Promise = createKatakanaEnglishIndex(); 43 | const allows = options.allows || DEFAULT_OPTIONS.allows; 44 | const ignoreNodeTypes = options.ignoreNodeTypes || DEFAULT_OPTIONS.ignoreNodeTypes; 45 | const disableBuiltinAllows = 46 | options.disableBuiltinAllows !== undefined 47 | ? options.disableBuiltinAllows 48 | : DEFAULT_OPTIONS.disableBuiltinAllows; 49 | return wrapReportHandler( 50 | context, 51 | { 52 | ignoreNodeTypes: ignoreNodeTypes 53 | }, 54 | report => { 55 | return { 56 | async [Syntax.Str](node) { 57 | const { midashiMap } = await indexPromise; 58 | const text = getSource(node); 59 | const katakanaItems = matchAll(text, KATAKANA); 60 | for (const katakanaItem of katakanaItems) { 61 | // カタカナの原語を取得する 62 | const matchKatakana = katakanaItem[0]; 63 | if (!matchKatakana) { 64 | continue; 65 | } 66 | const englishItems = midashiMap.get(matchKatakana); 67 | if (!englishItems) { 68 | continue; 69 | } 70 | // # 判定 71 | // 英単語が -warek -ware 72 | const isMatchSuffix = englishItems.some(item => { 73 | return item.endsWith("ware") || item.endsWith("wear"); 74 | }); 75 | if (!isMatchSuffix) { 76 | continue; 77 | } 78 | // 元のカタカナが「ウェア」になっている 79 | if (matchKatakana.endsWith("ウェア")) { 80 | continue; 81 | } 82 | // 例外は除外する 83 | if (allows.includes(matchKatakana)) { 84 | continue; 85 | } 86 | // ビルトイン例外を除外する if disableBuiltinAllows:false 87 | if (!disableBuiltinAllows) { 88 | if (BUILTIN_ALLOW_WORDS.includes(matchKatakana)) { 89 | continue; 90 | } 91 | } 92 | const index = katakanaItem.index; 93 | if (index === undefined) { 94 | continue; 95 | } 96 | const startIndex = matchKatakana.indexOf("ウエア"); 97 | const endIndex = index + matchKatakana.length; 98 | report( 99 | node, 100 | new RuleError("原語の語尾が-ware,-wearの場合はカタカナでは「ウェア」とするのが原則です", { 101 | index: index, 102 | fix: fixer.replaceTextRange([startIndex, endIndex], "ウェア") 103 | }) 104 | ); 105 | } 106 | } 107 | }; 108 | } 109 | ); 110 | }; 111 | export default { 112 | linter: report, 113 | fixer: report 114 | }; 115 | -------------------------------------------------------------------------------- /packages/textlint-rule-kana-english-suffix-ware/test/textlint-rule-kana-english-suffix-ware.test.ts: -------------------------------------------------------------------------------- 1 | import TextLintTester from "textlint-tester"; 2 | 3 | const tester = new TextLintTester(); 4 | // rule 5 | import rule from "../src/textlint-rule-kana-english-suffix-ware"; 6 | // ruleName, rule, { valid, invalid } 7 | tester.run("textlint-rule-kana-english-suffix-ware", rule, { 8 | valid: [ 9 | // -ware 10 | "ソフトウェア(software)", 11 | "スパイウェア(spyware)", 12 | "マルウェア(malware)", 13 | // -wear 14 | "スポーツウェア(sports wear)", 15 | "ゴルフウェア(gold wear)", 16 | "マウンテンウェア(mountain wear)", 17 | "カジュアルウェア(casual wear)", 18 | // オプション 19 | { 20 | text: "マルウエア", 21 | options: { 22 | allows: ["マルウエア"] 23 | } 24 | } 25 | ], 26 | invalid: [ 27 | { 28 | text: "ソフトウエアは-wareなので小文字", 29 | output: "ソフトウェアは-wareなので小文字", 30 | errors: [ 31 | { 32 | index: 0, 33 | message: "原語の語尾が-ware,-wearの場合はカタカナでは「ウェア」とするのが原則です" 34 | } 35 | ] 36 | }, 37 | { 38 | text: "スポーツウエアは-wareなので小文字", 39 | output: "スポーツウェアは-wareなので小文字", 40 | errors: [ 41 | { 42 | index: 0, 43 | message: "原語の語尾が-ware,-wearの場合はカタカナでは「ウェア」とするのが原則です" 44 | } 45 | ] 46 | } 47 | ] 48 | }); 49 | -------------------------------------------------------------------------------- /packages/textlint-rule-kana-english-suffix-ware/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Basic Options */ 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "esModuleInterop": true, 7 | "newLine": "LF", 8 | "outDir": "./lib/", 9 | "target": "es2015", 10 | "sourceMap": true, 11 | "declaration": true, 12 | "jsx": "preserve", 13 | "lib": [ 14 | "esnext", 15 | "dom" 16 | ], 17 | /* Strict Type-Checking Options */ 18 | "strict": true, 19 | /* Additional Checks */ 20 | /* Report errors on unused locals. */ 21 | "noUnusedLocals": true, 22 | /* Report errors on unused parameters. */ 23 | "noUnusedParameters": true, 24 | /* Report error when not all code paths in function return a value. */ 25 | "noImplicitReturns": true, 26 | /* Report errors for fallthrough cases in switch statement. */ 27 | "noFallthroughCasesInSwitch": true 28 | }, 29 | "include": [ 30 | "src/**/*" 31 | ], 32 | "exclude": [ 33 | ".git", 34 | "node_modules" 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /packages/textlint-rule-kana-english-suffix-y/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019 azu 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /packages/textlint-rule-kana-english-suffix-y/README.md: -------------------------------------------------------------------------------- 1 | # @textlint-ja/textlint-rule-kana-english-suffix-y 2 | 3 | 原語の語尾が-yの場合は、カタカナを長音記号「ー」で表わすのを原則とするtextlintルール。 4 | 5 | **OK**: 6 | 7 | ``` 8 | アクセサリーはOK 9 | エネルギーはOK 10 | アイデンティティーはOK 11 | メロディーはOK 12 | パーティーはOK 13 | メモリーはOK 14 | サンクチュアリは例外 15 | アムネスティは例外 16 | ``` 17 | 18 | **NG**: 19 | 20 | ``` 21 | メモリは-yなので長音 22 | パーティは-yなので長音 23 | ``` 24 | 25 | ## Install 26 | 27 | Install with [npm](https://www.npmjs.com/): 28 | 29 | npm install @textlint-ja/textlint-rule-kana-english-suffix-y 30 | 31 | ## Usage 32 | 33 | Via `.textlintrc`(Recommended) 34 | 35 | ```json 36 | { 37 | "rules": { 38 | "@textlint-ja/kana-english-suffix-y": true 39 | } 40 | } 41 | ``` 42 | 43 | Via CLI 44 | 45 | ``` 46 | textlint --rule @textlint-ja/kana-english-suffix-y README.md 47 | ``` 48 | 49 | ## Options 50 | 51 | ```ts 52 | { 53 | /** 54 | * 許可する単語を指定できます 55 | */ 56 | allows?: string[]; 57 | /** 58 | * 慣用的に長音が省略される単語も不許可にするかどうか 59 | * デフォルト: false 60 | */ 61 | disableBuiltinAllows: boolean; 62 | } 63 | ``` 64 | 65 | Example: 66 | 67 | ```json 68 | { 69 | "rules": { 70 | "@textlint-ja/kana-english-suffix-y": { 71 | "allows": ["メモリ"], 72 | "disableDefaultAllows": true 73 | } 74 | } 75 | } 76 | ``` 77 | 78 | ## References 79 | 80 | - [外来語(カタカナ)表記ガイドライン](https://www.jtca.org/standardization/katakana_guide_3_20171222.pdf) 81 | 82 | ## Changelog 83 | 84 | See [Releases page](https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing/releases). 85 | 86 | ## Running tests 87 | 88 | Install devDependencies and Run `npm test`: 89 | 90 | npm i -d && npm test 91 | 92 | ## Contributing 93 | 94 | Pull requests and stars are always welcome. 95 | 96 | For bugs and feature requests, [please create an issue](https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing/issues). 97 | 98 | 1. Fork it! 99 | 2. Create your feature branch: `git checkout -b my-new-feature` 100 | 3. Commit your changes: `git commit -am 'Add some feature'` 101 | 4. Push to the branch: `git push origin my-new-feature` 102 | 5. Submit a pull request :D 103 | 104 | ## Author 105 | 106 | - [github/azu](https://github.com/azu) 107 | - [twitter/azu_re](https://twitter.com/azu_re) 108 | 109 | ## License 110 | 111 | MIT © azu 112 | -------------------------------------------------------------------------------- /packages/textlint-rule-kana-english-suffix-y/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@textlint-ja/textlint-rule-kana-english-suffix-y", 3 | "version": "1.0.0", 4 | "description": "原語の語尾が-yの場合は、カタカナを長音記号「ー」で表わすのを原則とするtextlintルール", 5 | "keywords": [ 6 | "textlintrule" 7 | ], 8 | "homepage": "https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing/tree/master/packages/textlint-rule-kana-english-suffix-y/", 9 | "bugs": { 10 | "url": "https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing/issues" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing.git" 15 | }, 16 | "license": "MIT", 17 | "author": "azu", 18 | "files": [ 19 | "bin/", 20 | "lib/", 21 | "src/" 22 | ], 23 | "main": "lib/textlint-rule-kana-english-suffix-y.js", 24 | "directories": { 25 | "lib": "lib", 26 | "test": "test" 27 | }, 28 | "scripts": { 29 | "build": "textlint-scripts build", 30 | "prettier": "prettier --write \"**/*.{js,jsx,ts,tsx,css}\"", 31 | "prepublish": "npm run --if-present build", 32 | "test": "textlint-scripts test", 33 | "watch": "textlint-scripts build --watch" 34 | }, 35 | "prettier": { 36 | "printWidth": 120, 37 | "singleQuote": false, 38 | "tabWidth": 4 39 | }, 40 | "devDependencies": { 41 | "@textlint/types": "^1.2.3", 42 | "@types/node": "^13.1.1", 43 | "prettier": "^1.19.1", 44 | "textlint-scripts": "^3.0.0", 45 | "textlint-tester": "^5.1.11", 46 | "ts-node": "^8.5.4", 47 | "typescript": "^3.7.4", 48 | "sudachi-synonyms-dictionary": "^4.1.0" 49 | }, 50 | "peerDependencies": { 51 | "sudachi-synonyms-dictionary": "*" 52 | }, 53 | "publishConfig": { 54 | "access": "public" 55 | }, 56 | "dependencies": { 57 | "textlint-rule-helper": "^2.1.1", 58 | "string.prototype.matchall": "^4.0.2", 59 | "@textlint-ja/textlint-rule-preset-foreign-language-writing-helper": "^1.0.0" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /packages/textlint-rule-kana-english-suffix-y/src/textlint-rule-kana-english-suffix-y.ts: -------------------------------------------------------------------------------- 1 | import { TextlintRuleOptions, TextlintRuleReporter } from "@textlint/types"; 2 | import { wrapReportHandler } from "textlint-rule-helper"; 3 | import { 4 | createKatakanaEnglishIndex, 5 | KatakanEnglishIndexType 6 | } from "@textlint-ja/textlint-rule-preset-foreign-language-writing-helper"; 7 | import { TxtNodeType } from "@textlint/ast-node-types"; 8 | 9 | const matchAll = require("string.prototype.matchall"); 10 | // ・を含む場合はそれぞれ単語として見る 11 | const KATAKANA = /[ァ-ヴ][ァ-ヴー]*/g; 12 | export type Options = { 13 | /** 14 | * 許可する単語を指定できます 15 | */ 16 | allows?: string[]; 17 | /** 18 | * 慣用的に長音が省略される単語も不許可にするかどうか 19 | * ビルトインでいくつかの例外が定義されています 20 | * デフォルト: false 21 | */ 22 | disableBuiltinAllows?: boolean; 23 | /** 24 | * 無視したいTxtNodeのTypesを指定します 25 | * See https://textlint.github.io/docs/txtnode.html#type 26 | * Default: ["Link", "BlockQuote", "Emphasis", "Strong", "Code", "Comment", "Html"] 27 | */ 28 | ignoreNodeTypes?: TxtNodeType[]; 29 | }; 30 | /** 31 | * 慣用的に長音が省略される単語 32 | */ 33 | const BUILTIN_ALLOW_WORDS = ["サンクチュアリ", "アムネスティ"]; 34 | 35 | export const DEFAULT_OPTIONS = { 36 | allows: [], 37 | disableBuiltinAllows: false, 38 | ignoreNodeTypes: ["Link", "BlockQuote", "Emphasis", "Strong", "Code", "Comment", "Html"] 39 | }; 40 | export const report: TextlintRuleReporter> = (context, options = {}) => { 41 | const { Syntax, getSource, RuleError, fixer } = context; 42 | const indexPromise: Promise = createKatakanaEnglishIndex(); 43 | const allows = options.allows || DEFAULT_OPTIONS.allows; 44 | const ignoreNodeTypes = options.ignoreNodeTypes || DEFAULT_OPTIONS.ignoreNodeTypes; 45 | const disableBuiltinAllows = 46 | options.disableBuiltinAllows !== undefined 47 | ? options.disableBuiltinAllows 48 | : DEFAULT_OPTIONS.disableBuiltinAllows; 49 | return wrapReportHandler( 50 | context, 51 | { 52 | ignoreNodeTypes: ignoreNodeTypes 53 | }, 54 | report => { 55 | return { 56 | async [Syntax.Str](node) { 57 | const { midashiMap } = await indexPromise; 58 | const text = getSource(node); 59 | const katakanaItems = matchAll(text, KATAKANA); 60 | for (const katakanaItem of katakanaItems) { 61 | // カタカナの原語を取得する 62 | const matchKatakana = katakanaItem[0]; 63 | if (!matchKatakana) { 64 | continue; 65 | } 66 | const englishItems = midashiMap.get(matchKatakana); 67 | if (!englishItems) { 68 | continue; 69 | } 70 | // # 判定 71 | // 英単語が -y 72 | const isSuffixYEnglish = englishItems.some(item => { 73 | return item.endsWith("y"); 74 | }); 75 | if (!isSuffixYEnglish) { 76 | continue; 77 | } 78 | // 元のカタカナがー(長音)で終わっていない 79 | if (matchKatakana.endsWith("ー")) { 80 | continue; 81 | } 82 | // 例外は除外する 83 | if (allows.includes(matchKatakana)) { 84 | continue; 85 | } 86 | // ビルトイン例外を除外する if disableBuiltinAllows:false 87 | if (!disableBuiltinAllows) { 88 | if (BUILTIN_ALLOW_WORDS.includes(matchKatakana)) { 89 | continue; 90 | } 91 | } 92 | const index = katakanaItem.index; 93 | if (index === undefined) { 94 | continue; 95 | } 96 | const endIndex = index + matchKatakana.length - 1; 97 | report( 98 | node, 99 | new RuleError("原語の語尾が-yの場合はカタカナでは長音記号「ー」で表わすのが原則です", { 100 | index: index, 101 | fix: fixer.insertTextAfterRange([endIndex, endIndex + 1], "ー") 102 | }) 103 | ); 104 | } 105 | } 106 | }; 107 | } 108 | ); 109 | }; 110 | export default { 111 | linter: report, 112 | fixer: report 113 | }; 114 | -------------------------------------------------------------------------------- /packages/textlint-rule-kana-english-suffix-y/test/textlint-rule-kana-english-suffix-y.test.ts: -------------------------------------------------------------------------------- 1 | import TextLintTester from "textlint-tester"; 2 | 3 | const tester = new TextLintTester(); 4 | // rule 5 | import rule from "../src/textlint-rule-kana-english-suffix-y"; 6 | // ruleName, rule, { valid, invalid } 7 | tester.run("textlint-rule-kana-english-suffix-y", rule, { 8 | valid: [ 9 | // -y 10 | "アクセサリーはOK", 11 | "エネルギーはOK", 12 | "アイデンティティーはOK", 13 | "メロディーはOK", 14 | "パーティーはOK", 15 | "メモリーはOK", 16 | // 一般的に長音記号を使わない単語は例外とする 17 | "サンクチュアリは例外", 18 | "アムネスティは例外", 19 | // オプション 20 | { 21 | text: "メモリ", 22 | options: { 23 | allows: ["メモリ"] 24 | } 25 | } 26 | ], 27 | invalid: [ 28 | { 29 | text: "メモリは-yなので長音", 30 | output: "メモリーは-yなので長音", 31 | errors: [ 32 | { 33 | index: 0, 34 | message: "原語の語尾が-yの場合はカタカナでは長音記号「ー」で表わすのが原則です" 35 | } 36 | ] 37 | }, 38 | { 39 | text: "パーティは-yなので長音", 40 | output: "パーティーは-yなので長音", 41 | errors: [ 42 | { 43 | index: 0, 44 | message: "原語の語尾が-yの場合はカタカナでは長音記号「ー」で表わすのが原則です" 45 | } 46 | ] 47 | } 48 | 49 | ] 50 | }); 51 | -------------------------------------------------------------------------------- /packages/textlint-rule-kana-english-suffix-y/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Basic Options */ 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "esModuleInterop": true, 7 | "newLine": "LF", 8 | "outDir": "./lib/", 9 | "target": "es2015", 10 | "sourceMap": true, 11 | "declaration": true, 12 | "jsx": "preserve", 13 | "lib": [ 14 | "esnext", 15 | "dom" 16 | ], 17 | /* Strict Type-Checking Options */ 18 | "strict": true, 19 | /* Additional Checks */ 20 | /* Report errors on unused locals. */ 21 | "noUnusedLocals": true, 22 | /* Report errors on unused parameters. */ 23 | "noUnusedParameters": true, 24 | /* Report error when not all code paths in function return a value. */ 25 | "noImplicitReturns": true, 26 | /* Report errors for fallthrough cases in switch statement. */ 27 | "noFallthroughCasesInSwitch": true 28 | }, 29 | "include": [ 30 | "src/**/*" 31 | ], 32 | "exclude": [ 33 | ".git", 34 | "node_modules" 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /packages/textlint-rule-no-kana-english-v/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019 azu 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /packages/textlint-rule-no-kana-english-v/README.md: -------------------------------------------------------------------------------- 1 | # @textlint-ja/textlint-rule-no-kana-english-v 2 | 3 | 原語が「v」の場合はカタカナに「ヴ」を使わないのが原則とするtextlintルールです。 4 | 5 | 「ヴ[子音]」の代わりに「バ」「ビ」「ブ」「ベ」「ボ」のどれかを利用してください。 6 | 7 | **OK**: 8 | 9 | ``` 10 | アベレージ(average) 11 | イベント(event) 12 | バニラ(vanilla) 13 | ボランティア(volunteer) 14 | ``` 15 | 16 | **NG**: 17 | 18 | ``` 19 | イヴェントは-v-なので「ベ」を使う 20 | ``` 21 | 22 | ## Install 23 | 24 | Install with [npm](https://www.npmjs.com/): 25 | 26 | npm install @textlint-ja/textlint-rule-no-kana-english-v 27 | 28 | ## Usage 29 | 30 | Via `.textlintrc`(Recommended) 31 | 32 | ```json 33 | { 34 | "rules": { 35 | "@textlint-ja/no-kana-english-v": true 36 | } 37 | } 38 | ``` 39 | 40 | Via CLI 41 | 42 | ``` 43 | textlint --rule @textlint-ja/no-kana-english-v README.md 44 | ``` 45 | 46 | ## Options 47 | 48 | ```ts 49 | { 50 | /** 51 | * 許可する単語を指定できます 52 | */ 53 | allows?: string[]; 54 | /** 55 | * 慣用的に例外とされる単語も不許可にするかどうか 56 | * デフォルト: false 57 | */ 58 | disableBuiltinAllows: boolean; 59 | } 60 | ``` 61 | 62 | Example: 63 | 64 | ```json 65 | { 66 | "rules": { 67 | "@textlint-ja/no-kana-english-v": { 68 | "allows": ["ヴィデオ"], 69 | "disableDefaultAllows": true 70 | } 71 | } 72 | } 73 | ``` 74 | 75 | ## References 76 | 77 | - [国名表記「ヴ」消える 変更法案、衆院で可決  :日本経済新聞](https://www.nikkei.com/article/DGXMZO42662930Z10C19A3PP8000/) 78 | 79 | ## Changelog 80 | 81 | See [Releases page](https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing/releases). 82 | 83 | ## Running tests 84 | 85 | Install devDependencies and Run `npm test`: 86 | 87 | yarn install && yarn test 88 | 89 | ## Contributing 90 | 91 | Pull requests and stars are always welcome. 92 | 93 | For bugs and feature requests, [please create an issue](https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing/issues). 94 | 95 | 1. Fork it! 96 | 2. Create your feature branch: `git checkout -b my-new-feature` 97 | 3. Commit your changes: `git commit -am 'Add some feature'` 98 | 4. Push to the branch: `git push origin my-new-feature` 99 | 5. Submit a pull request :D 100 | 101 | ## Author 102 | 103 | - [github/azu](https://github.com/azu) 104 | - [twitter/azu_re](https://twitter.com/azu_re) 105 | 106 | ## License 107 | 108 | MIT © azu 109 | -------------------------------------------------------------------------------- /packages/textlint-rule-no-kana-english-v/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@textlint-ja/textlint-rule-no-kana-english-v", 3 | "version": "1.0.0", 4 | "description": "原語が「v」の場合はカタカナに「ヴ」を使わないのが原則とするtextlintルール", 5 | "keywords": [ 6 | "textlintrule" 7 | ], 8 | "homepage": "https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing/tree/master/packages/textlint-rule-no-kana-english-v/", 9 | "bugs": { 10 | "url": "https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing/issues" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing.git" 15 | }, 16 | "license": "MIT", 17 | "author": "azu", 18 | "files": [ 19 | "bin/", 20 | "lib/", 21 | "src/" 22 | ], 23 | "main": "lib/textlint-rule-no-kana-english-v.js", 24 | "directories": { 25 | "lib": "lib", 26 | "test": "test" 27 | }, 28 | "scripts": { 29 | "build": "textlint-scripts build", 30 | "prettier": "prettier --write \"**/*.{js,jsx,ts,tsx,css}\"", 31 | "prepublish": "npm run --if-present build", 32 | "test": "textlint-scripts test", 33 | "watch": "textlint-scripts build --watch" 34 | }, 35 | "prettier": { 36 | "printWidth": 120, 37 | "singleQuote": false, 38 | "tabWidth": 4 39 | }, 40 | "devDependencies": { 41 | "@textlint/types": "^1.2.3", 42 | "@types/node": "^13.1.1", 43 | "prettier": "^1.19.1", 44 | "textlint-scripts": "^3.0.0", 45 | "textlint-tester": "^5.1.11", 46 | "ts-node": "^8.5.4", 47 | "typescript": "^3.7.4", 48 | "sudachi-synonyms-dictionary": "^4.1.0" 49 | }, 50 | "peerDependencies": { 51 | "sudachi-synonyms-dictionary": "*" 52 | }, 53 | "publishConfig": { 54 | "access": "public" 55 | }, 56 | "dependencies": { 57 | "textlint-rule-helper": "^2.1.1", 58 | "string.prototype.matchall": "^4.0.2", 59 | "@textlint-ja/textlint-rule-preset-foreign-language-writing-helper": "^1.0.0" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /packages/textlint-rule-no-kana-english-v/src/textlint-rule-no-kana-english-v.ts: -------------------------------------------------------------------------------- 1 | import { TextlintRuleOptions, TextlintRuleReporter } from "@textlint/types"; 2 | import { wrapReportHandler } from "textlint-rule-helper"; 3 | import { 4 | createKatakanaEnglishIndex, 5 | KatakanEnglishIndexType 6 | } from "@textlint-ja/textlint-rule-preset-foreign-language-writing-helper"; 7 | import { TxtNodeType } from "@textlint/ast-node-types"; 8 | 9 | const matchAll = require("string.prototype.matchall"); 10 | // ・を含む場合はそれぞれ単語として見る 11 | const KATAKANA = /[ァ-ヴ][ァ-ヴー]*/g; 12 | export type Options = { 13 | /** 14 | * 許可する単語を指定できます 15 | */ 16 | allows?: string[]; 17 | /** 18 | * 慣用的に例外とされる単語も不許可にするかどうか 19 | * ビルトインでいくつかの例外が定義されています 20 | * デフォルト: false 21 | */ 22 | disableBuiltinAllows?: boolean; 23 | /** 24 | * 無視したいTxtNodeのTypesを指定します 25 | * See https://textlint.github.io/docs/txtnode.html#type 26 | * Default: ["Link", "BlockQuote", "Emphasis", "Strong", "Code", "Comment", "Html"] 27 | */ 28 | ignoreNodeTypes?: TxtNodeType[]; 29 | }; 30 | /** 31 | * 慣用的に例外とされる単語 32 | */ 33 | const BUILTIN_ALLOW_WORDS: string[] = []; 34 | const VAltPattern = /[ヴ][ァィゥェォ]/; 35 | const convertV = (word: string) => { 36 | return word 37 | .replace(/ヴァ/g, "バ") 38 | .replace(/ヴィ/g, "ビ") 39 | .replace(/ヴゥ/g, "ブ") 40 | .replace(/ヴェ/g, "ベ") 41 | .replace(/ヴォ/g, "ボ") 42 | .replace(/ヴュ/g, "ビュ"); 43 | }; 44 | export const DEFAULT_OPTIONS = { 45 | allows: [], 46 | disableBuiltinAllows: false, 47 | ignoreNodeTypes: ["Link", "BlockQuote", "Emphasis", "Strong", "Code", "Comment", "Html"] 48 | }; 49 | export const report: TextlintRuleReporter> = (context, options = {}) => { 50 | const { Syntax, getSource, RuleError, fixer } = context; 51 | const indexPromise: Promise = createKatakanaEnglishIndex(); 52 | const allows = options.allows || DEFAULT_OPTIONS.allows; 53 | const ignoreNodeTypes = options.ignoreNodeTypes || DEFAULT_OPTIONS.ignoreNodeTypes; 54 | const disableBuiltinAllows = 55 | options.disableBuiltinAllows !== undefined 56 | ? options.disableBuiltinAllows 57 | : DEFAULT_OPTIONS.disableBuiltinAllows; 58 | return wrapReportHandler( 59 | context, 60 | { 61 | ignoreNodeTypes: ignoreNodeTypes 62 | }, 63 | report => { 64 | return { 65 | async [Syntax.Str](node) { 66 | const { midashiMap } = await indexPromise; 67 | const text = getSource(node); 68 | const katakanaItems = matchAll(text, KATAKANA); 69 | for (const katakanaItem of katakanaItems) { 70 | // カタカナの原語を取得する 71 | const matchKatakana = katakanaItem[0]; 72 | if (!matchKatakana) { 73 | continue; 74 | } 75 | const normalizedItem = VAltPattern.test(matchKatakana) ? convertV(matchKatakana) : ""; 76 | const englishItems = (midashiMap.get(matchKatakana) || []).concat( 77 | midashiMap.get(normalizedItem) || [] 78 | ); 79 | if (!englishItems) { 80 | continue; 81 | } 82 | // # 判定 83 | // 英単語が -v- 84 | const matchEnglishWords = englishItems.some(item => { 85 | return item.includes("v"); 86 | }); 87 | if (!matchEnglishWords) { 88 | continue; 89 | } 90 | // 元のカタカナが「ヴ」を含む場合は問題 91 | if (!matchKatakana.includes("ヴ")) { 92 | continue; 93 | } 94 | // 例外は除外する 95 | if (allows.includes(matchKatakana)) { 96 | continue; 97 | } 98 | // ビルトイン例外を除外する if disableBuiltinAllows:false 99 | if (!disableBuiltinAllows) { 100 | if (BUILTIN_ALLOW_WORDS.includes(matchKatakana)) { 101 | continue; 102 | } 103 | } 104 | const index = matchKatakana.indexOf("ヴ"); 105 | report( 106 | node, 107 | new RuleError( 108 | "原語が「v」の場合はカタカナに「ヴ」を使わないのが原則です。\n\n" + 109 | "「バ」「ビ」「ブ」「ベ」「ボ」のどれかを利用してください", 110 | { 111 | index, 112 | fix: fixer.replaceTextRange( 113 | [katakanaItem.index, katakanaItem.index + matchKatakana.length], 114 | convertV(matchKatakana) 115 | ) 116 | } 117 | ) 118 | ); 119 | } 120 | } 121 | }; 122 | } 123 | ); 124 | }; 125 | export default { 126 | linter: report, 127 | fixer: report 128 | }; 129 | -------------------------------------------------------------------------------- /packages/textlint-rule-no-kana-english-v/test/textlint-rule-no-kana-english-v.test.ts: -------------------------------------------------------------------------------- 1 | import TextLintTester from "textlint-tester"; 2 | 3 | const tester = new TextLintTester(); 4 | // rule 5 | import rule from "../src/textlint-rule-no-kana-english-v"; 6 | // ruleName, rule, { valid, invalid } 7 | tester.run("textlint-rule-no-kana-english-v", rule, { 8 | valid: [ 9 | // -v- 10 | "アベレージ(average)", 11 | "イベント(event)", 12 | "オーバーコート(overcoat)", 13 | "キャラバン(caravan)", 14 | "サービス(service)", 15 | "サーベイ(survey)", 16 | "ネガティブ(negative)", 17 | "バイオリン(violin)", 18 | "バージョン(version)", 19 | "バニラ(vanilla)", 20 | "バリエーション(variation)", 21 | "バルブ(valve)", 22 | "ビデオ(video)", 23 | "ベテラン(veteran)", 24 | "ボーカル(vocal)", 25 | "ボランティア(volunteer)", 26 | "ボリューム(volume)", 27 | "ユニバーサル(universal)", 28 | "リバイバル(revival)", 29 | "レビュー(review)", 30 | "レベル(level)", 31 | // オプション 32 | { 33 | text: "ヴィンテージ", 34 | options: { 35 | allows: ["ヴィンテージ"] 36 | } 37 | } 38 | ], 39 | invalid: [ 40 | { 41 | text: "イヴェントは-v-なので「ベ」を使う", 42 | output: "イベントは-v-なので「ベ」を使う", 43 | errors: [ 44 | { 45 | index: 1, 46 | message: `原語が「v」の場合はカタカナに「ヴ」を使わないのが原則です。 47 | 48 | 「バ」「ビ」「ブ」「ベ」「ボ」のどれかを利用してください` 49 | } 50 | ] 51 | }, 52 | { 53 | text: "レヴューは-v-なので「ビュ」を使う", 54 | output: "レビューは-v-なので「ビュ」を使う", 55 | errors: [ 56 | { 57 | index: 1, 58 | message: `原語が「v」の場合はカタカナに「ヴ」を使わないのが原則です。 59 | 60 | 「バ」「ビ」「ブ」「ベ」「ボ」のどれかを利用してください` 61 | } 62 | ] 63 | } 64 | ] 65 | }); 66 | -------------------------------------------------------------------------------- /packages/textlint-rule-no-kana-english-v/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Basic Options */ 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "esModuleInterop": true, 7 | "newLine": "LF", 8 | "outDir": "./lib/", 9 | "target": "es2015", 10 | "sourceMap": true, 11 | "declaration": true, 12 | "jsx": "preserve", 13 | "lib": [ 14 | "esnext", 15 | "dom" 16 | ], 17 | /* Strict Type-Checking Options */ 18 | "strict": true, 19 | /* Additional Checks */ 20 | /* Report errors on unused locals. */ 21 | "noUnusedLocals": true, 22 | /* Report errors on unused parameters. */ 23 | "noUnusedParameters": true, 24 | /* Report error when not all code paths in function return a value. */ 25 | "noImplicitReturns": true, 26 | /* Report errors for fallthrough cases in switch statement. */ 27 | "noFallthroughCasesInSwitch": true 28 | }, 29 | "include": [ 30 | "src/**/*" 31 | ], 32 | "exclude": [ 33 | ".git", 34 | "node_modules" 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /packages/textlint-rule-preset-foreign-language-writing-helper/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019 azu 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /packages/textlint-rule-preset-foreign-language-writing-helper/README.md: -------------------------------------------------------------------------------- 1 | # @textlint-ja/textlint-rule-preset-foreign-language-writing-helper 2 | 3 | A helper for textlint-rule-preset-foreign-language-writing 4 | 5 | ## Install 6 | 7 | Install with [npm](https://www.npmjs.com/): 8 | 9 | npm install @textlint-ja/textlint-rule-preset-foreign-language-writing-helper 10 | 11 | ## Usage 12 | 13 | ```ts 14 | import { createKatakanaEnglishIndex } from "@textlint-ja/textlint-rule-preset-foreign-language-writing-helper"; 15 | import assert from "assert"; 16 | describe("create-katakana-english-index", () => { 17 | it("should should Map<カタカナ, 英単語[]>", async () => { 18 | const { midashiMap } = await createKatakanaEnglishIndex(); 19 | const englishItems = midashiMap.get("エディタ"); 20 | assert.deepStrictEqual(englishItems, ["editor"]); 21 | }); 22 | }); 23 | 24 | ``` 25 | 26 | ## Changelog 27 | 28 | See [Releases page](https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing/releases). 29 | 30 | ## Running tests 31 | 32 | Install devDependencies and Run `npm test`: 33 | 34 | npm test 35 | 36 | ## Contributing 37 | 38 | Pull requests and stars are always welcome. 39 | 40 | For bugs and feature requests, [please create an issue](https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing/issues). 41 | 42 | 1. Fork it! 43 | 2. Create your feature branch: `git checkout -b my-new-feature` 44 | 3. Commit your changes: `git commit -am 'Add some feature'` 45 | 4. Push to the branch: `git push origin my-new-feature` 46 | 5. Submit a pull request :D 47 | 48 | ## Author 49 | 50 | - [github/azu](https://github.com/azu) 51 | - [twitter/azu_re](https://twitter.com/azu_re) 52 | 53 | ## License 54 | 55 | MIT © azu 56 | -------------------------------------------------------------------------------- /packages/textlint-rule-preset-foreign-language-writing-helper/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@textlint-ja/textlint-rule-preset-foreign-language-writing-helper", 3 | "version": "1.0.0", 4 | "description": "A helper for textlint-rule-preset-foreign-language-writing ", 5 | "keywords": [ 6 | "helper", 7 | "textlint" 8 | ], 9 | "homepage": "https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing/tree/master/packages/textlint-rule-preset-foreign-language-writing-helper/", 10 | "bugs": { 11 | "url": "https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing/issues" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "https://github.com/textlint-ja/textlint-rule-preset-foreign-language-writing.git" 16 | }, 17 | "license": "MIT", 18 | "author": "azu", 19 | "files": [ 20 | "bin/", 21 | "lib/", 22 | "src/" 23 | ], 24 | "main": "lib/textlint-rule-preset-foreign-language-writing-helper.js", 25 | "types": "lib/textlint-rule-preset-foreign-language-writing-helper.d.ts", 26 | "directories": { 27 | "lib": "lib", 28 | "test": "test" 29 | }, 30 | "scripts": { 31 | "build": "cross-env NODE_ENV=production tsc -p .", 32 | "clean": "rimraf lib/", 33 | "prettier": "prettier --write \"**/*.{js,jsx,ts,tsx,css}\"", 34 | "prepublish": "npm run --if-present build", 35 | "test": "mocha \"test/**/*.ts\"", 36 | "watch": "tsc -p . --watch" 37 | }, 38 | "prettier": { 39 | "printWidth": 120, 40 | "singleQuote": false, 41 | "tabWidth": 4 42 | }, 43 | "devDependencies": { 44 | "@types/mocha": "^5.2.7", 45 | "@types/node": "^13.1.1", 46 | "cross-env": "^6.0.3", 47 | "mocha": "^6.2.2", 48 | "prettier": "^1.19.1", 49 | "rimraf": "^3.0.0", 50 | "ts-node": "^8.5.4", 51 | "ts-node-test-register": "^8.0.1", 52 | "typescript": "^3.7.4", 53 | "sudachi-synonyms-dictionary": "^4.1.0" 54 | }, 55 | "peerDependencies": { 56 | "sudachi-synonyms-dictionary": "*" 57 | }, 58 | "publishConfig": { 59 | "access": "public" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /packages/textlint-rule-preset-foreign-language-writing-helper/src/create-katakana-english-index.ts: -------------------------------------------------------------------------------- 1 | import { fetchDictionary } from "sudachi-synonyms-dictionary"; 2 | 3 | export type KATAKANA_MIDASHI = string; 4 | export type ENGLISH_MIDASHI = string; 5 | const KATAKANA_PATTERN = /^[ァ-ヴ][ァ-ヴー・]+$/; 6 | /** 7 | * インストールのチェック 8 | */ 9 | const assertInstallationSudachiSynonymsDictionary = () => { 10 | try { 11 | require("sudachi-synonyms-dictionary"); 12 | } catch (error) { 13 | throw new Error(`sudachi-synonyms-dictionaryがインストールされていません。 14 | ルールとは別にsudachi-synonyms-dictionaryをインストールしてください。 15 | 16 | $ npm install sudachi-synonyms-dictionary 17 | `); 18 | } 19 | }; 20 | export type KatakanEnglishIndexType = { 21 | midashiMap: Map; 22 | }; 23 | let _ret: KatakanEnglishIndexType | null = null; 24 | /** 25 | * Map<カタカナ, 英単語[]> のIndexを作って返す 26 | */ 27 | export const createKatakanaEnglishIndex = async (): Promise => { 28 | if (_ret) { 29 | return Promise.resolve(_ret); 30 | } 31 | assertInstallationSudachiSynonymsDictionary(); 32 | const midashiMap: Map = new Map(); 33 | const SynonymsDictionary = await fetchDictionary(); 34 | SynonymsDictionary.forEach(group => { 35 | group.items.forEach(item => { 36 | if (KATAKANA_PATTERN.test(item.midashi)) { 37 | const targetMidashi = item.midashi; 38 | // のAlphabet表記を集める 39 | const vocabularyNumber = item.vocabularyNumber; 40 | const englishItems = group.items.filter(item => { 41 | // 自分以外の同じvocabularyNumberのアルファベットを集める 42 | return ( 43 | item.midashi !== targetMidashi && 44 | item.vocabularyNumber === vocabularyNumber && 45 | (item.ryakusyou === "略語・略称/アルファベット" || item.hyoukiYure === "アルファベット表記") 46 | ); 47 | }); 48 | // Map<カタカナ, 英語[]> 49 | midashiMap.set( 50 | targetMidashi, 51 | englishItems.map(item => item.midashi) 52 | ); 53 | } 54 | }); 55 | }); 56 | _ret = { 57 | midashiMap 58 | }; 59 | return Promise.resolve(_ret); 60 | }; 61 | -------------------------------------------------------------------------------- /packages/textlint-rule-preset-foreign-language-writing-helper/src/textlint-rule-preset-foreign-language-writing-helper.ts: -------------------------------------------------------------------------------- 1 | export { createKatakanaEnglishIndex, KatakanEnglishIndexType } from "./create-katakana-english-index"; 2 | -------------------------------------------------------------------------------- /packages/textlint-rule-preset-foreign-language-writing-helper/test/create-katakana-english-index.test.ts: -------------------------------------------------------------------------------- 1 | import { createKatakanaEnglishIndex } from "../src/create-katakana-english-index"; 2 | import assert from "assert"; 3 | describe("create-katakana-english-index", () => { 4 | it("should should Map<カタカナ, 英単語[]>", async () => { 5 | const { midashiMap } = await createKatakanaEnglishIndex(); 6 | const englishItems = midashiMap.get("エディタ"); 7 | assert.deepStrictEqual(englishItems, ["editor"]); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /packages/textlint-rule-preset-foreign-language-writing-helper/test/mocha.opts: -------------------------------------------------------------------------------- 1 | --require ts-node-test-register 2 | -------------------------------------------------------------------------------- /packages/textlint-rule-preset-foreign-language-writing-helper/test/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "declaration": false, 5 | "noEmit": true 6 | }, 7 | "include": [ 8 | "../src/**/*", 9 | "./**/*" 10 | ] 11 | } -------------------------------------------------------------------------------- /packages/textlint-rule-preset-foreign-language-writing-helper/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Basic Options */ 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "esModuleInterop": true, 7 | "newLine": "LF", 8 | "outDir": "./lib/", 9 | "target": "es5", 10 | "sourceMap": true, 11 | "declaration": true, 12 | "jsx": "preserve", 13 | "lib": [ 14 | "esnext", 15 | "dom" 16 | ], 17 | /* Strict Type-Checking Options */ 18 | "strict": true, 19 | /* Additional Checks */ 20 | /* Report errors on unused locals. */ 21 | "noUnusedLocals": true, 22 | /* Report errors on unused parameters. */ 23 | "noUnusedParameters": true, 24 | /* Report error when not all code paths in function return a value. */ 25 | "noImplicitReturns": true, 26 | /* Report errors for fallthrough cases in switch statement. */ 27 | "noFallthroughCasesInSwitch": true 28 | }, 29 | "include": [ 30 | "src/**/*" 31 | ], 32 | "exclude": [ 33 | ".git", 34 | "node_modules" 35 | ] 36 | } -------------------------------------------------------------------------------- /tools/update-readme.ts: -------------------------------------------------------------------------------- 1 | // MIT © 2016 azu 2 | "use strict"; 3 | import fs from "fs"; 4 | import path from "path"; 5 | 6 | import { getPackages } from "@monorepo-utils/package-utils"; 7 | import { PackageResult } from "@monorepo-utils/package-utils/lib/get-packages"; 8 | 9 | const addMarkdown = require("add-text-to-markdown"); 10 | const SectionName = "ルール一覧"; 11 | const escapeMarkdown = (text: string) => { 12 | return text.replace(/([\[])/g, "\\$1"); 13 | }; 14 | const RootDirectory = path.join(__dirname, ".."); 15 | const createPackageList = (item: PackageResult) => { 16 | const relativePath = path.relative(RootDirectory, item.location); 17 | return `### [${escapeMarkdown(item.packageJSON["name"])}](${relativePath}) 18 | 19 | > ${escapeMarkdown(item.packageJSON["description"])} 20 | `; 21 | }; 22 | const packagePathList = getPackages(RootDirectory).filter(item => { 23 | return !/-helper$/.test(item.location); 24 | }); 25 | const items = packagePathList.map(item => createPackageList(item)).join("\n\n"); 26 | const README_PATH = path.join(__dirname, "..", "README.md"); 27 | const README = fs.readFileSync(README_PATH, "utf-8"); 28 | const UpdatedREADM = addMarkdown(README, items, SectionName); 29 | fs.writeFileSync(README_PATH, UpdatedREADM, "utf-8"); 30 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Basic Options */ 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "esModuleInterop": true, 7 | "newLine": "LF", 8 | "outDir": "./lib/", 9 | "target": "es2015", 10 | "sourceMap": true, 11 | "declaration": true, 12 | "noEmit": true, 13 | "jsx": "preserve", 14 | "lib": [ 15 | "esnext", 16 | "dom" 17 | ], 18 | /* Strict Type-Checking Options */ 19 | "strict": true, 20 | /* Additional Checks */ 21 | /* Report errors on unused locals. */ 22 | "noUnusedLocals": true, 23 | /* Report errors on unused parameters. */ 24 | "noUnusedParameters": true, 25 | /* Report error when not all code paths in function return a value. */ 26 | "noImplicitReturns": true, 27 | /* Report errors for fallthrough cases in switch statement. */ 28 | "noFallthroughCasesInSwitch": true 29 | }, 30 | "include": [ 31 | "**/*" 32 | ], 33 | "exclude": [ 34 | ".git", 35 | "node_modules" 36 | ] 37 | } 38 | --------------------------------------------------------------------------------