├── .babelrc ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── example ├── app.js ├── index.html └── package.json ├── package.json ├── src └── codemirror-textlint.js └── test ├── codemirror-textlint-test.js └── mocha.opts /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015"], 3 | "plugins": ["add-module-exports"] 4 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /example/build.js 2 | ### https://raw.github.com/github/gitignore/608690d6b9a78c2a003affc792e49a84905b3118/Node.gitignore 3 | 4 | # Logs 5 | logs 6 | *.log 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | 13 | # Directory for instrumented libs generated by jscoverage/JSCover 14 | lib-cov 15 | 16 | # Coverage directory used by tools like istanbul 17 | coverage 18 | 19 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 20 | .grunt 21 | 22 | # node-waf configuration 23 | .lock-wscript 24 | 25 | # Compiled binary addons (http://nodejs.org/api/addons.html) 26 | build/Release 27 | 28 | # Dependency directory 29 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- 30 | node_modules 31 | 32 | # Debug log from npm 33 | npm-debug.log 34 | 35 | 36 | ### https://raw.github.com/github/gitignore/608690d6b9a78c2a003affc792e49a84905b3118/Global/JetBrains.gitignore 37 | 38 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm 39 | 40 | *.iml 41 | 42 | ## Directory-based project format: 43 | .idea/ 44 | # if you remove the above rule, at least ignore the following: 45 | 46 | # User-specific stuff: 47 | # .idea/workspace.xml 48 | # .idea/tasks.xml 49 | # .idea/dictionaries 50 | 51 | # Sensitive or high-churn files: 52 | # .idea/dataSources.ids 53 | # .idea/dataSources.xml 54 | # .idea/sqlDataSources.xml 55 | # .idea/dynamic.xml 56 | # .idea/uiDesigner.xml 57 | 58 | # Gradle: 59 | # .idea/gradle.xml 60 | # .idea/libraries 61 | 62 | # Mongo Explorer plugin: 63 | # .idea/mongoSettings.xml 64 | 65 | ## File-based project format: 66 | *.ipr 67 | *.iws 68 | 69 | ## Plugin-specific files: 70 | 71 | # IntelliJ 72 | out/ 73 | 74 | # mpeltonen/sbt-idea plugin 75 | .idea_modules/ 76 | 77 | # JIRA plugin 78 | atlassian-ide-plugin.xml 79 | 80 | # Crashlytics plugin (for Android Studio and IntelliJ) 81 | com_crashlytics_export_strings.xml 82 | crashlytics.properties 83 | crashlytics-build.properties 84 | 85 | 86 | /lib 87 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: "stable" 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 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 | # codemirror-textlint 2 | 3 | CodeMirror plugin for [textlint](https://github.com/textlint/textlint "textlint"). 4 | 5 | ## Installation 6 | 7 | npm install codemirror-textlint 8 | 9 | ## Usage 10 | 11 | ```js 12 | var CodeMirror = require("codemirror"); 13 | require("./node_modules/codemirror/mode/markdown/markdown.js"); 14 | require("./node_modules/codemirror/addon/lint/lint.js"); 15 | var createValidator = require("codemirror-textlint"); 16 | var noTodo = require("textlint-rule-no-todo"); 17 | var validator = createValidator({ 18 | rules: { 19 | "no-todo": noTodo 20 | } 21 | }); 22 | var editor = CodeMirror.fromTextArea(document.getElementById("code-md"), { 23 | lineNumbers: true, 24 | mode: "markdown", 25 | gutters: ["CodeMirror-lint-markers"], 26 | lint: { 27 | "getAnnotations": validator, 28 | "async": true 29 | } 30 | }); 31 | ``` 32 | ## Tests 33 | 34 | npm test 35 | 36 | ## Contributing 37 | 38 | 1. Fork it! 39 | 2. Create your feature branch: `git checkout -b my-new-feature` 40 | 3. Commit your changes: `git commit -am 'Add some feature'` 41 | 4. Push to the branch: `git push origin my-new-feature` 42 | 5. Submit a pull request :D 43 | 44 | ## License 45 | 46 | MIT -------------------------------------------------------------------------------- /example/app.js: -------------------------------------------------------------------------------- 1 | // LICENSE : MIT 2 | "use strict"; 3 | var CodeMirror = require("codemirror"); 4 | require("./node_modules/codemirror/mode/markdown/markdown.js"); 5 | require("./node_modules/codemirror/addon/lint/lint.js"); 6 | var createValidator = require("codemirror-textlint"); 7 | var noTodo = require("textlint-rule-no-todo"); 8 | var validator = createValidator({ 9 | rules: { 10 | "no-todo": noTodo 11 | } 12 | }); 13 | var editor = CodeMirror.fromTextArea(document.getElementById("code-md"), { 14 | lineNumbers: true, 15 | mode: "markdown", 16 | gutters: ["CodeMirror-lint-markers"], 17 | lint: { 18 | "getAnnotations": validator, 19 | "async": true 20 | } 21 | }); 22 | -------------------------------------------------------------------------------- /example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CodeMirror 6 | 7 | 8 | 9 | 10 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "build": "browserify app.js -o build.js" 8 | }, 9 | "auth,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,or": "azu", 10 | "license": "MIT", 11 | "dependencies": { 12 | "codemirror": "^5.9.0", 13 | "codemirror-textlint": "file:../", 14 | "textlint-rule-no-todo": "^1.0.3" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "codemirror-textlint", 3 | "repository": { 4 | "type": "git", 5 | "url": "git+https://github.com/azu/codemirror-textlint.git" 6 | }, 7 | "author": "azu", 8 | "email": "azuciao@gmail.com", 9 | "homepage": "https://github.com/azu/codemirror-textlint", 10 | "license": "MIT", 11 | "bugs": { 12 | "url": "https://github.com/azu/codemirror-textlint/issues" 13 | }, 14 | "version": "1.2.0", 15 | "description": "CodeMirror with textlint.", 16 | "main": "lib/codemirror-textlint.js", 17 | "files": [ 18 | "lib", 19 | "src" 20 | ], 21 | "directories": { 22 | "test": "test" 23 | }, 24 | "scripts": { 25 | "build": "babel src --out-dir lib --source-maps", 26 | "watch": "babel src --out-dir lib --watch --source-maps", 27 | "prepublish": "npm run --if-present build", 28 | "test": "mocha" 29 | }, 30 | "keywords": [ 31 | "textlint", 32 | "codemirror" 33 | ], 34 | "devDependencies": { 35 | "babel-cli": "^6.3.17", 36 | "babel-plugin-add-module-exports": "^0.2.1", 37 | "babel-preset-es2015": "^6.3.13", 38 | "babelify": "^7.2.0", 39 | "browserify": "^13.0.1", 40 | "codemirror": "^5.9.0", 41 | "espower-babel": "^4.0.0", 42 | "mocha": "^3.0.1", 43 | "power-assert": "^1.2.0", 44 | "watchify": "^3.6.1" 45 | }, 46 | "dependencies": { 47 | "textlint": "^8.0.0" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/codemirror-textlint.js: -------------------------------------------------------------------------------- 1 | // LICENSE : MIT 2 | "use strict"; 3 | import {TextLintCore} from "textlint"; 4 | export default function createValidator(options = {}) { 5 | const textlint = new TextLintCore(); 6 | const rules = options.rules || {}; 7 | const rulesConfig = options.rulesConfig || {}; 8 | const Processors = options.Processors || []; 9 | textlint.setupRules(rules, rulesConfig); 10 | Processors.forEach(Processor => { 11 | textlint.addProcessor(Processor); 12 | }); 13 | function convertSeverity(severity) { 14 | switch (severity) { 15 | case 1: 16 | return "warning"; 17 | case 2: 18 | return "error"; 19 | default: 20 | return "error"; 21 | } 22 | } 23 | 24 | return function textlintValidator(text, updateLinting) { 25 | textlint.lintMarkdown(text).then(result => { 26 | const results = []; 27 | result.messages.forEach(message => { 28 | // https://codemirror.net/doc/manual.html 29 | // the API uses objects with line and ch properties. Both are zero-based. 30 | const posFrom = {line: message.line - 1, ch: message.column - 1}; 31 | const posTo = {line: message.line - 1, ch: message.column}; 32 | results.push({ 33 | from: posFrom, 34 | to: posTo, 35 | message: message.message, 36 | severity: convertSeverity(message.severity) 37 | }); 38 | }); 39 | updateLinting(results); 40 | }); 41 | }; 42 | } -------------------------------------------------------------------------------- /test/codemirror-textlint-test.js: -------------------------------------------------------------------------------- 1 | import assert from "power-assert"; 2 | import createValidator from "../src/codemirror-textlint"; 3 | describe("codemirror-textlint", function () { 4 | it("should return lint function", function (done) { 5 | const actualText = "test text"; 6 | const validator = createValidator({ 7 | rules: { 8 | "example-rule": function (context) { 9 | let {Syntax,getSource, report,RuleError} = context; 10 | return { 11 | [Syntax.Document](node){ 12 | const text = getSource(node); 13 | assert.equal(text, actualText); 14 | report(node, new RuleError("message")); 15 | } 16 | } 17 | } 18 | } 19 | }); 20 | validator(actualText, (results) => { 21 | assert.equal(results.length, 1); 22 | var result = results[0]; 23 | assert.equal(result.message, "message"); 24 | assert.deepEqual(result.from, {line: 0, ch: 0}); 25 | done(); 26 | }); 27 | }); 28 | }); -------------------------------------------------------------------------------- /test/mocha.opts: -------------------------------------------------------------------------------- 1 | --compilers js:espower-babel/guess --------------------------------------------------------------------------------