cbeta 3.8.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fdc6811da84a63c0696ba421fe426e21de327089cfa018cc8ec3252b7981caed
4
- data.tar.gz: 77ee88f62ae4ac35506ca756c7df764a5d35fcf1b2d8ce98a05c578873ef3164
3
+ metadata.gz: 0a8826c19847f81602cd7ca3fb1e976fffc20b98976fde5844134b4672d60e63
4
+ data.tar.gz: 06a2dc151b6623439cca6bbbf4a913fb70c1ac1f6fe8a041e8b052471b08c202
5
5
  SHA512:
6
- metadata.gz: 9d5e52c2087cc1d4c05fb8d0757dd1e1bb8d4e9a42a1d2aeb6c11f3455358d018380a777a7aeed914be3a4474dd12060222fbaa4118bf82fc69e9bf3cab7d26e
7
- data.tar.gz: abb54c0eaa239d7545e02ec957ec0648bc776a3d4c9f27f18a130d7f09164ea9ed0a7fbf9a0cac4480bdf98eec2282f94ef6b737ab8af659e6cd564212ee1755
6
+ metadata.gz: 102a0d53249646d923f2b95c1b5906c23ad6a243b31827e8c663b795448277c1cc4295d9340cdc79f73fc5c29cfc03430c0698cbae69ad4f618d051a0eab8dd4
7
+ data.tar.gz: 48f777330445f72f0e80c8a02c862b05a36e1ba8da6c4509ac81be5a7cab77fed0b71c8dc392b66598f47eaf438e85fe4b44eeb0401e9e6b7571e4ced99501f8
checksums.yaml.gz.sig CHANGED
Binary file
@@ -21,6 +21,7 @@ require_relative 'cbeta_share'
21
21
  # * [E14] <anchor type="right"> 不應直接出現在 div 或 body 下
22
22
  # * [E15] <note> corresp 無對應的 <note>
23
23
  # * [E16] app/@n 與 note/@n 不一致
24
+ # * [E17] list 下沒有任何有內容的 item
24
25
  #
25
26
  # * 警告類型
26
27
  # * [W01] 夾注包夾注
@@ -29,6 +30,9 @@ require_relative 'cbeta_share'
29
30
  class CBETA::P5aChecker
30
31
  ALLOW_TAB = %w[change]
31
32
 
33
+ # 判斷 item 是否有內容時,不計入的元素(本身不產生內容,只是標記位置)
34
+ EMPTY_ELEMENTS = %w[lb pb milestone anchor mulu space]
35
+
32
36
  # @param xml_root [String] 來源 CBETA XML P5a 路徑
33
37
  # @param figures [String] 插圖 路徑 (可由 https://github.com/cbeta-git/CBR2X-figures 取得)
34
38
  # @param log [String] Log file path
@@ -119,6 +123,12 @@ class CBETA::P5aChecker
119
123
  end
120
124
  end
121
125
 
126
+ # 節點是否有內容(文字,或 EMPTY_ELEMENTS 以外的元素)
127
+ def content?(e)
128
+ return true unless e.text.strip.empty?
129
+ e.xpath('.//*').any? { |d| not EMPTY_ELEMENTS.include?(d.name) }
130
+ end
131
+
122
132
  def display_errors
123
133
  @g_errors.keys.sort.each do |k|
124
134
  s = @g_errors[k].to_a.join(',')
@@ -230,6 +240,20 @@ class CBETA::P5aChecker
230
240
  traverse(e)
231
241
  end
232
242
 
243
+ # list 下應該至少有一個 item 是有內容的
244
+ def e_list(e)
245
+ # item 可能包在 app/lem 之類的元素裡,所以用 descendant 找,
246
+ # 但要排除 巢狀 list 底下的 item
247
+ items = e.xpath('.//item').select { |item| nearest_list(item).equal?(e) }
248
+ unless items.any? { |item| content?(item) }
249
+ msg = "[E17] list 下沒有任何有內容的 item"
250
+ head = e.at_xpath('head')
251
+ msg += ", head: #{head.text.gsub(/\s+/, ' ').strip[0, 30]}" unless head.nil?
252
+ error msg
253
+ end
254
+ traverse(e)
255
+ end
256
+
233
257
  def e_note(e)
234
258
  error "[E11] note 直接出現在 div 下" if e.parent.name == 'div'
235
259
  error "[E12] note 直接出現在 lg 下" if e.parent.name == 'lg'
@@ -342,6 +366,7 @@ class CBETA::P5aChecker
342
366
  when 'item' then e_item(e)
343
367
  when 'lb' then e_lb(e)
344
368
  when 'lem' then e_lem(e)
369
+ when 'list' then e_list(e)
345
370
  when 'note' then e_note(e)
346
371
  when 'p' then e_p(e)
347
372
  when 'rdg' then e_rdg(e)
@@ -360,6 +385,13 @@ class CBETA::P5aChecker
360
385
  end
361
386
  end
362
387
 
388
+ # 往上找最近的 list 祖先
389
+ def nearest_list(e)
390
+ r = e.parent
391
+ r = r.parent while r.element? and r.name != 'list'
392
+ r
393
+ end
394
+
363
395
  def read_notes(doc)
364
396
  @notes = Set.new
365
397
  doc.xpath('//note').each do |e|
data/lib/cbeta.rb CHANGED
@@ -312,14 +312,8 @@ require 'cbeta/bm_to_text'
312
312
  require 'cbeta/canon'
313
313
  require 'cbeta/char_count'
314
314
  require 'cbeta/char_freq'
315
- require 'cbeta/html_to_pdf'
316
315
  require 'cbeta/p5a_checker'
317
- require 'cbeta/p5a_to_html'
318
- require 'cbeta/p5a_to_html_for_every_edition'
319
- require 'cbeta/p5a_to_html_for_pdf'
320
- require 'cbeta/p5a_to_simple_html'
321
316
  require 'cbeta/p5a_to_text'
322
317
  require 'cbeta/p5a_validator'
323
- require 'cbeta/html_to_text'
324
318
  require 'cbeta/unicode_service'
325
319
  require 'cbeta/xml_document'
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cbeta
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.8.0
4
+ version: 4.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ray Chou
@@ -109,13 +109,7 @@ files:
109
109
  - lib/cbeta/char_count.rb
110
110
  - lib/cbeta/char_freq.rb
111
111
  - lib/cbeta/gaiji.rb
112
- - lib/cbeta/html_to_pdf.rb
113
- - lib/cbeta/html_to_text.rb
114
112
  - lib/cbeta/p5a_checker.rb
115
- - lib/cbeta/p5a_to_html.rb
116
- - lib/cbeta/p5a_to_html_for_every_edition.rb
117
- - lib/cbeta/p5a_to_html_for_pdf.rb
118
- - lib/cbeta/p5a_to_simple_html.rb
119
113
  - lib/cbeta/p5a_to_text.rb
120
114
  - lib/cbeta/p5a_validator.rb
121
115
  - lib/cbeta/unicode_service.rb
@@ -124,9 +118,6 @@ files:
124
118
  - lib/data/categories.json
125
119
  - lib/data/cbeta_gaiji.json
126
120
  - lib/data/cbeta_sanskrit.json
127
- - lib/data/html-for-pdf.css
128
- - lib/data/pdf-template.htm
129
- - lib/data/unicode-1.1.json
130
121
  homepage: https://github.com/RayCHOU/ruby-cbeta
131
122
  licenses:
132
123
  - MIT
metadata.gz.sig CHANGED
Binary file
@@ -1,75 +0,0 @@
1
- require 'fileutils'
2
-
3
- class CBETA::HTMLToPDF
4
- # @param input [String] folder of source HTML, HTML can be produced by CBETA::P5aToHTMLForPDF.
5
- # @param output [String] output folder
6
- # @param converter [String] shell command to convert HTML to PDF
7
- # * suggestion: http://www.princexml.com/
8
- # * wkhtmltopdf has font problem to display unicode extb characters
9
- #
10
- # @example
11
- # c = CBETA::HTMLToPDF.new('/temp/cbeta-html', '/temp/cbeta-pdf', "prince %{in} -o %{out}")
12
- def initialize(input, output, converter)
13
- @input = input
14
- @output = output
15
- @converter = converter
16
- end
17
-
18
- # Convert CBETA HTML to PDF
19
- #
20
- # @example for convert Taisho (大正藏) Volumn 1:
21
- #
22
- # c = CBETA::HTMLToPDF.new('/PATH/TO/CBETA/XML/P5a', '/OUTPUT/FOLDER')
23
- # c.convert('T01')
24
- #
25
- # @example for convert all in Taisho (大正藏):
26
- #
27
- # c = CBETA::HTMLToPDF.new('/PATH/TO/CBETA/XML/P5a', '/OUTPUT/FOLDER')
28
- # c.convert('T')
29
- #
30
- # @example for convert Taisho Vol. 5~7:
31
- #
32
- # c = CBETA::P5aToHTMLForPDF.new('/PATH/TO/CBETA/XML/P5a', '/OUTPUT/FOLDER')
33
- # c.convert('T05..T07')
34
- #
35
- # T 是大正藏的 ID, CBETA 的藏經 ID 系統請參考: http://www.cbeta.org/format/id.php
36
- def convert(target=nil)
37
- return convert_all if target.nil?
38
-
39
- arg = target.upcase
40
- if arg.size <= 2
41
- convert_collection(arg)
42
- else
43
- if arg.include? '..'
44
- arg.match(/^([^\.]+?)\.\.([^\.]+)$/) {
45
- convert_vols($1, $2)
46
- }
47
- else
48
- convert_vol(arg)
49
- end
50
- end
51
- end
52
-
53
- def convert_collection(c)
54
- @canon = c
55
- puts 'convert_collection ' + c
56
-
57
- output_folder = File.join(@output, @canon)
58
- FileUtils.mkdir_p(output_folder) unless Dir.exist? output_folder
59
-
60
- folder = File.join(@input, @canon)
61
- Dir.foreach(folder) { |f|
62
- next if f.start_with? '.'
63
- src = File.join(folder, f, 'main.htm')
64
- dest = File.join(output_folder, "#{f}.pdf")
65
- convert_file(src, dest)
66
- }
67
- end
68
-
69
- def convert_file(html_fn, pdf_fn)
70
- puts "convert file: #{html_fn} to #{pdf_fn}"
71
- cmd = @converter % { in: html_fn, out: pdf_fn}
72
- `#{cmd}`
73
- end
74
-
75
- end
@@ -1,151 +0,0 @@
1
- require 'fileutils'
2
- require 'nokogiri'
3
-
4
- # 將 CBETA HTML 轉為 純文字(含行首資訊)
5
- #
6
- # Example:
7
- #
8
- # h2t = CBETA::HTMLToText.new('/temp/cbeta-html', '/temp/cbeta-text')
9
- # h2t.convert("T01") # 轉換大正藏第一冊
10
- class CBETA::HTMLToText
11
- # @param html_root [String] 來源 HTML 路徑
12
- # @param out_root [String] 輸出路徑
13
- def initialize(html_root, out_root)
14
- @html_root = html_root
15
- @out_root = out_root
16
- end
17
-
18
- # @param arg [String] 要執行轉換的冊數
19
- # @example
20
- # convert("T01")
21
- def convert(arg)
22
- @dirty = false
23
- @vol = arg.upcase
24
- @corpus = @vol[0]
25
- handle_vol
26
- end
27
-
28
- private
29
-
30
- def traverse(e)
31
- r = ''
32
- e.children.each { |c|
33
- r += handle_node(c)
34
- }
35
- r.gsub(' ', '')
36
- end
37
-
38
- def handle_text(e)
39
- s = e.content().chomp
40
- return '' if s.empty?
41
- s.gsub(/[\n,、—!。:「]/, '')
42
- end
43
-
44
- def handle_span(e)
45
- r = ''
46
- case e['class']
47
- when 'doube-line-note'
48
- r = traverse(e)
49
- unless r.start_with? '('
50
- r = "(#{r})"
51
- end
52
- when 'lb'
53
- if @dirty
54
- r += "\n"
55
- else
56
- @dirty = true
57
- end
58
- # 行首資訊 T05n0220a 改為 T05n0220
59
- lb = e['id'].sub(/^(T0\dn0220)[a-z](.*)$/, '\1\2')
60
- r += lb + '║'
61
- when 'lineInfo'
62
- when 'ranja'
63
- r = '【◇】'
64
- when 'siddam'
65
- r = '【◇】'
66
- when 'star'
67
- else
68
- r = traverse(e)
69
- end
70
- r
71
- end
72
-
73
- def handle_node(e)
74
- return '' if e.comment?
75
- return handle_text(e) if e.text?
76
- r = ''
77
- case e.name
78
- when 'a'
79
- if e['class'] == 'gaijiAnchor'
80
- id = e['href'][1..-1]
81
- r = @gaiji[id]
82
- else
83
- r = traverse(e)
84
- end
85
- when 'div'
86
- if e['id'] != 'back'
87
- r = traverse(e)
88
- end
89
- when 'head'
90
- when 'p'
91
- if e['class'] == 'figure'
92
- r = '【圖】'
93
- else
94
- r = traverse(e)
95
- end
96
- when 'span'
97
- r = handle_span(e)
98
- else
99
- r = traverse(e)
100
- end
101
- r
102
- end
103
-
104
- def prepare_folder()
105
- folder = File.join(@out_root, @corpus, @vol)
106
- FileUtils.remove_dir(folder, true)
107
- FileUtils.mkdir_p(folder)
108
- folder
109
- end
110
-
111
- def handle_file(path)
112
- sutra = File.basename(path, ".*")
113
- sutra.sub!(/^(.*)_.*$/, '\1')
114
- sutra.sub!(/(T\d\dn0220).*$/, '\1') # T0220 BM 沒有分 a, b, c...
115
-
116
- if sutra != @last_sutra
117
- txt_fn = sutra + '.txt'
118
- txt_path = File.join(@folder_out, txt_fn)
119
- puts "h2t #{txt_path}"
120
- @fo = File.open(txt_path, 'w')
121
- @last_sutra = sutra
122
- @dirty = false
123
- end
124
-
125
- f = File.open(path)
126
- doc = Nokogiri::HTML(f)
127
- f.close
128
-
129
- @gaiji = {}
130
- doc.css("span.gaijiInfo").each { |e|
131
- @gaiji[e['id']] = e['zzs']
132
- }
133
-
134
- text = traverse(doc.root)
135
-
136
- # 悉曇字
137
- text.gsub!(/(\((【◇】)+\)|(【◇】)|【◇】)+/, '【◇】')
138
-
139
- @fo.write(text)
140
- end
141
-
142
- def handle_vol()
143
- folder_in = File.join(@html_root, @corpus, @vol)
144
- @folder_out = prepare_folder
145
- @last_sutra = ''
146
- Dir["#{folder_in}/*"].each { |f|
147
- handle_file(f)
148
- }
149
- end
150
-
151
- end