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

mecab-spawn

v1.0.1

Published

Morpheme analyzer MeCab IPC client.

Downloads

1

Readme

mecab-spawn

mecab-spawn は形態素解析器 MeCab とのプロセス間通信を簡易化するパッケージです。

インストール

npm install mecab-spawn

使い方

MeCab プロセスのスポーン

const mecabSpawn = require('mecab-spawn')
const mecab = mecabSpawn.spawn()

spawn() は引数がない場合、パスの通った mecab コマンドを実行しようとします。引数を指定した場合は child_process.spawn() にそのまま渡されます。

// UniDic 辞書を使用する
const mecab = mecabSpawn.spawn('mecab', ['-d', '/usr/local/lib/mecab/dic/unidic-mecab'])

解析

以下の例は文字列を解析し結果をコンソールに出力します。

mecab.analyze('メカブ\nスポーン')
  .then(result => {
    console.log(result)
  }).catch(err => {
    console.error(err)
  })
// => [ [ 'メカブ', '名詞', '固有名詞', '組織', '*', '*', '*', '*' ],
//      'EOS',
//      [ 'スポーン', '名詞', '固有名詞', '組織', '*', '*', '*', '*' ] ]

ファイルの内容を解析する場合、ファイルと辞書のエンコーディングが同じであれば analyze()Bufferオブジェクトを渡すことでデコード処理を省けます。

fs.readFile('filename.txt', 'utf-8', (err, data) => {
  if (err) {
    console.error(err)
  } else {
     mecab.analyze(data)
       .then(console.log)
       .catch(console.error)
  }
})

MeCab プロセスの終了

mecab.analyze('...').then(console.log)

mecab.kill()
  .then(message => {
    console.log(message)
  }).catch(err => {
    console.error(err)
  })
// => MeCab process is killed.

analyze() は非同期で実行されますが、mecab-spawn はタスクのキューを持つため kill() は解析結果が返された後に実行されます。

行パース関数

解析結果のうち eos のみ mecab.getEOSObject() の値がそのまま使われ、残りは全て行パース関数が処理します。

MeCab の解析結果に対して、初期状態では慣例的に \t, で行を分割した文字列の配列を返します。具体的には line.split(/[\t,]/) を実行するだけです。

これを手早く変更するには以下のように createLineParser() でパース関数を作成し設定します。

// カンマのみで行を分割する
mecab.lineParser = mecab.createLineParser(',')

行パース関数には自分で作成した関数を設定できます。 以下はUniDicの初期書式の行をオブジェクトとして返す行パース関数の設定例です。

// Make UniDic default morpheme an Object.
//   node-format-unidic: %m\t%f[9]\t%f[6]\t%f[7]\t%F-[0,1,2,3]\t%f[4]\t%f[5]\t%f[23]\n
//   unk-format-unidic:  %m\t%m\t%m\t%m\t%F-[0,1,2,3]\t%f[4]\t%f[5]\t0\n
mecab.lineParser = line => {
  if (line === 'BOS') {
    return 'BOS'
  }
  const tokens = line.split('\t')
  if (tokens.length !== 8) {
    return { whatIsThis: line }
  }
  const m = { surface: tokens[0] }
  if (tokens[1]) m.pron = tokens[1]
  if (tokens[2]) m.lForm = tokens[2]
  if (tokens[3]) m.lemma = tokens[3]
  const posArray = tokens[4].split('-')
  m.pos1 = posArray[0]
  if (posArray[1]) m.pos2 = posArray[1]
  if (posArray[2]) m.pos3 = posArray[2]
  if (posArray[3]) m.pos4 = posArray[3]
  if (tokens[5]) m.cType = tokens[5]
  if (tokens[6]) m.cForm = tokens[6]
  if (tokens[7]) m.aType = Number(tokens[7])
  return m
}

辞書のコーディングシステム

初期状態では UTF-8 辞書にのみ対応していますが、辞書に対応したエンコード/デコード関数を設定することで UTF-8 以外にも対応することができます。

npm install iconv-lite
// iconv-lite で EUC-JP 辞書に対応する
const iconv = require('iconv-lite')
// UTF-8 => EUC-JP
// EUC-JP のファイルを直接読ませる場合は不要
mecab.setDefaultEncoder(data => iconv.encode(data, 'eucjp'))
// EUC-JP => UTF-8
mecab.setDefaultDecoder(data => iconv.decode(data, 'eucjp'))

あるいは analyze() にエンコード/デコード関数を指定することで優先的に解析元データに合わせて変更できます。

const eucjpDecoder = data => iconv.decode(data, 'eucjp')
mecab.analyze(data, null, eucjpDecoder)

EOS オブジェクト

初期状態の解析結果では eos"EOS" 文字列オブジェクトですが、その後の処理の為に必要であれば変更可能です。

// 配列に入った eos を設定する。
mecab.setEOSObject(['EOS'])
mecab.analyze('メカブ\nスポーン\nスポーン').then(console.log)
// => [ [ 'メカブ', '名詞', '固有名詞', '組織', '*', '*', '*', '*' ],
        [ 'EOS' ],
        [ 'スポーン', '名詞', '固有名詞', '組織', '*', '*', '*', '*' ],
        [ 'EOS' ],
        [ 'スポーン', '名詞', '固有名詞', '組織', '*', '*', '*', '*' ] ]

EOS フォーマット

mecab-spawnMeCab の解析出力完了時を調べるためにバイト列中の eos 出現回数を数えることで判断します。もし解析結果とeos-formatの区別がつかない場合は解析結果の読み取りに失敗します。

EOS フォーマットを設定する際に Windows や Mac で \rを設定する必要はありません。MeCab は \n を自動的に OS に合わせた改行文字で出力するからです。

// eos を変更する
mecabIPC.spawn('mecab', ['--eos-format=End\\sof\\sSentence\\n'])
mecab.setEOSSample('End of Sentence\\n')