root/lang/ruby/syobodic/proc1.rb @ 26651

Revision 711, 4.9 kB (checked in by gyuque, 6 years ago)

lang/javascript/ruby/syobodic/proc1.rb

Line 
1require 'net/http'
2require 'kconv'
3require 'jcode'
4$KCODE = "UTF8"
5
6$SYOBO_SERVER = "cal.syoboi.jp"
7
8ST_OTHER     = 0
9ST_KANJI     = 1
10ST_KANJIKANA = 2
11
12class SyoboToken
13        attr_reader :type
14        attr_reader :text
15        attr_accessor :kana
16
17        def initialize(text, type)
18                @text = text
19                @type = type
20                @kana = nil
21
22                if type == 0
23                        @kana = text.tr("ァ-ン", "ぁ-ん")
24                        @kana.gsub!("~", "ー")
25                end
26        end
27
28        def to_s
29                "[#{@type} #{@text} #{@kana}]"
30        end
31end
32
33class Splitter
34        attr_reader :toks
35
36        def initialize(t,k)
37                @text = t
38                @kana = k
39
40                @ptext = String.new(t)
41                @pkana = String.new(k)
42                @nponly = false
43                @toks = []
44        end
45
46        def nponly?
47                return @nponly
48        end
49
50        def consumeAll
51                @nponly = true
52                loop do
53                        break if (!consume)
54                end
55        end
56
57        def consume
58                @ptext.gsub!(/^[ぁ-んァ-ヴー\-~☆!?!?・'()a-zA-Z&\s;./]+/, '')
59                if $&
60                        @toks << SyoboToken.new($&, ST_OTHER)
61                        STDERR.puts "  NP  \"#{$&}\"".tosjis
62                        return true
63                end
64
65                @ptext.gsub!(/^[一-龠々〆]{2,}/, '')
66                if $&
67                        @toks << SyoboToken.new($&, ST_KANJI)
68                        @nponly = false
69                        STDERR.puts "  漢  \"#{$&}\"".tosjis
70                        return true
71                end
72
73                @ptext.gsub!(/^[一-龠々〆][ぁ-ん]+/, '')
74                if $&
75                        @toks << SyoboToken.new($&, ST_KANJIKANA)
76                        @nponly = false
77                        STDERR.puts "  和1 \"#{$&}\"".tosjis
78                        return true
79                end
80
81                @ptext.gsub!(/^[一-龠々〆][ぁ-んァ-ヴー]+/, '')
82                if $&
83                        @toks << SyoboToken.new($&, ST_KANJIKANA)
84                        @nponly = false
85                        STDERR.puts "  和2 \"#{$&}\"".tosjis
86                        return true
87                end
88
89                @ptext.gsub!(/^([一-龠々〆])($|\s)/, '')
90                if $&
91                        @toks << SyoboToken.new($1, ST_KANJI)
92                        @nponly = false
93                        STDERR.puts "  単  \"#{$1}\"".tosjis
94                        return true
95                end
96
97                @ptext.gsub!(/^[0-9]+/, '')
98                if $&
99                        @toks << SyoboToken.new($&, ST_OTHER)
100                        @nponly = false
101                        STDERR.puts "  数  \"#{$&}\"".tosjis
102                        return true
103                end
104
105                return false if @ptext.length < 1
106
107                STDERR.puts "  ** WARNING **"
108
109                return false
110        end
111
112        def makeKana
113                @pkana = String.new(@kana)
114
115                @cur = 0
116
117                loop do
118                        break if !processKana
119                end
120        end
121
122        def processKana()
123                nxt = @cur +1
124
125                if toks.length == 1
126                        toks[0].kana = @pkana
127                        return false
128                end
129
130                return false if (!toks[@cur] || !toks[nxt])
131
132                if toks[@cur].type == ST_KANJI
133                        if !toks[nxt].kana
134                                @cur+=1
135                                return true
136                        end
137                        p1 = toks[nxt].kana.gsub(/[^ぁ-んー]/, '').gsub('ー', '[ー\s]')
138                        if @pkana.gsub!(/^([ぁ-んー]+)#{p1}/, '')
139                                toks[@cur].kana = $1
140                        end
141                elsif toks[@cur].type == ST_KANJIKANA
142                        if toks[@cur].text =~ /[ぁ-んァ-ヴー]+/
143                                o = $&.tr("ァ-ン", "ぁ-ん")
144                                if @pkana.gsub!(/^([ぁ-んー]+)#{o}/, '')
145                                        toks[@cur].kana = $1
146                                end
147                        end
148                else
149                        p1 = toks[@cur].kana.gsub(/[^ぁ-んー]/, '[a-zA-Z0-9\s\-]+')
150                        @pkana.gsub!(/#{p1}/, '')
151                end
152
153                @cur += 1
154                return true;
155        end
156end
157
158class SyoboTitle
159        attr_reader :title
160        attr_reader :kana
161        attr_reader :tid
162
163        def read_from_line(ln)
164                ln.chomp!
165                ln.gsub!(/^[ *],/,"")
166
167                ln.gsub!(/^([0-9]+),/, "")
168                raise "cannot read tid" if !($&)
169                @tid = $1.to_i
170
171                ln.gsub!(/^\"([^\"]+)\",/, "")
172                raise "cannot read title" if !($&)
173                @title = $1
174
175                ln.gsub!(/^\"([^\"]+)\",/, "")
176                raise "cannot read kana" if !($&)
177                @kana = $1
178
179                ln.gsub!(/^\"([^\"]+)\"/, "")
180                @abbr = $1
181
182                @abbr = nil if @abbr == ""
183
184        end
185
186        def read_from_web(tid)
187                Net::HTTP.start($SYOBO_SERVER, 80) {|http|
188                    response = http.get("/tid/#{tid}")
189                        raise "request failed: #{response.code}" if response.code.to_i >= 400
190
191                        rbody = response.body
192                        rbody =~ /<h1>([^<]+)<\/h1>/
193                        raise "cannot found h1" if !($&)
194                        @title = $1
195                        @title.gsub!("&amp;","&")
196
197                        rbody =~ /<th>よみ<\/th><td>([^<]+)<\/td>/
198                        raise "cannot found h1" if !($&)
199                        @kana = $1
200
201                        @abbr = nil
202                        rbody =~ /<th>略名<\/th><td>([^<]+)<\/td>/
203                        @abbr = $1 if $&
204
205                        @tid = tid
206                }
207        end
208
209        def print
210                mark = @abbr ? "*" : " "
211                puts "#{mark},#{@tid},\"#{@title}\",\"#{@kana}\",\"#{@abbr}\""
212        end
213end
214
215def makeRawList(tid_from, tid_to)
216        (tid_from..tid_to).each{|tid|
217                begin
218                        t = SyoboTitle.new
219                        t.read_from_web(tid)
220                        t.print
221                rescue
222                        STDERR.puts $!
223                end
224                STDERR.print "."
225                sleep 4
226        }
227end
228
229def dumpSplitTitle(t, splitter)
230        puts "- tid:   #{t.tid}"
231        puts "  title: #{t.title}"
232        puts "  kana:  #{t.kana}"
233        puts "  words:"
234
235        splitter.toks.each{|tk|
236        next if tk.type == 0
237        puts "    - {type: #{tk.type}, text: #{tk.text}, kana: #{tk.kana}}"
238        }
239end
240
241def splitWords(rawlist_fn)
242        list = []
243
244        File.open(rawlist_fn) {|f|
245                f.each {|ln|
246                        STDERR.puts
247
248                        t = SyoboTitle.new
249                        t.read_from_line(ln)
250
251                        s = Splitter.new(t.title, t.kana)
252                        STDERR.puts t.title.tosjis
253                        s.consumeAll
254
255                        next if s.nponly?
256                       
257                        s.makeKana
258                        STDERR.puts s.toks.to_s.tosjis
259                        dumpSplitTitle(t, s)
260                }
261        }
262end
263
264# -----------------------------
265
266if ARGV.length == 1
267        splitWords(ARGV[0])
268else
269        makeRawList(1150, 1250)
270end
Note: See TracBrowser for help on using the browser.