trenni-formatters 2.6.0 → 2.11.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,148 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require 'trenni/builder'
24
+ require 'trenni/template'
25
+
26
+ require_relative 'form_formatter'
27
+
28
+ module Trenni
29
+ module Formatters
30
+ module HTML
31
+ module LabelForm
32
+ include FormFormatter
33
+
34
+ # An input field (single line text).
35
+ def input(**options)
36
+ options = @options.merge(**options)
37
+
38
+ Builder.fragment do |builder|
39
+ builder.inline(:label) do
40
+ builder.inline(:span) do
41
+ builder.text title_for(**options)
42
+
43
+ if details = details_for(**options)
44
+ builder.inline(:small) {builder.text details}
45
+ end
46
+ end
47
+
48
+ builder.inline :input, input_attributes_for(**options)
49
+ end
50
+ end
51
+ end
52
+
53
+ # An output field for the result of a computation.
54
+ def output(**options)
55
+ options = @options.merge(**options)
56
+
57
+ builder.inline(:label) do
58
+ builder.inline(:span) do
59
+ builder.text title_for(**options)
60
+
61
+ if details = details_for(**options)
62
+ builder.inline(:small) {builder.text details}
63
+ end
64
+ end
65
+
66
+ builder.inline :output, output_attributes_for(**options) do
67
+ builder.text value_for(**options)
68
+ end
69
+ end
70
+ end
71
+
72
+ # A textarea field (multi-line text).
73
+ def textarea(**options)
74
+ options = @options.merge(**options)
75
+
76
+ Builder.fragment do |builder|
77
+ builder.inline(:label) do
78
+ builder.inline(:span) do
79
+ builder.text title_for(**options)
80
+
81
+ if details = details_for(**options)
82
+ builder.inline(:small) {builder.text details}
83
+ end
84
+ end
85
+
86
+ builder.tag :textarea, textarea_attributes_for(**options) do
87
+ builder.text value_for(**options)
88
+ end
89
+ end
90
+ end
91
+ end
92
+
93
+ # A checkbox field.
94
+ def checkbox(**options)
95
+ options = @options.merge(**options)
96
+
97
+ Builder.fragment do |builder|
98
+ builder.inline(:label) do
99
+ builder.inline :input, :type => :hidden, :name => name_for(**options), :value => 'false'
100
+
101
+ builder.inline(:span) do
102
+ builder.text title_for(**options)
103
+
104
+ if details = details_for(**options)
105
+ builder.inline(:small) {builder.text details}
106
+ end
107
+ end
108
+
109
+ builder.tag :input, checkbox_attributes_for(**options)
110
+
111
+ # We would like a little bit of whitespace between the checkbox and the title.
112
+ builder.text " " + title_for(**options)
113
+ end
114
+ end
115
+ end
116
+
117
+ # A submission button
118
+ def submit(**options)
119
+ options = @options.merge(**options)
120
+ options[:title] ||= submit_title_for(**options)
121
+
122
+ Builder.fragment do |builder|
123
+ builder.inline :input, submit_attributes_for(**options)
124
+ end
125
+ end
126
+
127
+ def element(klass, **options, &block)
128
+ options = @options.merge(**options)
129
+ buffer = Trenni::Template.buffer(block.binding)
130
+
131
+ buffer << Builder.fragment do |builder|
132
+ builder.inline(:label) do
133
+ builder.inline(:span) do
134
+ builder.text title_for(**options)
135
+
136
+ if details = details_for(**options)
137
+ builder.inline(:small) {builder.text details}
138
+ end
139
+ end
140
+
141
+ klass.call(self, builder, **options, &block)
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
147
+ end
148
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -25,24 +27,24 @@ module Trenni
25
27
  module HTML
26
28
  # Standard drop-down select box:
27
29
  class OptionSelect
28
- def self.call(formatter, options, builder, &block)
29
- instance = self.new(formatter, options, builder)
30
+ def self.call(formatter, builder, **options, &block)
31
+ instance = self.new(formatter, builder, **options)
30
32
 
31
33
  instance.call(options, &block)
32
34
  end
33
35
 
34
- def initialize(formatter, options, builder)
36
+ def initialize(formatter, builder, **options)
35
37
  @formatter = formatter
36
38
  @object = formatter.object
37
- @field = options[:field]
38
-
39
- @options = options
40
39
 
41
40
  @builder = builder
41
+
42
+ @options = options
43
+ @field = options[:field]
42
44
  end
43
45
 
44
- def name_for(options)
45
- if name = @formatter.name_for(options)
46
+ def name_for(**options)
47
+ if name = @formatter.name_for(**options)
46
48
  if options[:multiple]
47
49
  name = "#{name}[]"
48
50
  end
@@ -51,26 +53,26 @@ module Trenni
51
53
  end
52
54
  end
53
55
 
54
- def raw_value_for(options)
55
- @formatter.raw_value_for(options)
56
+ def raw_value_for(**options)
57
+ @formatter.raw_value_for(**options)
56
58
  end
57
59
 
58
60
  def raw_value
59
- @raw_value ||= raw_value_for(@options)
61
+ @raw_value ||= raw_value_for(**@options)
60
62
  end
61
63
 
62
- def value_for(options)
63
- @formatter.value_for(options)
64
+ def value_for(**options)
65
+ @formatter.value_for(**options)
64
66
  end
65
67
 
66
- def title_for(options)
67
- @formatter.title_for(options)
68
+ def title_for(**options)
69
+ @formatter.title_for(**options)
68
70
  end
69
71
 
70
- def option_attributes_for(options)
72
+ def option_attributes_for(**options)
71
73
  return {
72
- :value => value_for(options),
73
- :selected => options.fetch(:selected){ raw_value == raw_value_for(options) },
74
+ :value => value_for(**options),
75
+ :selected => options.fetch(:selected) {raw_value == raw_value_for(**options)},
74
76
  :id => options[:id],
75
77
  :class => options[:class],
76
78
  :data => options[:data],
@@ -81,11 +83,11 @@ module Trenni
81
83
  options[:field] ||= 'id'
82
84
 
83
85
  Builder.fragment(builder) do |builder|
84
- builder.inline(:option, option_attributes_for(options)) { builder.text title_for(options) }
86
+ builder.inline(:option, option_attributes_for(**options)) {builder.text title_for(**options)}
85
87
  end
86
88
  end
87
89
 
88
- def optional_title_for(options)
90
+ def optional_title_for(**options)
89
91
  if options[:optional] == true
90
92
  options[:blank] || ''
91
93
  else
@@ -93,9 +95,9 @@ module Trenni
93
95
  end
94
96
  end
95
97
 
96
- def group_attributes_for(options)
98
+ def group_attributes_for(**options)
97
99
  return {
98
- :label => title_for(options),
100
+ :label => title_for(**options),
99
101
  :id => options[:id],
100
102
  :class => options[:class],
101
103
  :data => options[:data],
@@ -104,34 +106,35 @@ module Trenni
104
106
 
105
107
  def group(options = {}, &block)
106
108
  Builder.fragment(@builder) do |builder|
107
- builder.tag :optgroup, group_attributes_for(options) do
109
+ builder.tag :optgroup, group_attributes_for(**options) do
108
110
  if options[:optional]
109
- item(:title => optional_title_for(options), :value => nil, :builder => builder)
111
+ item(:title => optional_title_for(**options), :value => nil, :builder => builder)
110
112
  end
111
113
 
112
- builder.append Trenni::Template.capture(&block)
114
+ builder.capture(&block)
113
115
  end
114
116
  end
115
117
  end
116
118
 
117
- def select_attributes_for(options)
119
+ def select_attributes_for(**options)
118
120
  return {
119
- :name => name_for(options),
121
+ :name => name_for(**options),
120
122
  :id => options[:id],
121
123
  :class => options[:class],
122
124
  :multiple => options[:multiple],
123
125
  :data => options[:data],
126
+ :required => options[:required],
124
127
  }
125
128
  end
126
129
 
127
130
  def call(options = {}, &block)
128
131
  Builder.fragment(@builder) do |builder|
129
- builder.tag :select, select_attributes_for(options) do
132
+ builder.tag :select, select_attributes_for(**options) do
130
133
  if options[:optional]
131
- item(:title => optional_title_for(options), :value => nil, :builder => builder)
134
+ item(:title => optional_title_for(**options), :value => nil, :builder => builder)
132
135
  end
133
136
 
134
- builder.append Trenni::Template.capture(self, &block)
137
+ builder.capture(self, &block)
135
138
  end
136
139
  end
137
140
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -25,49 +27,49 @@ module Trenni
25
27
  module HTML
26
28
  # Table based select boxes using per-row checkboxes.
27
29
  class RadioSelect
28
- def self.call(formatter, options, builder, &block)
29
- instance = self.new(formatter, options, builder)
30
+ def self.call(formatter, builder, **options, &block)
31
+ instance = self.new(formatter, builder, **options)
30
32
 
31
33
  instance.call(options, &block)
32
34
  end
33
35
 
34
- def initialize(formatter, options, builder)
36
+ def initialize(formatter, builder, **options)
35
37
  @formatter = formatter
36
38
  @object = formatter.object
37
39
 
40
+ @builder = builder
41
+
38
42
  @options = options
39
43
  @field = options[:field]
40
-
41
- @builder = builder
42
44
  end
43
45
 
44
- def name_for(options)
45
- @formatter.name_for(options)
46
+ def name_for(**options)
47
+ @formatter.name_for(**options)
46
48
  end
47
49
 
48
- def raw_value_for(options)
49
- @formatter.raw_value_for(options)
50
+ def raw_value_for(**options)
51
+ @formatter.raw_value_for(**options)
50
52
  end
51
53
 
52
54
  def raw_value
53
- @raw_value ||= raw_value_for(@options)
55
+ @raw_value ||= raw_value_for(**@options)
54
56
  end
55
57
 
56
- def value_for(options)
57
- @formatter.value_for(options)
58
+ def value_for(**options)
59
+ @formatter.value_for(**options)
58
60
  end
59
61
 
60
- def title_for(options)
61
- @formatter.title_for(options)
62
+ def title_for(**options)
63
+ @formatter.title_for(**options)
62
64
  end
63
65
 
64
- def radio_attributes_for(options)
66
+ def radio_attributes_for(**options)
65
67
  return {
66
68
  :type => :radio,
67
69
  :name => @field,
68
70
  # We set a default value to empty string, otherwise it becomes "on".
69
- :value => value_for(options) || "",
70
- :checked => options.fetch(:selected){ raw_value == raw_value_for(options) },
71
+ :value => value_for(**options) || "",
72
+ :checked => options.fetch(:selected) {raw_value == raw_value_for(**options)},
71
73
  :data => options[:data],
72
74
  }
73
75
  end
@@ -76,21 +78,21 @@ module Trenni
76
78
  Builder.fragment(builder) do |builder|
77
79
  builder.tag :tr do
78
80
  builder.inline(:td, :class => :handle) do
79
- builder.tag :input, radio_attributes_for(options)
81
+ builder.tag :input, radio_attributes_for(**options)
80
82
  end
81
83
 
82
84
  builder.inline(:td, :class => :item) do
83
85
  if block_given?
84
- builder.append Trenni::Template.capture(self, &block)
86
+ builder.capture(self, &block)
85
87
  else
86
- builder.text title_for(options)
88
+ builder.text title_for(**options)
87
89
  end
88
90
  end
89
91
  end
90
92
  end >> block
91
93
  end
92
94
 
93
- def optional_title_for(options)
95
+ def optional_title_for(**options)
94
96
  if options[:optional] == true
95
97
  options[:blank] || ''
96
98
  else
@@ -103,10 +105,10 @@ module Trenni
103
105
  builder.tag :table do
104
106
  builder.tag :tbody do
105
107
  if options[:optional]
106
- item(:title => optional_title_for(options), :value => nil, :builder => builder)
108
+ item(:title => optional_title_for(**options), :value => nil, :builder => builder)
107
109
  end
108
110
 
109
- builder.append Trenni::Template.capture(self, &block)
111
+ builder.capture(self, &block)
110
112
  end
111
113
  end
112
114
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -18,20 +20,18 @@
18
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
21
  # THE SOFTWARE.
20
22
 
21
- require 'sanitize'
22
- require 'kramdown'
23
+ require 'markly'
23
24
 
24
25
  require 'trenni/markup'
26
+ require 'trenni/sanitize/fragment'
25
27
 
26
28
  module Trenni
27
29
  module Formatters
28
30
  module Markdown
29
- def markdown(text)
30
- config = Sanitize::Config::BASIC.dup
31
-
32
- config[:elements] += ['h1', 'h2', 'h3']
31
+ def markdown(text, filter = Trenni::Sanitize::Fragment, **options)
32
+ root = Markly.parse(text, **options)
33
33
 
34
- html = Sanitize.clean(Kramdown::Document.new(text).to_html, config)
34
+ html = filter.parse(root.to_html).output
35
35
 
36
36
  return MarkupString.raw(html)
37
37
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -27,24 +29,24 @@ module Trenni
27
29
  def truncated_text(content, options = {})
28
30
  if content
29
31
  length = options.fetch(:length, 30)
30
-
32
+
31
33
  content = TruncatedText.truncate_text(content, length, options)
32
34
 
33
35
  return self.format(content)
34
36
  end
35
37
  end
36
-
38
+
37
39
  def self.truncate_text(text, truncate_at, options = {})
38
40
  return text.dup unless text.length > truncate_at
39
-
41
+
40
42
  options[:omission] ||= '...'
41
43
  length_with_room_for_omission = truncate_at - options[:omission].length
42
44
  stop = if options[:separator]
43
- text.rindex(options[:separator], length_with_room_for_omission) || length_with_room_for_omission
44
- else
45
- length_with_room_for_omission
46
- end
47
-
45
+ text.rindex(options[:separator], length_with_room_for_omission) || length_with_room_for_omission
46
+ else
47
+ length_with_room_for_omission
48
+ end
49
+
48
50
  "#{text[0...stop]}#{options[:omission]}"
49
51
  end
50
52
  end