get-alex / alex

Catch insensitive, inconsiderate writing
https://alexjs.com
MIT License
4.81k stars 207 forks source link

Allow running html and text in a single command #264

Closed arirawr closed 5 years ago

arirawr commented 5 years ago

Subject of the feature

Allow running html and text in a single command

Problem

When running alex, text files are checked. When running alex --html, html files are checked. I would like to be able to do both in a single command, as my project has both html copy and markdown documentation.

Expected behaviour

Running alex --html treats text files as text and html as html and runs both.

Alternatives

Currently running the two commands separately.

wooorm commented 5 years ago

Hi there, nice to meet you and great idea! Unfortunately it would be pretty hard to accomplish in the CLI because alex and the underlying stuff is built for one type of “chain”, e.g., markdown to natural language, and then checking that natural language. That chain is defined before creating the CLI. It would take a lot of effort to change that unfortunately, so I’ll keep this in mind but it won’t happen in the foreseeable future.

Luckily the tools are also tiny packages, which act like lego bricks that you can combine in your own way. Here is an example (pseudo-code, should be close to working) that checks multiple types of files:

var glob = require('glob')
var async = require('async')
var trough = require('trough')
var vfile = require('to-vfile')
var reporter = require('vfile-reporter')
var unified = require('unified')
var markdown = require('remark-parse')
var frontmatter = require('remark-frontmatter')
var html = require('rehype-parse')
var english = require('retext-english')
var equality = require('retext-equality')
var profanities = require('retext-profanities')
var remark2retext = require('remark-retext')
var rehype2retext = require('rehype-retext')

var textProcessor = unified()
  .use(english)
  .use(equality)
  .use(profanities)

var htmlProcessor = unified()
  .use(html)
  .use(rehype2retext)
  .use(english)
  .use(equality)
  .use(profanities)

var markdownProcessor = unified()
  .use(markdown)
  .use(frontmatter, ['yaml', 'toml'])
  .use(remark2retext)
  .use(english)
  .use(equality)
  .use(profanities)

var processors = {
  html: htmlProcessor,
  htm: htmlProcessor,
  mkdn: markdownProcessor,
  md: markdownProcessor,
  text: textProcessor,
  txt: textProcessor
}

var filePipeline = trough()
  .use(vfile.read)
  .use(function(file, next) {
    var ext = file.extname

    if (ext in processors) {
      processors[ext]().process(file, function(err) {
        next(err)
      })
    } else {
      next()
    }
  })
  .use(function(file) {
    console.error(reporter(file))
  })

trough()
  .use(glob)
  .use(function(paths, done) {
    return async.map(paths, filePipeline.run, done)
  })
  .run('src/**/*.*', function(err) {
    if (err) {
      console.error(err)
      process.exitCode = 1
    }
  })

The benefits of rolling your own instead of using alex is that you could check many more things! See here for other plugins and learn more about unified on its website