html2slim2 0.3.1 → 0.4.1

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: a545d55f7ec6dd7f97e609446fa01d6da140a689d51b6be921b4c15c8b6667f4
4
- data.tar.gz: 6e5e6b61b863f62c1a88f97e9ae588f8bc766159fcff347eae98a44157a9892b
3
+ metadata.gz: c977c64c4721d5124549f9a03ee27cd5c889adcb238f2e91fb74cd0d967d636e
4
+ data.tar.gz: 7e46a4be4a7aa50210b838248a63165f5d3a5b0e9db3da6e06df580016749894
5
5
  SHA512:
6
- metadata.gz: 196406fc4f69748e6bea1e0743b3a5171dd90e015d7d13026b8466999d55f0ad37d3d2279801d49df7a4a30f81be7107118b3c76d3f4a2c3690066bc4c2327f3
7
- data.tar.gz: d1344a4283b17bfdd8b1dd5a6844e4769b731a63aa5ed3faed6e8c587fb89a92748b5e65a51ba9368f784846f2e7ab2aa52f64cddb6d2f4fa200d24d0e27e526
6
+ metadata.gz: 5dafebc8d2f963272afee508511c50ffbef82ca550980efd12bd0e97502b6eab1e1dd130788fb1214f76d3bc9350d4e63436489cdf4678e16e7d0d62ae874abd
7
+ data.tar.gz: 10250ab3f587a3c17ea9014684541b916d15529653aac5276e922f1e93fe221f36e550685cba6f27e878ea5a8dcbe0c3244bd0e812795f6dd9cb3136d869ee5f
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # HTML2Slim2
2
2
 
3
- ![Version](https://img.shields.io/gem/v/html2slim2.svg)
3
+ [![Gem Version](https://badge.fury.io/rb/html2slim2.svg)](https://badge.fury.io/rb/html2slim2)
4
4
 
5
5
  <!--
6
6
  [![Build Status](https://travis-ci.org/slim-template/html2slim.png?branch=master)](https://travis-ci.org/slim-template/html2slim)
@@ -8,7 +8,7 @@
8
8
  [![Code climate](https://codeclimate.com/github/slim-template/html2slim.png)](https://codeclimate.com/github/slim-template/html2slim)
9
9
  -->
10
10
 
11
- Script for converting HTML and ERB files to [slim](http://slim-lang.com/).
11
+ Script for converting HTML and ERB files to [slim](http://slim-template.github.io/).
12
12
 
13
13
  ## Usage
14
14
 
@@ -42,7 +42,7 @@ This project is released under the MIT license.
42
42
 
43
43
  ## Maintained repo
44
44
 
45
- [https://github.com/sanadan/html2slim](https://github.com/sanadan/html2slim)
45
+ [https://github.com/sanadan/html2slim2](https://github.com/sanadan/html2slim2)
46
46
 
47
47
  ## OFFICIAL REPO
48
48
 
data/bin/erb2slim2 ADDED
@@ -0,0 +1 @@
1
+ erb2slim
data/bin/html2slim2 ADDED
@@ -0,0 +1 @@
1
+ html2slim
@@ -44,7 +44,7 @@ module HTML2Slim2
44
44
  end
45
45
 
46
46
  opts.on_tail('-v', '--version', 'Print version') do
47
- puts "#{command_name} #{HTML2Slim::VERSION}"
47
+ puts "#{command_name} #{HTML2Slim2::VERSION}"
48
48
  exit
49
49
  end
50
50
 
@@ -1,8 +1,15 @@
1
+ module HTML2Slim2
2
+ MULTILINE_ATTR_MARKER = 'html2slim2-multiline'
3
+ end
4
+
1
5
  require_relative 'nokogiri_monkey_patches'
2
6
 
3
7
  module HTML2Slim2
4
8
  class Converter
9
+ OPENING_TAG_RE = /<([A-Za-z][A-Za-z0-9:-]*)((?:[^>"']|"[^"]*"|'[^']*')*)(\/?)>/m
10
+
5
11
  def initialize(html)
12
+ html = mark_multiline_opening_tags(html)
6
13
  nokogiri = html[..1] == '<!' ? Nokogiri.parse(html) : Nokogiri::HTML.fragment(html)
7
14
  @slim = nokogiri.to_slim
8
15
  end
@@ -10,6 +17,19 @@ module HTML2Slim2
10
17
  def to_s
11
18
  @slim
12
19
  end
20
+
21
+ private
22
+
23
+ def mark_multiline_opening_tags(html)
24
+ html.gsub(OPENING_TAG_RE) do |match|
25
+ attrs = Regexp.last_match[2]
26
+ next match unless attrs.include?("\n")
27
+
28
+ name = Regexp.last_match[1]
29
+ slash = Regexp.last_match[3]
30
+ %(<#{name}#{attrs} #{MULTILINE_ATTR_MARKER}="1"#{slash}>)
31
+ end
32
+ end
13
33
  end
14
34
 
15
35
  class HTMLConverter < Converter
@@ -5,7 +5,15 @@ class Nokogiri::XML::Text
5
5
  str = escape(content)
6
6
  return nil if str.strip.empty?
7
7
 
8
- (' ' * lvl) + %(| #{str.gsub(/\s+/, ' ')})
8
+ # A lone text line with no indentation is content, not HTML formatting space.
9
+ # "\na\n" → "| a" (not "| a ")
10
+ normalized = if str.match?(/\A\n+\S/) && str.match?(/\S\n+\z/)
11
+ str.strip.gsub(/\s+/, ' ')
12
+ else
13
+ str.gsub(/\s+/, ' ')
14
+ end
15
+
16
+ (' ' * lvl) + %(| #{normalized})
9
17
  end
10
18
 
11
19
  private
@@ -39,14 +47,15 @@ class Nokogiri::XML::Element
39
47
  BLANK_RE = /\A[[:space:]]*\z/.freeze
40
48
 
41
49
  def slim(lvl = 0)
42
- r = ' ' * lvl
50
+ indent = ' ' * lvl
43
51
 
44
- return r + slim_ruby_code(r) if ruby?
52
+ return indent + slim_ruby_code(indent) if ruby?
45
53
 
54
+ r = indent
46
55
  r += name unless skip_tag_name?
47
56
  r += slim_id
48
57
  r += slim_class
49
- r += slim_attributes
58
+ r += slim_attributes(indent)
50
59
  r
51
60
  end
52
61
 
@@ -54,7 +63,10 @@ class Nokogiri::XML::Element
54
63
  if children.any?
55
64
  %(#{slim(lvl)}\n#{children.filter_map { |c| c.to_slim(lvl + 1) }.join("\n")})
56
65
  else
57
- slim(lvl)
66
+ r = slim(lvl)
67
+ # Empty multiline tags still end with a newline so sibling spacing
68
+ # matches tags that only contained ignorable whitespace.
69
+ r.include?("\n") ? "#{r}\n" : r
58
70
  end
59
71
  end
60
72
 
@@ -80,10 +92,33 @@ class Nokogiri::XML::Element
80
92
  has_class? ? ".#{self['class'].to_s.strip.split(/\s+/).join('.')}" : ''
81
93
  end
82
94
 
83
- def slim_attributes
95
+ def slim_attributes(indent = '')
96
+ multiline = has_attribute?(HTML2Slim2::MULTILINE_ATTR_MARKER)
97
+ remove_attribute(HTML2Slim2::MULTILINE_ATTR_MARKER)
84
98
  remove_attribute('class')
85
99
  remove_attribute('id')
86
- has_attributes? ? "[#{attributes_as_html.to_s.strip}]" : ''
100
+ return '' unless has_attributes?
101
+
102
+ if multiline && multiline_attribute_output?
103
+ slim_multiline_attributes(indent)
104
+ else
105
+ "[#{attributes_as_html.to_s.strip}]"
106
+ end
107
+ end
108
+
109
+ def multiline_attribute_output?
110
+ attrs = attributes.to_hash
111
+ attrs.size > 1 || attrs.values.any? { |value| value.to_s.include?("\n") }
112
+ end
113
+
114
+ def slim_multiline_attributes(indent)
115
+ parts = attributes.map do |attr_name, attr_val|
116
+ attr_val ? "#{attr_name}=#{html_quote attr_val.to_s}" : attr_name.to_s
117
+ end
118
+ return "[#{parts.first}]" if parts.size <= 1
119
+
120
+ inner_indent = "#{indent} "
121
+ "[\n#{parts.map { |part| "#{inner_indent}#{part}" }.join("\n")}\n#{indent}]"
87
122
  end
88
123
 
89
124
  def has_attributes? # rubocop:disable Naming/PredicatePrefix
@@ -1,3 +1,3 @@
1
1
  module HTML2Slim2
2
- VERSION = '0.3.1'
2
+ VERSION = '0.4.1'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: html2slim2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - sanadan
8
8
  - Maiz Lulkin
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-02-09 00:00:00.000000000 Z
11
+ date: 2026-09-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -31,14 +31,18 @@ email:
31
31
  - maiz@lulk.in
32
32
  executables:
33
33
  - erb2slim
34
+ - erb2slim2
34
35
  - html2slim
36
+ - html2slim2
35
37
  extensions: []
36
38
  extra_rdoc_files:
37
39
  - README.md
38
40
  files:
39
41
  - README.md
40
42
  - bin/erb2slim
43
+ - bin/erb2slim2
41
44
  - bin/html2slim
45
+ - bin/html2slim2
42
46
  - lib/html2slim2.rb
43
47
  - lib/html2slim2/command.rb
44
48
  - lib/html2slim2/converter.rb
@@ -58,14 +62,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
58
62
  requirements:
59
63
  - - ">="
60
64
  - !ruby/object:Gem::Version
61
- version: '3.2'
65
+ version: '3.3'
62
66
  required_rubygems_version: !ruby/object:Gem::Requirement
63
67
  requirements:
64
68
  - - ">="
65
69
  - !ruby/object:Gem::Version
66
70
  version: '0'
67
71
  requirements: []
68
- rubygems_version: 4.0.3
72
+ rubygems_version: 4.0.20
69
73
  specification_version: 4
70
74
  summary: HTML to Slim converter.
71
75
  test_files: []