npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

zhlint

v0.8.2

Published

A linting tool for Chinese language.

Downloads

2,323

Readme

zhlint

一个中文内容的格式化工具。

如何安装

您可以通过 npmyarn 安装 zhlint

# 通过 npm 安装
npm install zhlint -g

# 或通过 yarn
yarn global add zhlint

# 或通过 pnpm
pnpm add zhlint -g

用法

作为 CLI

# Glob 文件,执行格式化命令,并打印错误报告,
# 如果有任何错误被发现,则会以错误码 `1` 退出。
zhlint <file-pattern>

# Glob 文件,并修复所有可能发现的错误。
zhlint <file-pattern> --fix

# 格式化文件并将修复后的内容输出到另一个文件。
zhlint <input-file-path> --output=<output-file-path>

# 打印用法信息
zhlint --help

错误报告看起来像这样:

高阶用法

zhlint 还支持 rc 和 ignore 配置文件:

# 默认为 .zhlintrc
zhlint --config <filepath>

# 默认为 .zhlintignore
zhlint --ignore <filepath>
zhlint --file-ignore <filepath>

# 默认为 .zhlintcaseignore
zhlint --case-ignore <filepath>

# 默认为 current directory
zhlint --dir <path>

在 rc 配置文件中,您可以写一个 JSON,例如:

{
  "preset": "default",
  "rules": {
    "adjustedFullwidthPunctuation": ""
  }
}

关于更多细节,请参见支持的规则

在 file-ignore 文件中,您可以写多行内容来忽略相应的文件,其语法遵循 .gitignore 语法

在 case-ignore 文件中,您可以写多行内容来忽略一些特例,例如:

( , )

关于更多细节:请参见设置被忽略的特例

作为 Node.js 包

const { run, report } = require('zhlint')

const value = '自动在中文和English之间加入空格'
const options = { rules: { preset: 'default' }}
const output = run(value, options)

// 打印 '自动在中文和 English 之间加入空格'
console.log(output.result)

// 打印错误报告
report([output])

错误报告的格式像这样:

1:6 - 此处中英文内容之间需要一个空格

自动在中文和English之间加入空格
      ^

1:13 - 此处中英文内容之间需要一个空格

自动在中文和English之间加入空格
             ^
Invalid files:
- foo.md

Found 2 errors.

高阶用法

zhlint 还支持 rc 和 ignore 配置文件:

const { readRc, runWithConfig } = require('zhlint')

const value = '自动在中文和English之间加入空格'

const dir = '...' // 目标文件所在的目录
const configPath = '...' // rc 配置文件路径
const fileIgnorePath = '...' // file-ignore 文件路径
const caseIgnorePath = '...' // case-ignore 文件路径

const config = readRc(dir, configPath, fileIgnorePath, caseIgnorePath)
const output = runWithConfig(value, config)

// ... 后续操作

作为一个单独的包

您可以找到一个 JavaScript 文件 dist/zhlint.js 作为独立版本。 例如,要使用它,您可以直接将它添加到您的浏览器中作为 <script> 标签。 即可访问全局变量 zhlint

API

  • run(str: string, options?: Options): Result:格式化某个文件内容。
    • 参数:
      • str:需要格式化的文本内容。
      • options:一些配置选项。
    • 返回值:
      • 针对输入的单个字符串的处理结果。其包好了修复格式之后的文本内容 value 以及所有 validation 的格式化信息。
  • report(results: Result[], logger?: Console): void:为每个文件打印格式化报告。
    • 参数:
      • results:所有格式化结果的数组。
      • logger:日志处理器实例,默认是 Node.js/浏览器中的 console
  • readRc: (dir: string, config: string, fileIgnore: string, caseIgnore: string, logger?: Console) => Config:读取配置文件信息。
  • runWithConfig(str: string, config: Config): Result:通过配置信息格式化特定内容。

选项

自定义你的格式化规则和其它高阶选项。

type Options = {
  rules?: RuleOptions
  hyperParse?: string[]
  ignoredCases?: IgnoredCase[]
  logger?: Console
}
  • rules:自定义格式化规则,可以是 undefined 意味着不做任何格式化,也可以是 { preset: 'default' } 以使用默认配置。关于 RuleOptions 的更多细节参见支持的规则
  • hyperParse:根据解析器名自定义超文本解析器列表。可以是 undefined 以使用默认的忽略特例的解析器Markdown 解析器以及Hexo tag 解析器
  • ignoredCases:提供想要忽略的特例。
  • logger:和 report(...) 中的参数相同。

RC Config

  • preset: string (可选项)
  • rules: RuleOptions 但不包括 preset 字段。(可选项)
  • hyperParsers: string[] (可选项)
  • caseIgnores: string[] 该优先级低于 .zhlintcaseignore。(可选项)

输出格式

type Result = {
  // 基本信息和文件的可用性
  file?: string
  disabled: boolean

  // 原始的文本内容
  origin: string

  // 所有错误信息
  validations: Validation[]
}

type Validation = {
  message: string
  index: number
  length: number
}
  • Result
    • file:文件名。这是一个可选的字段,只在 CLI 中适用。
    • origin:原始的文本内容。
    • result:最终修复格式的文本内容。
    • validations:所有格式化信息。
  • Validation
    • index:输入的字符串中目标片段所在的索引值。
    • length:输入的字符串中目标片段的长度。
    • message:对该格式化信息的自然语言描述。

特性

Markdown 语法支持

我们默认支持格式化 Markdown 语法的文本内容。例如:

run('自动在_中文_和**English**之间加入空格')

这将首先分析 Markdown 语法并提取纯文本内容,然后执行格式化操作。修复后的纯文本内容可以复原为 Markdown 格式字符串,并作为结果中的输出 value 返回。

Hexo tag 语法支持

特别地,我们支持 Hexo tag 语法。这是因为当我们使用 Hexo 构建 Vue.js 网站时,Markdown 源文件中可能包含一些特殊的标签从而得到不可预测的格式化结果。

因此,我们会默认跳过 Hexo 风格的标签。例如:

run('现在过滤器只能用在插入文本中 (`{% raw %}{{ }}{% endraw %}` tags)。')

设置被忽略的特例

在一些特殊的情况下,我们可能会有一些特殊的文本内容不遵循规则。因此,我们可以使用 ignoredCases 选项来配置。例如,我们想要保留括号内的空格,这在默认情况下是格式不正确的。不过我们可以在文件的任何地方写一行 HTML 注释:

<!-- the good case -->

text before (text inside) text after

<!-- the bad case -->

vm.$on( event, callback )

<!-- 我们可以在这里写下要忽略的特例 -->
<!-- zhlint ignore: ( , ) -->

或传入高阶选项:

run(str, { ignoredCases: { textStart: '( ', textEnd: ' )' } })

如果你想要忽略整个文件,你也可以添加这个 HTML 注释:

<!-- zhlint disabled -->

支持的预处理器 (超文本解析器)

  • ignore:通过 HTML 注释 <!-- zhlint ignore: ... --> 匹配所有被忽略的特例
  • hexo:匹配所有 Hexo tag 以避免它们被解析。
  • markdown:用 Markdown 解析器找到所有的块级文本和内联级的标记。

支持的规则

大多数规则都提炼自过往 W3C 中文排版需求W3C HTML 中文兴趣组Vue.js 中文文档的翻译经验。

……这些规则也许存在争议。所以如果你对某些规则不够满意,我们非常希望得到大家的反馈和改进建议。我们也一直欢迎大家来创建 issue,以讨论出可能更好的规则。

type RuleOptions = {
  /* PRESET */

  // Custom preset, currently only support:
  // - `'default'`
  preset?: string

  /* PUNCTUATIONS */

  // Convert these punctuations into halfwidth.
  // default preset: `()`
  // e.g. `(文字)` -> `(文字)`
  halfwidthPunctuation?: string

  // Convert these punctuations into fullwidth.
  // default preset: `,。:;?!“”‘’`
  // e.g. `文字,文字.` -> `文字,文字。`
  fullwidthPunctuation?: string

  // Treat these fullwidth punctuations as half-fullWidthPunctuation
  // when processing the spaces issues around them.
  // Since something like quotations in morder Chinese fonts are
  // only rendered in halfwidth.
  // default preset: `“”‘’`
  adjustedFullwidthPunctuation?: string

  // Convert traditional Chinese punctuations into simplified ones or vice versa.
  // default preset: `simplified`
  // e.g. `「文字」` -> `“文字”`
  //
  // besides the above, we also unify some common punctuations below:
  //
  // // U+2047 DOUBLE QUESTION MARK, U+203C DOUBLE EXCLAMATION MARK
  // // U+2048 QUESTION EXCLAMATION MARK, U+2049 EXCLAMATION QUESTION MARK
  // '??': ['⁇'],
  // '!!': ['‼'],
  // '?!': ['⁈'],
  // '!?': ['⁉'],
  //
  // // U+002F SOLIDUS, U+FF0F FULLWIDTH SOLIDUS
  // '/': ['/', '/'],
  //
  // // U+FF5E FULLWIDTH TILDE
  // '~': ['~', '~'],
  //
  // // U+2026 HORIZONTAL ELLIPSIS, U+22EF MIDLINE HORIZONTAL ELLIPSIS
  // '…': ['…', '⋯'],
  //
  // // U+25CF BLACK CIRCLE, U+2022 BULLET, U+00B7 MIDDLE DOT,
  // // U+2027 HYPHENATION POINT, U+30FB KATAKANA MIDDLE DOT
  // '·': ['●', '•', '·', '‧', '・'],
  //
  // advanced usage: you can also specify a more detailed map like:
  //
  // ```
  // {
  //   default: true, // follow all the default preset
  //   '「': ['“', '【'], // convert `“` or `【` into `「`
  //   '」': ['”', '】'], // convert `”` or `】` into `」`
  //  '…': true, // follow the default preset for this character
  //  '·': false, // not unify any of these characters
  // }
  // ```
  unifiedPunctuation?: 'traditional' | 'simplified' | Record<string, boolean | string[]> & { default: boolean }

  // Special case: skip `fullWidthPunctuation` for abbreviations.
  // default preset:
  // `['Mr.','Mrs.','Dr.','Jr.','Sr.','vs.','etc.','i.e.','e.g.','a.k.a']`
  skipAbbrs?: string[]

  /* SPACES AROUND LETTERS */

  // default preset: `true`
  // - `true`: one space
  // - `undefined`: do nothing
  // e.g. `foo  bar` -> `foo bar`
  spaceBetweenHalfwidthContent?: boolean

  // default preset: `true`
  // - `true`: zero space
  // - `undefined`: do nothing
  // e.g. `文 字` -> `文字`
  noSpaceBetweenFullwidthContent?: boolean

  // default preset: `true`
  // - `true`: one space
  // - `false`: zero space
  // - `undefined`: do nothing
  // e.g. `文字 foo文字` -> `文字 foo 文字` (`true`)
  // e.g. `文字foo 文字` -> `文字foo文字` (`false`)
  spaceBetweenMixedwidthContent?: boolean

  // Special case: skip `spaceBetweenMixedWidthContent`
  // for numbers x Chinese units.
  // default preset: `年月日天号时分秒`
  skipZhUnits?: string

  /* SPACES AROUND PUNCTUATIONS */

  // default preset: `true`
  // - `true`: zero space
  // - `undefined`: do nothing
  // e.g. `文字 ,文字` -> `文字,文字`
  noSpaceBeforePauseOrStop?: boolean

  // default preset: `true`
  // - `true`: one space
  // - `false`: zero space
  // - `undefined`: do nothing
  // e.g. `文字,文字` -> `文字, 文字` (`true`)
  // e.g. `文字, 文字` -> `文字,文字` (`false`)
  spaceAfterHalfwidthPauseOrStop?: boolean

  // default preset: `true`
  // - `true`: zero space
  // - `undefined`: do nothing
  // e.g. `文字, 文字` -> `文字,文字`
  noSpaceAfterFullwidthPauseOrStop?: boolean

  /* SPACES AROUND QUOTATIONS */

  // default preset: `true`
  // - `true`: one space
  // - `false`: zero space
  // - `undefined`: do nothing
  // e.g. `文字 "文字"文字` -> `文字 "文字" 文字` (`true`)
  // e.g. `文字"文字" 文字` -> `文字"文字"文字` (`false`)
  spaceOutsideHalfwidthQuotation?: boolean

  // default preset: `true`
  // - `true`: zero space
  // - `undefined`: do nothing
  // e.g. `文字 “文字” 文字` -> `文字“文字”文字`
  noSpaceOutsideFullwidthQuotation?: boolean

  // default preset: `true`
  // - `true`: zero space
  // - `undefined`: do nothing
  // e.g. `文字“ 文字 ”文字` -> `文字“文字”文字`
  noSpaceInsideQuotation?: boolean

  /* SPACES AROUND BRACKETS */

  // default preset: `true`
  // - `true`: one space
  // - `false`: zero space
  // - `undefined`: do nothing
  spaceOutsideHalfwidthBracket?: boolean

  // default preset: `true`
  // - `true`: zero space
  // - `undefined`: do nothing
  noSpaceOutsideFullwidthBracket?: boolean

  // default preset: `true`
  // - `true`: zero space
  // - `undefined`: do nothing
  noSpaceInsideBracket?: boolean

  /* SPACES AROUND CODE */

  // default preset: `true`
  // - `true`: one space
  // - `false`: zero space
  // - `undefined`: do nothing
  // e.g. '文字 `code`文字' -> '文字 `code` 文字' ('true')
  // e.g. '文字`code` 文字' -> '文字`code`文字' ('false')
  spaceOutsideCode?: boolean

  /* SPACES AROUND MARKDOWN/HTML WRAPPERS */

  // default `true`
  // - `true`: zero space
  // - `undefined`: do nothing
  // e.g. `文字** foo **文字` -> `文字 **foo** 文字`
  noSpaceInsideHyperMark?: boolean

  /* SPACES AT THE BEGINNING/END */

  // default `true`
  // e.g. ` 文字 ` -> `文字`
  trimSpace?: boolean

  /* SKIP PURE WESTERN SENTENCES */

  // default `true`
  skipPureWestern?: boolean
}

更多信息

zhlint 是一个开源项目,目前源代码在 GitHub 上,也欢迎大家来提交 issue