Skip to content

Instantly share code, notes, and snippets.

@kakajika
Last active August 31, 2016 12:10
Show Gist options
  • Save kakajika/1933bfb367cacf0c3a2939112d7f0a3f to your computer and use it in GitHub Desktop.
Save kakajika/1933bfb367cacf0c3a2939112d7f0a3f to your computer and use it in GitHub Desktop.
Detect ikku script for Hubot.
# 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