Last active
August 31, 2016 12:10
-
-
Save kakajika/1933bfb367cacf0c3a2939112d7f0a3f to your computer and use it in GitHub Desktop.
Detect ikku script for Hubot.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ikku.coffee | |
# | |
# Description: | |
# Bot for detecting ikku pattern. | |
# | |
{tokenize} = require 'kuromojin' | |
{nfkc} = require 'unorm' | |
haiku_pattern = [5, 7, 5] | |
tanka_pattern = [5, 7, 5, 7, 7] | |
judgeFirstOfPhrase = (token) -> | |
token.pos not in ['助詞', '助動詞'] and token.pos_detail_1 not in ['接尾', '非自立'] | |
splitToRegions = (tokens, pattern) => | |
regions = [ | |
count: 0 | |
text: '' | |
] | |
for token in tokens | |
if regions.length > pattern.length | |
regions = regions.slice(0, pattern.length) | |
break | |
last = regions.length - 1 | |
if token.pos is '記号' or token.surface_form in ['、', '!', '?'] | |
if regions.length < pattern.length and regions[last].count >= pattern[last] | |
regions.push | |
count: 0 | |
text: '' | |
continue | |
pronunciation = token.pronunciation or token.surface_form | |
return [] unless pronunciation.match /^[ぁ-ゔァ-ヺー…]+$/ | |
count = pronunciation.replace(/[ぁぃぅぇぉゃゅょァィゥェォャュョ…]/g, '').length | |
surface = token.surface_form or '' | |
if regions[last].count < pattern[last] or not judgeFirstOfPhrase token | |
regions[last].count += count | |
regions[last].text += surface | |
else | |
regions.push | |
count: count | |
text: surface | |
return regions | |
scanIkku = (tokens, pattern) => | |
regions = splitToRegions tokens, pattern | |
return if regions.length isnt pattern.length | |
return if regions.some (region, i) -> region.count isnt pattern[i] | |
return regions.map (region) => region.text | |
formatText = (text) => | |
return nfkc(text | |
.replace /^<.+?>:?/, '' | |
.replace /^[A-z]+ +/, '' # for DM | |
.replace /[「」()\(\)]/g, ' ' | |
) | |
findIkku = (robot, text, onIkku, onIsshu) => | |
tokenize(formatText text) | |
.then (tokens) => | |
for token, i in tokens | |
targets = tokens.slice(i) | |
isshu = scanIkku targets, tanka_pattern | |
return onIsshu isshu if isshu? | |
ikku = scanIkku targets, haiku_pattern | |
return onIkku ikku if ikku? | |
module.exports = (robot) -> | |
robot.hear /.*?/i, (msg) => | |
findIkku robot, msg.message.text | |
, (ikku) => | |
msg.send "ここで一句 「#{ikku.join(' ')} :white_flower:」" | |
, (isshu) => | |
msg.send "ここで一首 「#{isshu.join(' ')} :white_flower:」" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment