Skip to content

Commit

Permalink
feat(helper: add helper.isPlainStrNode methods (#17)
Browse files Browse the repository at this point in the history
* feat: add `helper.isPlainStrNode` methods

* test: update mocha

* test: add test

* Update README

* Update README

* Update README
  • Loading branch information
azu authored May 16, 2021
1 parent 11b01bf commit e80e06a
Show file tree
Hide file tree
Showing 10 changed files with 1,426 additions and 627 deletions.
20 changes: 20 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: test
on: [push, pull_request]
jobs:
test:
name: "Test on Node.js ${{ matrix.node-version }}"
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12, 14]
steps:
- name: checkout
uses: actions/checkout@v2
- name: setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- name: Install
run: yarn install
- name: Test
run: yarn test
5 changes: 5 additions & 0 deletions .mocharc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"require": [
"ts-node-test-register"
]
}
4 changes: 0 additions & 4 deletions .travis.yml

This file was deleted.

42 changes: 41 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# textlint-rule-helper [![Build Status](https://travis-ci.org/textlint/textlint-rule-helper.svg?branch=master)](https://travis-ci.org/textlint/textlint-rule-helper)
# textlint-rule-helper [![Actions Status: test](https://github.com/textlint/textlint-rule-helper/workflows/test/badge.svg)](https://github.com/textlint/textlint-rule-helper/actions?query=workflow%3A"test")

This is helper library for creating [textlint](https://github.com/textlint/textlint "textlint") rule.

Expand Down Expand Up @@ -33,6 +33,46 @@ Return true if `node` is wrapped any one of node `types`.
- node `TxtNode` - is target node
- types `Array.<string>` - are wrapped target node

#### ruleHelper.isPlainStrNode(node): boolean

Return true if the node is Str node and fill following conditions:

- the node is Str node
- the node is under the Paragraph node
- the node is not under the BlockQuote

This function is useful for common use-case.
If you want to lint Str node, but you not want to lint styled node, this function is useful.
The styled node is Link, Strong, BlockQuote, Header etc, and it may be written by another people.
For example, you have added a link to your document, the link's title is written by another people.

Opposite of it, The plain Str node is just under the Paragraph node, and it was written by user.

**Examples**

Return true

```markdown
str str str
- list text
```

Return false

```markdown
# Header
![alt text](https://example.com)
[link title](https://example.com)
> BlockQuote text
**Strong text**
[linkReference][]
[^footnote text]
```

**Params**

- node `TxtNode` - is target node

### class IgnoreNodeManager

You can manager ignoring range in texts.
Expand Down
22 changes: 11 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "textlint-rule-helper",
"version": "2.1.1",
"description": "Helper for textlint rule.",
"description": "A helper library for textlint rule.",
"homepage": "https://github.com/textlint/textlint-rule-helper/",
"bugs": {
"url": "https://github.com/textlint/textlint-rule-helper/issues"
Expand All @@ -25,22 +25,22 @@
"watch": "tsc -p . --watch"
},
"dependencies": {
"@textlint/ast-node-types": "^4.2.1",
"@textlint/types": "^1.1.2",
"@textlint/ast-node-types": "^4.4.3",
"@textlint/types": "^1.5.5",
"structured-source": "^3.0.2",
"unist-util-visit": "^1.1.0"
},
"devDependencies": {
"@types/mocha": "^5.2.5",
"@types/node": "^10.12.18",
"@types/mocha": "^8.2.2",
"@types/node": "^15.3.0",
"@types/structured-source": "^3.0.0",
"cross-env": "^5.2.0",
"cross-env": "^7.0.3",
"markdown-to-ast": "^6.0.3",
"mocha": "^5.2.0",
"textlint": "^11.2.1",
"ts-node": "^7.0.1",
"ts-node-test-register": "^4.0.0",
"mocha": "^8.4.0",
"textlint": "^11.9.1",
"ts-node": "^9.1.1",
"ts-node-test-register": "^9.0.1",
"txt-ast-traverse": "^2.0.4",
"typescript": "^3.2.2"
"typescript": "^4.2.4"
}
}
63 changes: 59 additions & 4 deletions src/textlint-rule-helper.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import { TxtNode } from "@textlint/ast-node-types"
import { TextlintRuleContext } from "@textlint/types"
import { ASTNodeTypes, TxtNode } from "@textlint/ast-node-types"

/**
* RuleHelper is helper class for textlint.
* @class RuleHelper
*/
export default class RuleHelper {
// @ts-ignore
private _ruleContext: any;
private _ruleContext: Readonly<TextlintRuleContext>;

/**
* Initialize RuleHelper with RuleContext object.
* @param {RuleContext} ruleContext the ruleContext is context object of the rule.
* @param ruleContext the ruleContext is context object of the rule.
*/
constructor(ruleContext: any) {
constructor(ruleContext: Readonly<TextlintRuleContext>) {
this._ruleContext = ruleContext;
}

Expand Down Expand Up @@ -49,4 +50,58 @@ export default class RuleHelper {
});
});
}

/**
* Return true if the node is Str node and fill following conditions
*
* - the node is Str node
* - the node is under the Paragraph node
* - the node is not under the BlockQuote
*
* This function is useful for common use-case.
* If you want to lint Str node, but you not want to lint styled node, this function is useful.
* styled node is Link, Strong, BlockQuote, Header etc...
* Opposite of it, plain str node is just under the Paragraph node.
*
* @example
*
* Return true
*
* ---
* str str str
* - list text
* ---
*
* Return false
*
* ----
* # Header
* ![alt text](https://example.com)
* [link title](https://example.com)
* > BlockQuote
* **Strong**
* [^footnote]: text text
* ----
*
* Summary:
*
* Return true if the node is plain text.
* In other words, return false if the node is styled
*
* @param node
*/
isPlainStrNode(node: TxtNode): boolean {
if (node.type !== ASTNodeTypes.Str) {
return false;
}
if (node.parent?.type !== ASTNodeTypes.Paragraph) {
return false;
}

const isInUncontrollableNode = this.isChildNode(node, [
// <blockquote> is Block node in html. It can has Pragaraph node as children
ASTNodeTypes.BlockQuote
]);
return !isInUncontrollableNode
}
}
2 changes: 2 additions & 0 deletions src/wrap-report-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export function wrapReportHandler<T extends Readonly<TextlintRuleContext>, R ext
const ignoreNodeTypes = options.ignoreNodeTypes || [];
const ignoreNodeManager = new IgnoreNodeManager();
const ruleHelper = new RuleHelper(context);
// @ts-expect-error: https://github.com/textlint/textlint/issues/770
const text = context.getSource();
const sourceLocation = new SourceLocation(text);
const reportIfUnignored = function reportIfUnignored(node: AnyTxtNode, ruleError: TextlintRuleError): void | Promise<any> {
Expand All @@ -54,6 +55,7 @@ export function wrapReportHandler<T extends Readonly<TextlintRuleContext>, R ext
}
return nodeHandler(node);
};
// @ts-expect-error: ignore
handlers[nodeType] = wrappedNodeHandler
});
return handlers;
Expand Down
1 change: 0 additions & 1 deletion test/mocha.opts

This file was deleted.

71 changes: 71 additions & 0 deletions test/textlint-rule-helper-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,75 @@ describe("textlint-rule-helper-test", function () {
});
});
});
describe("#isPlainStrNode(node)", () => {
it("should return true if the node is under the paragraph", () => {
const text = "text";
let result: boolean;
textlint.setupRules({
"rule-key": function (context: any) {
const helper = new RuleHelper(context);
return {
[context.Syntax.Str](node: TxtNode) {
result = helper.isPlainStrNode(node)
}
}
}
});
return textlint.lintMarkdown(text).then(() => {
assert.ok(result);
});
});
it("should return true if the node is under the paragraph in list", () => {
const text = "- text";
let result: boolean;
textlint.setupRules({
"rule-key": function (context: any) {
const helper = new RuleHelper(context);
return {
[context.Syntax.Str](node: TxtNode) {
result = helper.isPlainStrNode(node)
}
}
}
});
return textlint.lintMarkdown(text).then(() => {
assert.ok(result);
});
});
it("should return false if the node is under the Img, Link, Header, Strong", () => {
const text = `# text
![text](https://example.com/img)[text](https://example.com/img)**strong**__strong__`;
const results: boolean[] = [];
textlint.setupRules({
"rule-key": function (context: any) {
const helper = new RuleHelper(context);
return {
[context.Syntax.Str](node: TxtNode) {
results.push(helper.isPlainStrNode(node))
}
}
}
});
return textlint.lintMarkdown(text).then(() => {
results.forEach(result => assert(!result))
});
})
it("should return false if the node is under the blockquote ", () => {
const text = "> text";
let result: boolean;
textlint.setupRules({
"rule-key": function (context: any) {
const helper = new RuleHelper(context);
return {
[context.Syntax.Str](node: TxtNode) {
result = helper.isPlainStrNode(node)
}
}
}
});
return textlint.lintMarkdown(text).then(() => {
assert.ok(!result);
});
})
})
});
Loading

0 comments on commit e80e06a

Please sign in to comment.