hitomalu_formatter 0.1.1 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 45ac48979e4805892091a1a54d1495dca54c3e005d4388f7807749a4a8931600
4
- data.tar.gz: 285d4394fe935dcf155c2f1796fcc5125afcb1401599f6b355ebdbbede946a8c
3
+ metadata.gz: f2205cbc4188517f6f9f1743c907390dab1d22a505039ccd0776b1fcabe085b4
4
+ data.tar.gz: 486f9f4da2bedef501e596e1400911e95e8ead7bd5439d9ef4483d1d48432c73
5
5
  SHA512:
6
- metadata.gz: 4a62c118963f1a22fbb155e8588b6053700e7306b8f64f904543f077106b5e717f476eb513f66db1b615dfdfdab5101005a11b23ccd43bec5018081381788f67
7
- data.tar.gz: 706d000b7ee94dc0d077834ed39a5b1ca480260b490aea8f0759f0fdc2fb43fa76fb8c723e4a5fb9185c269c40a63e6fdf70ff181c93377e09a23b6657a7c251
6
+ metadata.gz: 7b2db08c7bf066cf66c029acc290e0e6b1a9be69fba58f710a40287851dd9bdfc81738604ee9e2879e6859cef9de57fc28d9ebbd4e7da1255bb4143ddf446de7
7
+ data.tar.gz: 392bfe6ed8438a46a924cb3cf72c820d4c36c067cbaa15769798c8fff640325f253bf777ce404e72c64d3f9afb1bc9b152abc75e1a23b601639e0e754c9a8234
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.1.4] - 2022-08-16
4
+ ## [0.1.3] - 2022-08-04
5
+ ## [0.1.2] - 2022-08-03
6
+
7
+ - a little fix
8
+
3
9
  ## [0.1.1] - 2022-07-30
4
10
 
5
11
  - Initial release
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- hitomalu_formatter (0.1.1)
4
+ hitomalu_formatter (0.1.4)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -6,7 +6,15 @@ module Hitomalu
6
6
 
7
7
  # cf. https://developer.mozilla.org/ja/docs/Web/HTML/Inline_elements
8
8
  # rp と rt は上に記載がないが、改行させたくないので追加
9
- INLINE_TAGS = [ 'a', 'abbr', 'acronym', 'audio', 'b', 'bdi', 'bdo', 'big', 'br', 'button', 'canvas', 'cite', 'code', 'data', 'datalist', 'del', 'dfn', 'em', 'embed', 'i', 'iframe', 'img', 'input', 'ins', 'kbd', 'label', 'map', 'mark', 'meter', 'noscript', 'object', 'output', 'picture', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'script', 'select', 'slot', 'small', 'span', 'strong', 'sub', 'sup', 'svg', 'template', 'textarea', 'time', 'u', 'tt', 'var', 'video', 'wbr' ]
9
+ # node.name 'comment' であるコメントノードもインライン扱い
10
+ INLINE_TAGS = [ 'a', 'abbr', 'acronym', 'audio', 'b', 'bdi', 'bdo', 'big', 'br', 'button', 'canvas', 'cite', 'code', 'comment', 'data', 'datalist', 'del', 'dfn', 'em', 'embed', 'i', 'iframe', 'img', 'input', 'ins', 'kbd', 'label', 'map', 'mark', 'meter', 'nobr', 'noscript', 'object', 'output', 'picture', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'script', 'select', 'slot', 'small', 'span', 'strong', 'sub', 'sup', 'svg', 'template', 'text', 'textarea', 'time', 'u', 'tt', 'var', 'video', 'wbr' ]
11
+ INLINE_TAGS_REGEXP = INLINE_TAGS.join('|')
12
+
13
+ ADD_BREAK_LINE_TAGS = [ 'br', 'hr', 'col' ]
14
+ ADD_BREAK_LINE_TAGS_REGEXP = ADD_BREAK_LINE_TAGS.join('|')
15
+
16
+ # フォーマットで改行が増えないタグ (改行が増えるタグで改行増殖を抑えるために使う)
17
+ BREAK_LINE_NOT_INCREASE_TAGS = INLINE_TAGS - ADD_BREAK_LINE_TAGS
10
18
 
11
19
  def self.format(html)
12
20
  # 改行コード \n を \r\n に統一しておく
@@ -21,17 +29,29 @@ module Hitomalu
21
29
  body = doc.at_css('body')
22
30
 
23
31
  body.traverse { |node|
32
+ # テキストノードが空白文字以外を含み、親が非インライン要素(=ブロックノード)でもpreでもないならば中身の先頭と最後のスペースを消す
33
+ # (親のブロック要素に接しているところ = 兄弟がいない方向のみ)
34
+ if node.instance_of?(Nokogiri::XML::Text) && /\S/.match(node.content) && !(INLINE_TAGS + CONTENT_NO_MODIFY_TAGS).include?(node.parent.name)
35
+ if node.previous_sibling.nil?
36
+ node.content = node.content.gsub(/(\A\s+)/, "")
37
+ end
38
+ if node.next_sibling.nil?
39
+ node.content = node.content.gsub(/(\s+\Z)/, "")
40
+ end
41
+ end
42
+
43
+
24
44
  # 中身がないと、li などの閉じタグ省略可能なタグについてNokogiriが閉じタグ省略を行い、整形をかけるたびに閉じタグがついたりなくなったりするので、
25
45
  # 中身がないかスペースだけの場合、仮文字列にして最後に空文字列に置換する
26
- # ただし、 <img src="1.jpg"> <img src="2.jpg"> のようなインライン要素の間のスペースと改行は保持する必要があるので保持する。
27
46
  # <li></li> の中に |mykaramojiretsu| を入れるために + ではなく * が必要
28
- if /\A[ ]*\Z/.match?(node.content) && (node.previous_sibling.nil? || !INLINE_TAGS.include?(node.previous_sibling.name))
29
- node.content = "|mykaramojiretsu|"
47
+ if /\A[ ]*\Z/.match?(node.content)
48
+ node.content = node.content + "|mykaramojiretsu|"
30
49
  end
31
50
 
32
51
  # インライン要素は、ブロック内先頭やテキストノードやインライン要素の次では改行しない
33
52
  # (前がブロック要素の終わりやコメントノードだと改行する)
34
- if INLINE_TAGS.include?(node.name) && (node.previous_sibling.nil? || (node.previous_sibling.instance_of?(Nokogiri::XML::Text) || INLINE_TAGS.include?(node.previous_sibling.name)))
53
+ # (前が最後に改行を足すタグの場合、|nobreakline| を足すとスペースが増えて、フォーマットをかける度に結果が変わるので、|nobreakline| を足しません)
54
+ if INLINE_TAGS.include?(node.name) && (node.previous_sibling.nil? || (INLINE_TAGS.include?(node.previous_sibling.name) && !ADD_BREAK_LINE_TAGS.include?(node.previous_sibling.name)))
35
55
  node.add_previous_sibling("|nobreakline|")
36
56
  end
37
57
 
@@ -53,9 +73,24 @@ module Hitomalu
53
73
  node.next_sibling.content = "|mykaigyo|"
54
74
  end
55
75
 
76
+ # この下の処理で先頭改行をスペースに置換している & ブロック要素閉じタグの後には改行を入れる処理の関係上、
77
+ # </summary>\r\nnakami のような ブロック要素閉じタグ直後に改行が来ている場合、スペースが増殖してしまう (= 2回フォーマットをかけると結果が変わってしまう)
78
+ # それを防ぐため、ブロック要素閉じタグ直後の場合は先頭の改行を削除する
79
+ if node.instance_of?(Nokogiri::XML::Text) && !node.previous_sibling.nil? && !BREAK_LINE_NOT_INCREASE_TAGS.include?(node.previous_sibling.name) && !CONTENT_NO_MODIFY_TAGS.include?(node.parent.name)
80
+ node.content = node.content.gsub(/\A *(\r\n|\n)*/, "")
81
+ end
82
+
83
+ # 上の事を、直後がブロック要素開始タグの場合にも末尾の改行についてする
84
+ if node.instance_of?(Nokogiri::XML::Text) && !node.next_sibling.nil? && !BREAK_LINE_NOT_INCREASE_TAGS.include?(node.next_sibling.name) && !CONTENT_NO_MODIFY_TAGS.include?(node.parent.name)
85
+ node.content = node.content.gsub(/ *(\r\n|\n)*\Z/, "")
86
+ end
87
+
56
88
  # タグの中身を整形する(見やすくするため)
89
+ # 英文など、スペースが重要な言語があるので、stripはしない (Hello <a href="#world">world</a> のような文でスペースが、stripで無くなってしまう)
90
+ # \r\n を 2文字で1つのもの扱いにするため \s ではなく () で列挙している
91
+ # 連続する改行・スペースをスペース1つにし、先頭と最後の改行・スペースを除去し、文中の改行を除去する
57
92
  if node.instance_of?(Nokogiri::XML::Text) && !CONTENT_NO_MODIFY_TAGS.include?(node.parent.name)
58
- node.content = node.content.strip.gsub(/\s{2,}/, " ")
93
+ node.content = node.content.gsub(/(\r\n|\n| |\t|\f){2,}/, " ").gsub(/(\A ?(\r\n|\n) ?| ?(\r\n|\n) ?\Z)/, " ").gsub("\r\n", " ")
59
94
  end
60
95
 
61
96
  # 閉じタグとテキストノードの間に改行がなければ入れる(見やすくするため)
@@ -72,19 +107,20 @@ module Hitomalu
72
107
  body_str = body.to_s.gsub(/(\|mykaigyo\|)+/, "\r\n").gsub('|myspace|', ' ').gsub(/(<\/wbr>|\|mykaramojiretsu\||\A<body>(\n|\r\n)*|(\n|\r\n)*<\/body>\Z)/, "").gsub(/(?<!\r)\n/, "\r\n")
73
108
 
74
109
  # </span></div> のような閉じタグの間に改行が無かったら改行を入れる (Nokogiri の add_next_sibling は 20000回するとメモリを6GB以上使うので文字列処理でやる)
75
- # ただし、</ruby>の前には入れない(</rp>などの短いインライン要素が来るため)
110
+ # ただし、片方または両方がインライン要素の閉じタグだったら入れない
76
111
  prev_str = ""
77
112
  while body_str != prev_str do
78
113
  prev_str = body_str
79
- body_str = body_str.gsub(/(<\/[a-z]+>)(<\/(?!ruby))/, "\\1\r\n\\2")
114
+ body_str = body_str.gsub(/(<\/(?!(#{INLINE_TAGS_REGEXP}))[a-z]+>)(<\/(?!(#{INLINE_TAGS_REGEXP}))[a-z]+>)/, "\\1\r\n\\3")
80
115
  end
81
116
 
82
117
  # 開始タグの前に改行がなければ改行を入れる (add_prev_sibling は重いので文字列処理でやる) (文章の先頭からは消す)
83
118
  # その後、使い終わった改行しない印を消す
84
- body_str = body_str.gsub(/(?<!\r\n)(?<!\|nobreakline\|)(?<!\|nobreakline\| )<(?!\/)/, "\r\n<").gsub(/(\A\r\n|\|nobreakline\|)/, "")
119
+ # また、閉じタグしか無い行の先頭のスペースを消す (閉じタグで改行されるのはブロック要素の閉じタグだけであるため、pre以外ならスペースを消して問題ない)
120
+ body_str = body_str.gsub(/(?<!\r\n)(?<!\|nobreakline\|)(?<!\|nobreakline\| )<(?!\/)/, "\r\n<").gsub(/(\A\r\n|\|nobreakline\|)/, "").gsub(/^ *(?!<\/pre>)(<\/[a-z]+>)$/, "\\1")
85
121
 
86
122
  # <br> や <hr> や <col> の後ろに改行がなければ改行を入れる (add_next_sibling は重いので文字列処理でやる)
87
- body_str = body_str.gsub(/(<(?:br|hr|col)>)(?!\r\n)/, "\\1\r\n")
123
+ body_str = body_str.gsub(/(<(?:#{ADD_BREAK_LINE_TAGS_REGEXP})>)(?!\r\n)/, "\\1\r\n")
88
124
  end
89
125
  end
90
126
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HitomaluFormatter
4
- VERSION = "0.1.1"
4
+ VERSION = "0.1.4"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hitomalu_formatter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - t-hazawa
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-07-30 00:00:00.000000000 Z
11
+ date: 2022-08-15 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email: []