Skip to content

Commit

Permalink
マージ: dev-option
Browse files Browse the repository at this point in the history
  • Loading branch information
big-stream committed Jun 25, 2020
2 parents c2993bc + 3e50fde commit d5c3c4f
Show file tree
Hide file tree
Showing 17 changed files with 596 additions and 1,397 deletions.
255 changes: 148 additions & 107 deletions README.md

Large diffs are not rendered by default.

421 changes: 62 additions & 359 deletions bin/rubygana.js

Large diffs are not rendered by default.

532 changes: 0 additions & 532 deletions bin/オプションと標準入力.js

This file was deleted.

156 changes: 92 additions & 64 deletions docs/index.html

Large diffs are not rendered by default.

94 changes: 23 additions & 71 deletions lib/add-class.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,20 @@

// index0-5が小1-6、6が残り常用漢字
const 学年別漢字 = require('./学年別漢字.js')
const {文字参照を文字に} = require('./func')

module.exports = (html, オプション, コールバック) => {
if (typeof html !== 'string') {
throw __filename + ': stringでない入力'
}
if (typeof html !== 'string') throw __filename + ': stringでない入力'
html = html.trim()

if (オプション.debug) {
console.time('#### 解析時間')
console.log()
}

if (オプション.debug) console.time('#### 解析時間')
const cheerio = require('cheerio')
const loadOption = {
decodeEntities: false,
}

// ロードでhtml,head,bodyはどれか無くても自動生成。DOCTYPEは生成されず
// 元からの有無は('body').get().lengthなどでは判定できず
let $ = cheerio.load(html, loadOption)
let $ = cheerio.load(html)
セレクタ文法チェック($)

// 空文字で対象なし(notで全対象)
// cheerio: title下にタグがあっても$('title').find('タグ')は無効
$(オプション.selector).not(オプション.not_selector).find('rb').each((i, element) => {
const rb = $(element).text()
const rb = 文字参照を文字に($(element).text())
let 学年クラス = ''
rb.split('').forEach((漢字) => {
const 常用 = 学年別漢字.find((item, index) => {
Expand All @@ -43,33 +31,19 @@ module.exports = (html, オプション, コールバック) => {
return true
}
})
if (常用 === undefined) {
学年クラス += オプション.add_class + '8 '
}
if (常用 === undefined) 学年クラス += オプション.add_class + '8 '
});
// class="学年4 学年2 学年4"のように重複するが、文字ごとの学年希望
$(element).parent('ruby').addClass(学年クラス)
})

// --css
if (オプション.css !== null) { // 空文字あり
$('head').append('<style>' + オプション.css + '</style>\n')
}

if (オプション.debug) {
console.timeEnd('#### 解析時間')
console.log()
}

// load()やhtml()で<pre><code>内の&lt;なども<に変換、元に戻す
// text()だとその中を検索できず
$('body').find('code').each((i, element) => {
$(element).text($(element).html().replace(/</g, '&lt;').replace(/>/g, '&gt;'))
})
// --css 空文字あり
if (オプション.css !== null) $('head').append('<style>' + オプション.css + '</style>\n')

// --switch
if (オプション.switch) {
const switch_html = ファイル読込(__dirname + '/switch.html')
const fs = require('fs')
const switch_html = fs.readFileSync(__dirname + '/switch.html', 'utf8')
if (オプション.add_class === '学年') {
$('body').prepend(switch_html)
} else {
Expand All @@ -81,49 +55,27 @@ module.exports = (html, オプション, コールバック) => {

let 結果
if (オプション.only_body) {
結果 = $('body').html()
結果 = 文字参照を文字に($('body').html())
} else {
結果 = $.html()
}
if (結果.startsWith('<html')) {
結果 = '<!DOCTYPE html>' + 結果
結果 = 文字参照を文字に($.html())
if (/^<html>/.test(結果.trim())) 結果 = '<!DOCTYPE html>' + 結果
}
if (オプション.末尾改行) 結果 += '\n'

if (オプション.末尾改行) {
コールバック(結果 + '\n')
} else {
コールバック(結果)
}
if (オプション.debug) {console.timeEnd('#### 解析時間'); console.log()}
コールバック(結果)

function セレクタ文法チェック($) {
try {
if (オプション.selector) {
$(オプション.selector)
}
} catch (e) {
console.error('エラー: add-class.js: --selector の文法')
console.error(e)
process.exit(3)
}
if (オプション.selector) $(オプション.selector)
} catch (e) {error('--selector', e)}
try {
if (オプション.not_selector) {
$(オプション.not_selector)
}
} catch (e) {
console.error('エラー: add-class.js: --not-selector の文法')
console.error(e)
if (オプション.not_selector) $(オプション.not_selector)
} catch (e) {error('--not-selector', e)}
function error(opt, e) {
if (オプション.debug) console.error(e)
console.error(`エラー: ${opt}の文法:`)
process.exit(3) // TODO
}
}
}

function ファイル読込(ファイル) {
const fs = require('fs')
try {
return fs.readFileSync(ファイル, 'utf8')
} catch (e) {
console.error('ファイルを開けない: ' + ファイル)
console.error(e)
process.exit(2)
}
}
17 changes: 17 additions & 0 deletions lib/build-kuromoji.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const kuromoji = require('kuromoji')

module.exports = debug => {
return new Promise((resolve, reject) => {
if (debug) console.time('#### ビルド時間')
kuromoji.builder({
dicPath: __dirname + '/../node_modules/kuromoji/dict'
}).build(function(err, _tokenizer) {
if (err) {
console.error('エラー: kuromojiのビルド失敗')
reject(err)
}
if (debug) {console.timeEnd('#### ビルド時間'); console.log()}
resolve(_tokenizer)
})
})
}
16 changes: 16 additions & 0 deletions lib/func.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

module.exports = {
文字参照を文字に: str => {
return str.replace(/&#x[0-9a-fA-F]+;/gm, e => String.fromCharCode(e.replace(/&#/, '0').replace(/;/, '')))
},
ひらがなへ: 文字列 => {
return 文字列.replace(/[ァ-ヴ]/g, (カタカナ) => {
return String.fromCharCode(カタカナ.charCodeAt(0) - 96)
})
},
カタカナへ: 文字列 => {
return 文字列.replace(/[ぁ-ゔ]/g, (ひらがな) => {
return String.fromCharCode(ひらがな.charCodeAt(0) + 96);
});
},
}
2 changes: 1 addition & 1 deletion lib/help.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

const readme = __dirname.slice(0, -3) + 'README.md'
const バージョン = '0.7.3'
const バージョン = '0.8.1'

exports.バージョン = バージョン

Expand Down
128 changes: 32 additions & 96 deletions lib/html.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

'use strict'

const {文字参照を文字に} = require('./func')

/*
* 方針: kuromojiには分割されたテキストを渡し、後で連結。
* まず、$(セレクタ).not(除外セレクタ).each()で要素をまわす。(Cheerio)
Expand All @@ -15,51 +17,19 @@
*/

module.exports = (html, オプション, コールバック) => {
if (typeof html !== 'string') {
throw __filename + ': stringでない入力'
}
if (typeof html !== 'string') throw __filename + ': stringでない入力'
html = html.trim()

const 除外表現 = RegExp('<(ruby|' + オプション.ng_elements + ')[^>]*>[^]*?</(ruby|' + オプション.ng_elements + ')>|<[^>]+>', 'gm')
const ルビ = require('./ruby.js')
const kuromoji = require('kuromoji')
const build = require('./build-kuromoji')

let tokenizer

function kuromojiビルド() {
return new Promise((resolve, reject) => {
if (オプション.debug) {
console.time('#### ビルド時間')
}
kuromoji.builder({
dicPath: __dirname + '/../node_modules/kuromoji/dict'
}).build(function(err, _tokenizer) {
if (err) {
console.error('エラー: html.js: kuromojiのビルド失敗')
reject(err)
}
tokenizer = _tokenizer
if (オプション.debug) {
console.timeEnd('#### ビルド時間') // 1秒くらいかかる
console.log()
}
resolve()
})
})
}

function html解析() {
if (オプション.debug) {
console.time('#### 解析時間')
}
function html解析(_tokenizer) {
tokenizer = _tokenizer
if (オプション.debug) console.time('#### 解析時間')
const cheerio = require('cheerio')
const loadOption = {
decodeEntities: false,
}

// ロードでhtml,head,bodyはどれか無くても自動生成。DOCTYPEは生成されず
// 元からの有無は('body').get().lengthなどでは判定できず
let $ = cheerio.load(html, loadOption)
let $ = cheerio.load(html)
セレクタ文法チェック($)

// 空文字で対象なし(notで全対象)
Expand All @@ -68,7 +38,7 @@ module.exports = (html, オプション, コールバック) => {
if (オプション.debug && オプション.verbose && オプション.verbose.length > 2) {
console.log('__html解析__: ', i, 'tagName:', $(element).get(0).tagName)
}
$(element).html(要素処理($(element).html()))
$(element).html(要素処理($(element).html())) // 再び文字参照になっている
})

// --title
Expand All @@ -80,46 +50,26 @@ module.exports = (html, オプション, コールバック) => {
}
}

// --css
if (オプション.css !== null) { // 空文字あり
$('head').append('<style>' + オプション.css + '</style>\n')
}

if (オプション.debug) {
console.timeEnd('#### 解析時間')
console.log()
}

// load()やhtml()で<pre><code>内の&lt;なども<に変換、元に戻す
// text()だとその中を検索できず
$('body').find('code').each((i, element) => {
$(element).text($(element).html().replace(/</g, '&lt;').replace(/>/g, '&gt;'))
})
if (オプション.comment) {
//結果 += オプション.comment
$('body').append(オプション.comment)
}
// --css 空文字あり
if (オプション.css !== null) $('head').append('<style>' + オプション.css + '</style>\n')
if (オプション.comment) $('body').append('\n<!-- 7d94530980e8645d966033bfa8eca3cd -->\n') // 文字参照対策: 後で置換

// </body>と</html>の間に改行 => body末尾に改行入る
// cheerioの仕様のよう: 他にheadの改行が除かれたりする
let 結果
if (オプション.only_body) {
結果 = $('body').html()
結果 = 文字参照を文字に($('body').html())
} else {
結果 = $.html()
if (/^<html>/.test(結果.trim())) {
結果 = '<!DOCTYPE html>' + 結果
}
結果 = 文字参照を文字に($.html())
if (/^<html>/.test(結果.trim())) 結果 = '<!DOCTYPE html>' + 結果
}
if (オプション.末尾改行) 結果 += '\n'
if (オプション.comment) 結果 = 結果.replace(/^<!-- 7d94530980e8645d966033bfa8eca3cd -->$/m, オプション.comment)

if (オプション.末尾改行) {
コールバック(結果 + '\n')
} else {
コールバック(結果)
}
if (オプション.debug) {console.timeEnd('#### 解析時間'); console.log()}
コールバック(結果)
}

function 要素処理(要素) {
要素 = 文字参照を文字に(要素)
let 要素結果 = ''
let arr
let now = 0
Expand Down Expand Up @@ -147,19 +97,12 @@ module.exports = (html, オプション, コールバック) => {
}

function ルビ付きテキスト(テキスト) {
if (オプション.アリエンティスト) {
テキスト = アリエンティー入れる(テキスト)
}
if (オプション.アリエンティスト) テキスト = アリエンティー入れる(テキスト)
const kuromoji解析json = tokenizer.tokenize(テキスト)
const ruby = new ルビ(テキスト, kuromoji解析json, オプション)
if (オプション.debug) {
ruby.ログ()
}
if (オプション.アリエンティスト) {
return アリエンティー戻す(ruby.ルビ付き)
} else {
return ruby.ルビ付き
}
if (オプション.debug) ruby.ログ()
if (オプション.アリエンティスト) return アリエンティー戻す(ruby.ルビ付き)
return ruby.ルビ付き
}

function アリエンティー入れる(line) {
Expand Down Expand Up @@ -193,21 +136,14 @@ module.exports = (html, オプション, コールバック) => {

function セレクタ文法チェック($) {
try {
if (オプション.selector) {
$(オプション.selector)
}
} catch (e) {
console.error('エラー: html.js: --selector の文法')
console.error(e)
process.exit(3)
}
if (オプション.selector) $(オプション.selector)
} catch (e) {error('--selector', e)}
try {
if (オプション.not_selector) {
$(オプション.not_selector)
}
} catch (e) {
console.error('エラー: html.js: --not-selector の文法')
console.error(e)
if (オプション.not_selector) $(オプション.not_selector)
} catch (e) {error('--not-selector', e)}
function error(opt, e) {
if (オプション.debug) console.error(e)
console.error(`エラー: ${opt}の文法:`)
process.exit(3) // TODO
}
}
Expand All @@ -217,5 +153,5 @@ module.exports = (html, オプション, コールバック) => {
process.exit(4) // TODO
}

kuromojiビルド().then(html解析).catch(失敗)
build(オプション.debug).then(html解析).catch(失敗)
}
Loading

0 comments on commit d5c3c4f

Please sign in to comment.