rtlize-2 1.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 884272fe01dab544c72d86df4ea20244d451288d8ae579b9bae1c70cffb8bff6
4
+ data.tar.gz: e0d12af5c26c6d21810549cb2f63b91a4b5b272c49b266f95bee1de5373ca216
5
+ SHA512:
6
+ metadata.gz: 9be72cfe6fc05eab6b89c6116cd1522f8fb0e0bd623716fb4a2aa621f5e898ba3426ff9700ccc62ef3d2c30f0d5909aadc18ec0e86bcaa6467f02e22038ce403
7
+ data.tar.gz: '00778d679fda8ef300be52b36304e11b08cd80d36315681f86b89ef409f3a12a78f10ac27849f9f24e7add26e59ffea511b43cafcf3fa9f4d323f130cbc0e2d9'
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2014 Marwan Al Jubeh
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,167 @@
1
+ # RTLize
2
+
3
+ [![Build Status](https://github.com/fadynaffa3/RTLize/actions/workflows/ci.yml/badge.svg)](https://github.com/fadynaffa3/RTLize/actions)
4
+
5
+ RTLize allows you to write your stylesheets for left-to-right (LTR) layouts and have them automatically work for right-to-left (RTL) layouts as well. It does this by mirroring all the properties and values to their RTL equivalent.
6
+
7
+ RTLize doesn't depend on any other gem and doesn't tie you down to Rails or any other framework. However, it does work with Rails & Sprockets out of the box, and you can hook it up manually if you use a different stack.
8
+
9
+ ## Requirements
10
+
11
+ - Ruby >= 4.0.0
12
+ - Rails >= 7.0 (optional — works standalone too)
13
+ - Sprockets 4.x (when used with Rails)
14
+
15
+ ## Installation
16
+
17
+ Add it to your Gemfile:
18
+
19
+ ```ruby
20
+ gem 'rtlize'
21
+ ```
22
+
23
+ Then run:
24
+
25
+ ```bash
26
+ bundle install
27
+ ```
28
+
29
+ ## Using RTLize from the Command Line
30
+
31
+ Install the gem:
32
+
33
+ ```bash
34
+ gem install rtlize
35
+ ```
36
+
37
+ Then use the `rtlize` command to flip your LTR stylesheets to RTL (or vice versa):
38
+
39
+ ```bash
40
+ rtlize application.css application.rtl.css
41
+ ```
42
+
43
+ For help:
44
+
45
+ ```bash
46
+ rtlize -h
47
+ ```
48
+
49
+ ## Using RTLize with Rails
50
+
51
+ ### 1. Create symlinks for your RTL stylesheets
52
+
53
+ Create symbolic links of your stylesheets with `.css` replaced by `.rtl.css`:
54
+
55
+ ```bash
56
+ ln -s sheet1.css sheet1.rtl.css
57
+ ln -s sheet2.css.scss sheet2.rtl.css.scss
58
+ ln -s sheet3.css.erb sheet3.rtl.css.erb
59
+ ```
60
+
61
+ ### 2. Declare them in your Sprockets manifest
62
+
63
+ In `app/assets/config/manifest.js`, explicitly link your RTL assets:
64
+
65
+ ```js
66
+ //= link application.css
67
+ //= link application.rtl.css
68
+ //= link sheet2.css
69
+ //= link sheet2.rtl.css
70
+ ```
71
+
72
+ ### 3. Set the `dir` attribute on your HTML element
73
+
74
+ ```erb
75
+ <html lang="<%= I18n.locale %>" dir="<%= Rtlize.dir %>">
76
+ ```
77
+
78
+ `Rtlize.dir` returns `'rtl'` when the current locale is in the RTL locales list (`:ar`, `:fa`, `:he`, `:ur` by default), and `'ltr'` otherwise.
79
+
80
+ Now when you request `sheet1.rtl.css`, you receive an RTLized version of `sheet1.css`.
81
+
82
+ ## Configuration
83
+
84
+ In `config/application.rb` or an initializer:
85
+
86
+ ```ruby
87
+ # Default: "[dir=rtl]"
88
+ config.rtlize.rtl_selector = "[dir=rtl]"
89
+
90
+ # Default: [:ar, :fa, :he, :ur]
91
+ config.rtlize.rtl_locales = [:ar, :fa, :he, :ur]
92
+ ```
93
+
94
+ ## Manually Overriding CSS
95
+
96
+ RTLize won't transform any CSS rules whose selector contains the `rtl_selector`. Use this to write RTL-specific overrides:
97
+
98
+ ```css
99
+ /* This will be transformed: margin becomes "1px 4px 3px 2px" */
100
+ .class-1 {
101
+ margin: 1px 2px 3px 4px;
102
+ }
103
+
104
+ /* These will NOT be transformed — they already target RTL */
105
+ [dir=rtl] .class-2 { margin-right: 2px; }
106
+ [dir="rtl"] .class-3 { margin-right: 3px; }
107
+ [dir='rtl'].class-4 { margin-right: 4px; }
108
+ ```
109
+
110
+ ## Preventing Sections from Being Transformed
111
+
112
+ Use the `no-rtl` directive to exclude blocks of CSS:
113
+
114
+ ```css
115
+ /* This will be transformed */
116
+ .top-level-class .child-1 {
117
+ margin-left: 1px;
118
+ }
119
+
120
+ /*!= begin(no-rtl) */
121
+ /* This will NOT be transformed */
122
+ .top-level-class .child-2 {
123
+ float: left;
124
+ }
125
+ /*!= end(no-rtl) */
126
+
127
+ /* This will be transformed again */
128
+ .another-class span {
129
+ padding-right: 5px;
130
+ }
131
+ ```
132
+
133
+ > **Note:** The `!` in the comment is required so CSS compressors don't strip the directive before RTLize sees it. In SCSS/Sass you may need `!!` (e.g. `/*!!= begin(no-rtl) */`). Only use these directives at the top level of your CSS — not inside nested rules.
134
+
135
+ ## Rails Admin
136
+
137
+ RTLize works with [rails_admin](https://github.com/railsadminteam/rails_admin). Add a symlink for the rails_admin stylesheet and link it in your manifest:
138
+
139
+ ```bash
140
+ ln -s rails_admin/application.css rails_admin/application.rtl.css
141
+ ```
142
+
143
+ In `app/assets/config/manifest.js`:
144
+
145
+ ```js
146
+ //= link rails_admin/application.rtl.css
147
+ ```
148
+
149
+ Then in your rails_admin layout or initializer, switch the stylesheet based on locale:
150
+
151
+ ```erb
152
+ <html dir="<%= Rtlize.dir %>">
153
+ ```
154
+
155
+ ## Versioning
156
+
157
+ This gem follows [Semantic Versioning](https://semver.org).
158
+
159
+ ## Credits
160
+
161
+ Maintained by [Fady Naffa](https://github.com/fadynaffa3).
162
+
163
+ Originally inspired by [Dustin Diaz's R2](https://github.com/ded/R2).
164
+
165
+ ## License
166
+
167
+ RTLize is released under the [MIT License](MIT-LICENSE).
data/Rakefile ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+
8
+
9
+
10
+
11
+ Bundler::GemHelper.install_tasks
12
+
13
+ require 'rake/testtask'
14
+
15
+ Rake::TestTask.new(:test) do |t|
16
+ t.libs << 'lib'
17
+ t.libs << 'test'
18
+ t.pattern = 'test/**/*_test.rb'
19
+ t.verbose = false
20
+ end
21
+
22
+
23
+ task :default => :test
24
+
25
+ desc "Delete the latest tag"
26
+ task :delete_tag do
27
+ system "git tag -d v#{Rtlize::VERSION}"
28
+ system "git push origin :refs/tags/v#{Rtlize::VERSION}"
29
+ end
data/bin/rtlize ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.expand_path("../../lib", __FILE__)
3
+
4
+ require 'rtlize'
5
+ require 'rtlize/exec'
6
+
7
+ opts = Rtlize::Exec.new(ARGV)
8
+ opts.parse!
@@ -0,0 +1,178 @@
1
+ module Rtlize
2
+ class Declaration
3
+ @property_map = {
4
+ 'margin-left' => 'margin-right',
5
+ 'margin-right' => 'margin-left',
6
+
7
+ 'padding-left' => 'padding-right',
8
+ 'padding-right' => 'padding-left',
9
+
10
+ 'border-left' => 'border-right',
11
+ 'border-right' => 'border-left',
12
+
13
+ 'border-left-width' => 'border-right-width',
14
+ 'border-right-width' => 'border-left-width',
15
+
16
+ 'border-left-style' => 'border-right-style',
17
+ 'border-right-style' => 'border-left-style',
18
+
19
+ 'border-left-color' => 'border-right-color',
20
+ 'border-right-color' => 'border-left-color',
21
+
22
+ 'border-bottom-right-radius' => 'border-bottom-left-radius',
23
+ 'border-bottom-left-radius' => 'border-bottom-right-radius',
24
+ '-webkit-border-bottom-right-radius' => '-webkit-border-bottom-left-radius',
25
+ '-webkit-border-bottom-left-radius' => '-webkit-border-bottom-right-radius',
26
+ '-moz-border-radius-bottomright' => '-moz-border-radius-bottomleft',
27
+ '-moz-border-radius-bottomleft' => '-moz-border-radius-bottomright',
28
+
29
+ 'border-top-right-radius' => 'border-top-left-radius',
30
+ 'border-top-left-radius' => 'border-top-right-radius',
31
+ '-webkit-border-top-right-radius' => '-webkit-border-top-left-radius',
32
+ '-webkit-border-top-left-radius' => '-webkit-border-top-right-radius',
33
+ '-moz-border-radius-topright' => '-moz-border-radius-topleft',
34
+ '-moz-border-radius-topleft' => '-moz-border-radius-topright',
35
+
36
+ 'left' => 'right',
37
+ 'right' => 'left',
38
+ }
39
+
40
+ @value_map = {
41
+ 'border-color' => :quad,
42
+ 'border-style' => :quad,
43
+ 'border-width' => :quad,
44
+ 'padding' => :quad,
45
+ 'margin' => :quad,
46
+ 'clip' => :rect,
47
+ 'cursor' => :cursor,
48
+ 'text-align' => :rtltr,
49
+ 'float' => :rtltr,
50
+ 'clear' => :rtltr,
51
+ 'direction' => :direction,
52
+ 'border-radius' => :quad_radius,
53
+ '-webkit-border-radius' => :quad_radius,
54
+ '-moz-border-radius' => :quad_radius,
55
+ 'box-shadow' => :shadow,
56
+ '-webkit-box-shadow' => :shadow,
57
+ '-moz-box-shadow' => :shadow,
58
+ 'text-shadow' => :shadow,
59
+ '-webkit-text-shadow' => :shadow,
60
+ '-moz-text-shadow' => :shadow,
61
+ 'rotation' => :deg,
62
+ }
63
+
64
+ class << self
65
+ def transform(property, value)
66
+ # Get the property, without comments or spaces, to be able to find it.
67
+ property_name = property.strip.split(' ').last.gsub(/^[*_]/, '')
68
+ if @property_map[property_name]
69
+ property = property.sub(property_name, @property_map[property_name])
70
+ elsif @value_map[property_name]
71
+ clean_value = value.sub(/;$/, '').sub(/\\9/, '').sub(/!\s*important/, '').strip
72
+ value = value.sub(clean_value, self.send(@value_map[property_name], clean_value))
73
+ end
74
+
75
+ property + ':' + value
76
+ end
77
+
78
+ def transform_multiple(declarations)
79
+ declarations.split(/(;)(?!base64)/).map do |declaration|
80
+ m = declaration.match(/([^:]+):(.+)/m)
81
+
82
+ if m
83
+ property, value = m[1..2]
84
+ transform(property, value)
85
+ else
86
+ declaration
87
+ end
88
+ end.join
89
+ end
90
+
91
+ def rtltr(v)
92
+ v == 'left' ? 'right' : v == 'right' ? 'left' : v
93
+ end
94
+
95
+ def direction(v)
96
+ v == 'ltr' ? 'rtl' : v == 'rtl' ? 'ltr' : v
97
+ end
98
+
99
+ def rect(v)
100
+ if v.match(/rect\([^)]*\)/)
101
+ v.gsub(/\([^)]*\)/) do |m|
102
+ parts = m.gsub(/[()]/, '').split(',').map(&:strip)
103
+ if parts.size == 1
104
+ # Using backwards compatible syntax
105
+ parts = m.gsub(/[()]/, '').split(/\s+/).map(&:strip)
106
+ "(#{parts[0]} #{parts[3]} #{parts[2]} #{parts[1]})"
107
+ else
108
+ "(#{parts[0]}, #{parts[3]}, #{parts[2]}, #{parts[1]})"
109
+ end
110
+ end
111
+ else
112
+ v
113
+ end
114
+ end
115
+
116
+ def quad(v)
117
+ # 1px 2px 3px 4px => 1px 4px 3px 2px
118
+ m = v.split(/\s+/)
119
+ m.length == 4 && !v.include?('rgba(') ? [m[0], m[3], m[2], m[1]].join(' ') : v
120
+ end
121
+
122
+ def quad_radius(v)
123
+ # top-left, top-right, bottom-right, bottom-left
124
+ # when bottom-left is omitted, it takes the value of top-right
125
+ # when bottom-right is omitted, it takes the value of top-left
126
+ # when top-right is omitted, it takes the value of top-left
127
+ m = v.split(/\s+/)
128
+ case m.length
129
+ when 4 then [m[1], m[0], m[3], m[2]].join(' ')
130
+ when 3 then [m[1], m[0], m[1], m[2]].join(' ')
131
+ when 2 then [m[1], m[0]].join(' ')
132
+ else v
133
+ end
134
+ end
135
+
136
+ def cursor(v)
137
+ if v.match(/^[ns]?e-resize$/)
138
+ v.gsub(/e-resize/, 'w-resize')
139
+ elsif v.match(/^[ns]?w-resize$/)
140
+ v.gsub(/w-resize/, 'e-resize')
141
+ else
142
+ v
143
+ end
144
+ end
145
+
146
+ def shadow(v)
147
+ found = false
148
+ v.gsub(/rgba\([^)]*\)|,|#[0-9A-Fa-f]*|[-0-9.px]+/) do |m|
149
+ if m == ","
150
+ # this property can take several comma-seperated values, we account for that, and transform each one correctly.
151
+ found = false
152
+ m
153
+ elsif m.match(/rgba\([^)]*\)|#[0-9A-Fa-f]*/) || found
154
+ m
155
+ else
156
+ found = true
157
+ if m.to_f.zero?
158
+ m
159
+ else
160
+ m.chars.first == '-' ? m[1..-1] : '-' + m
161
+ end
162
+ end
163
+ end
164
+ end
165
+
166
+ def deg(v)
167
+ if v == '0'
168
+ v
169
+ else
170
+ old_angle = v.to_f
171
+ new_angle = 360 - old_angle
172
+ new_angle = new_angle.to_i if new_angle == new_angle.to_i # If it's an integer, write it without a decimal part.
173
+ v.gsub(/[0-9.]+/, new_angle.to_s)
174
+ end
175
+ end
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,70 @@
1
+ require 'optparse'
2
+
3
+ module Rtlize
4
+ class Exec
5
+ def initialize(args)
6
+ @args = args
7
+ @input = $stdin
8
+ @output = $stdout
9
+ end
10
+
11
+ def setup_option_parser
12
+ @option_parser = OptionParser.new do |opts|
13
+ opts.banner = <<-END
14
+ Usage: rtlize [options | source_file [target_file]]
15
+
16
+ Description:
17
+
18
+ The rtlize utility reads CSS from the source_file, or the standard input (stdin) if no source_file is specified,
19
+ and transforms it to target right-to-left (RTL) layouts instead of left-to-right (LTR) layouts, or vice versa.
20
+
21
+ The transformed CSS will then be written to the target_file, or the standard output (stdout) if no target_file is specified.
22
+
23
+ Options:
24
+ END
25
+
26
+ opts.on_tail("-h", "-?", "--help", "Show this message") do
27
+ puts opts
28
+ exit
29
+ end
30
+
31
+ opts.on_tail("-v", "--version", "Print version") do
32
+ puts("RTLize #{Rtlize::VERSION}")
33
+ exit
34
+ end
35
+ end
36
+ end
37
+
38
+ def parse_options
39
+ setup_option_parser
40
+ @option_parser.parse!(@args)
41
+
42
+ if @args.length > 2
43
+ puts @option_parser
44
+ exit 1
45
+ end
46
+
47
+ @input = File.open(@args[0], 'r') if @args.length > 0
48
+ @output = File.open(@args[1], 'w') if @args.length > 1
49
+ end
50
+
51
+ def parse!
52
+ parse_options
53
+ rtlize_input
54
+ exit 0
55
+ end
56
+
57
+ def rtlize_input
58
+ if @input.tty?
59
+ puts "Warning: Reading from standard input. Use Ctrl-D to indicate EOF."
60
+ end
61
+ input = @input.read
62
+ @input.close
63
+
64
+ output = Rtlize::RTLizer.transform(input)
65
+
66
+ @output.write(output)
67
+ @output.close
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,5 @@
1
+ module Rtlize
2
+ def self.dir(locale = I18n.locale)
3
+ Rtlize.rtl_locales.include?(locale.to_sym) ? 'rtl' : 'ltr'
4
+ end
5
+ end
@@ -0,0 +1,22 @@
1
+ require 'rtlize/helpers'
2
+ require 'rtlize/rtl_processor'
3
+
4
+ module Rtlize
5
+ class Railtie < ::Rails::Railtie
6
+ config.rtlize = ActiveSupport::OrderedOptions.new
7
+ config.rtlize.rtl_selector = Rtlize.rtl_selector
8
+ config.rtlize.rtl_locales = Rtlize.rtl_locales
9
+
10
+ initializer "rtlize.railtie", :after => "sprockets.environment" do |app|
11
+ if defined?(Sprockets)
12
+ # Sprockets 4+ (Rails 7+) uses a callable with call(input) -> { data: }
13
+ # Sprockets 3 used register_postprocessor with a class having render(context, locals)
14
+ # We support Sprockets 4+ only.
15
+ Sprockets.register_postprocessor 'text/css', Rtlize::RtlProcessor
16
+ end
17
+
18
+ Rtlize.rtl_selector = config.rtlize.rtl_selector
19
+ Rtlize.rtl_locales = config.rtlize.rtl_locales
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,24 @@
1
+ module Rtlize
2
+ class RtlProcessor
3
+ ALLOWED_EXTENSIONS = %w[css scss sass].freeze
4
+
5
+ def self.call(input)
6
+ filename = input[:filename]
7
+ source = input[:data]
8
+ context = input[:environment].context_class.new(input)
9
+
10
+ result = run(filename, source, context)
11
+ context.metadata.merge(data: result)
12
+ end
13
+
14
+ def self.run(filename, source, context)
15
+ basename = File.basename(filename)
16
+ extension = basename.split('.').last
17
+ if ALLOWED_EXTENSIONS.include?(extension) && context.logical_path.to_s.match?(/\.rtl/i)
18
+ Rtlize::RTLizer.transform(source)
19
+ else
20
+ source
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,126 @@
1
+ require 'rtlize/declaration'
2
+
3
+ module Rtlize
4
+ def self.rtl_selector
5
+ @@rtl_selector ||= "[dir=rtl]"
6
+ end
7
+
8
+ def self.rtl_selector=(selector)
9
+ @@rtl_selector = selector
10
+ end
11
+
12
+ def self.rtl_locales
13
+ @@rtl_locales ||= [:ar, :fa, :he, :ur]
14
+ end
15
+
16
+ def self.rtl_locales=(locales)
17
+ @@rtl_locales = locales
18
+ end
19
+
20
+ class RTLizer
21
+ class << self
22
+ def simple_block_regexp
23
+ %r{
24
+ ( [^\{\}]+ ) \{
25
+ ( [^\{\}]+ )
26
+ \}
27
+ }x
28
+ end
29
+
30
+ def block_regexp
31
+ %r{
32
+ [^\{\}]+ \{
33
+ (?:
34
+ (?:
35
+ [^\{\}]+ \{
36
+ [^\}]*
37
+ \} [^\{\}]*
38
+ )*
39
+ |
40
+ [^\{\}]+
41
+ )
42
+ \}
43
+ }x
44
+ end
45
+
46
+ def rule_regexp
47
+ # Break the blocks' rules into their selector & declaration parts
48
+ %r{
49
+ ( [^\{\}]+ ) \{
50
+ (
51
+ (?:
52
+ [^\{\}]+ \{
53
+ [^\}]*
54
+ \} [^\{\}]*
55
+ )*
56
+ )
57
+ \}
58
+ |
59
+ ( [^\{\}]+ ) \{
60
+ ( [^\{\}]+ )
61
+ \}
62
+ }x
63
+ end
64
+
65
+ def should_rtlize_selector?(selector)
66
+ selector = selector.gsub(/\/\*[\s\S]+?\*\//, '') # Remove comments
67
+ selector = selector.gsub(/['"]/, '') # Remove quote characters
68
+
69
+ rtl_selector = Rtlize.rtl_selector.gsub(/['"]/, '') # Remove quote characters
70
+
71
+ rtl_selector_regexp = /(^|\b|\s)#{Regexp.escape(rtl_selector)}($|\b|\s)/
72
+ !selector.match(rtl_selector_regexp)
73
+ end
74
+
75
+ def update_no_invert(selector)
76
+ # The CSS comment must start with "!" in order to be considered as important by the CSS compressor
77
+ # otherwise, it will be removed by the asset pipeline before reaching this processor.
78
+ if selector.match(/\/\*!= begin\(no-rtl\) \*\//)
79
+ @no_invert = true
80
+ elsif selector.match(/\/\*!= end\(no-rtl\) \*\//)
81
+ @no_invert = false
82
+ end
83
+ end
84
+
85
+ def transform(css)
86
+ @no_invert = false
87
+
88
+ css.gsub(block_regexp) do |block|
89
+ block_selector_regexp = %r{ ^ [^\{\}]+ }x
90
+ block_selector = block.match(block_selector_regexp).to_s
91
+ next if block_selector.length == 0
92
+
93
+ block.gsub(rule_regexp) do |rule|
94
+ parts = rule.match(rule_regexp)
95
+ if parts[1].nil?
96
+ # Simple block
97
+ selector, declarations = parts[3,4]
98
+ transform_simple_block(selector, declarations)
99
+ else
100
+ # Nested blocks
101
+ selector, declarations = parts[1,2]
102
+ selector + '{' + transform_nested_blocks(declarations) + '}'
103
+ end
104
+ end
105
+ end
106
+ end
107
+
108
+ def transform_simple_block(selector, declarations)
109
+ update_no_invert(selector)
110
+ if !@no_invert && should_rtlize_selector?(selector)
111
+ selector + '{' + Rtlize::Declaration.transform_multiple(declarations) + '}'
112
+ else
113
+ selector + '{' + declarations + '}'
114
+ end
115
+ end
116
+
117
+ def transform_nested_blocks(blocks)
118
+ blocks.gsub(simple_block_regexp) do |block|
119
+ parts = block.match(simple_block_regexp)
120
+ selector, declarations = parts[1,2]
121
+ transform_simple_block(selector, declarations)
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,3 @@
1
+ module Rtlize
2
+ VERSION = "1.0.0"
3
+ end
data/lib/rtlize.rb ADDED
@@ -0,0 +1,6 @@
1
+ module Rtlize
2
+ end
3
+
4
+ require 'rtlize/version'
5
+ require 'rtlize/rtlizer'
6
+ require 'rtlize/railtie' if defined?(Rails)
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :rtlize do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rtlize-2
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Fady Naffa
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: rails
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: 7.0.0
19
+ type: :development
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: 7.0.0
26
+ - !ruby/object:Gem::Dependency
27
+ name: sprockets-rails
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: sqlite3
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '1.4'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '1.4'
54
+ - !ruby/object:Gem::Dependency
55
+ name: simplecov
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ description: |
69
+ RTLize allows you to write your stylesheets for left-to-right (LTR) layouts
70
+ and have them automatically work for right-to-left (RTL) layouts as well.
71
+ email:
72
+ - fadynaffa3@gmail.com
73
+ executables:
74
+ - rtlize
75
+ extensions: []
76
+ extra_rdoc_files: []
77
+ files:
78
+ - MIT-LICENSE
79
+ - README.md
80
+ - Rakefile
81
+ - bin/rtlize
82
+ - lib/rtlize.rb
83
+ - lib/rtlize/declaration.rb
84
+ - lib/rtlize/exec.rb
85
+ - lib/rtlize/helpers.rb
86
+ - lib/rtlize/railtie.rb
87
+ - lib/rtlize/rtl_processor.rb
88
+ - lib/rtlize/rtlizer.rb
89
+ - lib/rtlize/version.rb
90
+ - lib/tasks/rtlize_tasks.rake
91
+ homepage: https://github.com/fadynaffa3/RTLize
92
+ licenses:
93
+ - MIT
94
+ metadata: {}
95
+ rdoc_options: []
96
+ require_paths:
97
+ - lib
98
+ required_ruby_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: 4.0.0
103
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ requirements: []
109
+ rubygems_version: 4.0.10
110
+ specification_version: 4
111
+ summary: Automatic CSS layout switcher (from LTR to RTL)
112
+ test_files: []