xhtml_report_generator 1.1.0 → 2.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.
- data/README.md +73 -0
- data/lib/xhtml_report_generator.rb +17 -10
- data/lib/xhtml_report_generator/custom.rb +120 -69
- data/lib/xhtml_report_generator/toc.js +1 -2
- data/lib/xhtml_report_generator/version.rb +1 -1
- metadata +21 -18
- checksums.yaml +0 -7
data/README.md
CHANGED
@@ -1,2 +1,75 @@
|
|
1
1
|
xhtml-report-generator
|
2
2
|
======================
|
3
|
+
|
4
|
+
This project was written to provide an easy way to create valid xhtml documents.
|
5
|
+
Usecases are the automatic creation of reports (e.g. program logs) with automatically created table of contents.
|
6
|
+
xhtml-report-generator is not a Logger replacement, since the complete document is always kept in memory and
|
7
|
+
only written to disk on demand. Hence in case of crashes the data might be lost.
|
8
|
+
|
9
|
+
|
10
|
+
Example usage
|
11
|
+
-------------
|
12
|
+
In the following you can find a quick start on how to use xhtml-report-generator.
|
13
|
+
Basically the project is built in a way that lets you supply your own methods for everything.
|
14
|
+
By default "custom.rb" is loaded through instance eval, so you can check the corresponding documentation for available methods.
|
15
|
+
|
16
|
+
Note that there is a major syntax change for "custom.rb" between version 1.x and 2.x of the gem.
|
17
|
+
Here an example for version >= 2 of this gem is provided.
|
18
|
+
|
19
|
+
Basically starting from version 2 the syntax for each method of custom.rb is unified. It accepts an hash of html attributes as argument, and the actual contents as block argument.
|
20
|
+
|
21
|
+
def method({"attribute" => "value", "attribute" => "value"}) {contents}
|
22
|
+
|
23
|
+
in addition the method naming convention was changed from camelCase to underscore to comply more with ruby conventions.
|
24
|
+
|
25
|
+
<pre>
|
26
|
+
require 'xhtml-report-generator'
|
27
|
+
|
28
|
+
gen1 = XhtmlReportGenerator::Generator.new
|
29
|
+
gen1.create_layout("Title")
|
30
|
+
gen1.heading("h1", {"class" => "bothtoc"}) {"titel"}
|
31
|
+
gen1.heading("h2") {"subtitel"}
|
32
|
+
gen1.heading("h3") {"section"}
|
33
|
+
gen1.content() {"content function: Hallo welt <br /> html test <span class=\"r\" >red span test</span>", {"class"=>"bold"}}
|
34
|
+
gen1.html("<p class="italic">html function: Hallo welt <br /> html test <span class=\"r\" >red span test</span></p>")
|
35
|
+
gen1.highlight(/Ha.*lt/)
|
36
|
+
|
37
|
+
</pre>
|
38
|
+
|
39
|
+
Changes from version 1.x to 2.x
|
40
|
+
-------------------------------
|
41
|
+
To ease with migration here is a list with the changed function names, please also check the new synopsis
|
42
|
+
|
43
|
+
XhtmlReportGenerator::Generator :
|
44
|
+
|
45
|
+
<pre>
|
46
|
+
createXhtmlDoc -> create_xhtml_document
|
47
|
+
|
48
|
+
writeToFile -> write(file=@file, mode='w')
|
49
|
+
</pre>
|
50
|
+
|
51
|
+
Custom :
|
52
|
+
|
53
|
+
<pre>
|
54
|
+
createLayout -> create_layout(title, layout=3)
|
55
|
+
|
56
|
+
setTitle -> set_title(title)
|
57
|
+
|
58
|
+
getTitle -> get_title
|
59
|
+
|
60
|
+
setCurrent! -> set_current!(xpath)
|
61
|
+
|
62
|
+
getCurrent -> get_current
|
63
|
+
|
64
|
+
highlightCaptures -> highlight_captures(regex, color="y", el = @current)
|
65
|
+
|
66
|
+
code -> code(attrs={}, &block)
|
67
|
+
|
68
|
+
content -> content(attrs={}, &block)
|
69
|
+
|
70
|
+
heading -> heading(tag_type="h1", attrs={}, &block)
|
71
|
+
|
72
|
+
headingTop -> heading_top(tag_type="h1", attrs={}, &block)
|
73
|
+
|
74
|
+
</pre>
|
75
|
+
|
@@ -9,7 +9,7 @@ module XhtmlReportGenerator
|
|
9
9
|
# This is the main generator class. It can be instanced with custom javascript, css, and ruby files to allow
|
10
10
|
# generation of arbitrary reports.
|
11
11
|
class Generator
|
12
|
-
attr_accessor :document
|
12
|
+
attr_accessor :document, :file
|
13
13
|
# @param opts [Hash] See the example for an explanation of the valid symbols
|
14
14
|
# @example Valid symbols for the opts Hash
|
15
15
|
# :jquery if specified, path to a version of jquery, that will be inlined into the html header section
|
@@ -21,9 +21,9 @@ module XhtmlReportGenerator
|
|
21
21
|
# define the default values
|
22
22
|
path = File.expand_path("../xhtml_report_generator", __FILE__)
|
23
23
|
symbols = {
|
24
|
-
:jquery
|
25
|
-
:toc
|
26
|
-
:css
|
24
|
+
:jquery => File.expand_path("jquery.js",path),
|
25
|
+
:toc => File.expand_path("toc.js",path),
|
26
|
+
:css => File.expand_path("style_template.css",path),
|
27
27
|
:css_print => File.expand_path("print_template.css",path),
|
28
28
|
:custom_rb => File.expand_path("custom.rb",path)
|
29
29
|
}
|
@@ -37,7 +37,7 @@ module XhtmlReportGenerator
|
|
37
37
|
# all existing Generator classes
|
38
38
|
instance_eval symbols[:custom_rb]
|
39
39
|
|
40
|
-
@document = Generator.
|
40
|
+
@document = Generator.create_xhtml_document("Title")
|
41
41
|
head = @document.elements["//head"]
|
42
42
|
# insert the custom css, and javascript files
|
43
43
|
style = head.add_element("style", {"type" => "text/css"})
|
@@ -56,7 +56,7 @@ module XhtmlReportGenerator
|
|
56
56
|
|
57
57
|
# Creates a minimal valid xhtml document including header title and body elements
|
58
58
|
# @param title [String] Title in the header section
|
59
|
-
def self.
|
59
|
+
def self.create_xhtml_document(title)
|
60
60
|
header = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>'
|
61
61
|
header += '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
|
62
62
|
|
@@ -74,7 +74,7 @@ module XhtmlReportGenerator
|
|
74
74
|
# @param indent [Number] indent for child elements. defaults to 0.
|
75
75
|
def to_s(indent = 0)
|
76
76
|
output = ""
|
77
|
-
# note transitive is needed to preserve newlines in <pre> tags
|
77
|
+
# note : transitive is needed to preserve newlines in <pre> tags
|
78
78
|
# note2: the hash options syntax is supported only from ruby version >= 2.0.0 we need the old style
|
79
79
|
# for compatibility with 1.9.3
|
80
80
|
#@document.write({:output=>output, :indent=>indent, :transitive=>true})
|
@@ -82,12 +82,19 @@ module XhtmlReportGenerator
|
|
82
82
|
return output
|
83
83
|
end
|
84
84
|
|
85
|
-
#
|
86
|
-
#
|
85
|
+
# Saves the xml document to a file. If no file is given, the file which was used most recently for this Generator
|
86
|
+
# object will be overwritten.
|
87
|
+
# @param file [String] absolute or relative path to the file to which will be written. Default: last file used.
|
87
88
|
# @param mode [String] defaults to 'w', one of the file open modes that allows writing ['r+','w','w+','a','a+']
|
88
|
-
def
|
89
|
+
def write(file=@file, mode='w')
|
90
|
+
# instance variables are nil if they were never initialized
|
91
|
+
if file == nil
|
92
|
+
raise "no valid file given"
|
93
|
+
end
|
94
|
+
@file = file
|
89
95
|
File.open(file, "#{mode}:UTF-8") {|f| f.write(self.to_s)}
|
90
96
|
end
|
97
|
+
|
91
98
|
end
|
92
99
|
end
|
93
100
|
|
@@ -5,28 +5,42 @@ module Custom
|
|
5
5
|
# creates the basic page layout and sets the current Element to the main content area (middle div)
|
6
6
|
# @example The middle div is matched by the following xPath
|
7
7
|
# //body/div[@class='middle']
|
8
|
-
|
8
|
+
# @param title [String] the title of the document
|
9
|
+
# @param layout [Fixnum] one of 0,1,2,3 where 0 means minimal layout without left and right table of contents,
|
10
|
+
# 1 means only left toc, 2 means only right toc, and 3 means full layout with left and right toc.
|
11
|
+
def create_layout(title, layout=3)
|
12
|
+
raise "invalid layout selector, choose from 0..3" if (layout < 0) || (layout > 3)
|
13
|
+
|
9
14
|
@body = @document.elements["//body"]
|
10
15
|
# only add the layout if it is not already there
|
11
16
|
if !@layout
|
12
17
|
@body.add_element("div", {"class" => "head"})
|
18
|
+
|
19
|
+
if (layout & 0x1) != 0
|
13
20
|
div = @body.add_element("div", {"class" => "lefttoc", "id" => "ltoc"})
|
14
21
|
div.add_text("Table of Contents")
|
15
22
|
div.add_element("br")
|
23
|
+
end
|
24
|
+
|
25
|
+
if (layout & 0x2) != 0
|
16
26
|
div = @body.add_element("div", {"class" => "righttoc", "id" => "rtoc"})
|
17
27
|
div.add_text("Quick Links")
|
18
28
|
div.add_element("br");div.add_element("br")
|
29
|
+
end
|
30
|
+
|
19
31
|
@div_middle = @body.add_element("div", {"class" => "middle"})
|
20
32
|
@layout = true
|
21
33
|
end
|
22
34
|
@current = @document.elements["//body/div[@class='middle']"]
|
35
|
+
set_title(title)
|
23
36
|
end
|
24
37
|
|
25
|
-
# sets the title of the document in the
|
26
|
-
#
|
27
|
-
|
28
|
-
|
29
|
-
|
38
|
+
# sets the title of the document in the <head> section as well as in the layout header div
|
39
|
+
# create_layout must be called before!
|
40
|
+
# @param title [String] the text which will be insertead
|
41
|
+
def set_title(title)
|
42
|
+
if !@layout
|
43
|
+
raise "call create_layout first"
|
30
44
|
end
|
31
45
|
pagetitle = @document.elements["//head/title"]
|
32
46
|
pagetitle.text = title
|
@@ -35,48 +49,64 @@ module Custom
|
|
35
49
|
end
|
36
50
|
|
37
51
|
# returns the title text of the report
|
38
|
-
|
52
|
+
# @return [String] The title of the report
|
53
|
+
def get_title()
|
39
54
|
pagetitle = @document.elements["//head/title"]
|
40
55
|
return pagetitle.text
|
41
56
|
end
|
42
57
|
|
43
58
|
# set the current element to the element or first element matched by the xpath expression.
|
44
59
|
# The current element is the one which can be modified through highlighting.
|
45
|
-
# @param xpath [REXML::Element|String] the element or
|
46
|
-
def
|
60
|
+
# @param xpath [REXML::Element|String] the element or an xpath string
|
61
|
+
def set_current!(xpath)
|
47
62
|
if xpath.is_a?(REXML::Element)
|
48
63
|
@current = xpath
|
49
|
-
|
64
|
+
elsif xpath.is_a?(String)
|
50
65
|
@current = @document.elements[xpath]
|
66
|
+
else
|
67
|
+
raise "xpath is neither a String nor a REXML::Element"
|
51
68
|
end
|
52
69
|
end
|
53
70
|
|
54
71
|
# returns the current xml element
|
55
|
-
|
72
|
+
# @return [REXML::Element] the xml element after which the following elements will be added
|
73
|
+
def get_current()
|
56
74
|
return @current
|
57
75
|
end
|
58
76
|
|
59
77
|
# Appends a <pre> node after the @current node
|
60
|
-
|
78
|
+
# @param attrs [Hash] attributes for the <pre> element
|
79
|
+
# @yieldreturn [String] the text to be added to the <pre> element
|
80
|
+
# @return [REXML::Element] the Element which was just added
|
81
|
+
def code(attrs={}, &block)
|
61
82
|
temp = REXML::Element.new("pre")
|
62
83
|
temp.add_attributes(attrs)
|
63
84
|
@div_middle.insert_after(@current, temp)
|
64
85
|
@current = temp
|
86
|
+
raise "Block argument is mandatory" unless block_given?
|
87
|
+
text = block.call()
|
65
88
|
@current.add_text(text)
|
66
89
|
return @current
|
67
90
|
end
|
68
91
|
|
69
92
|
# Appends a <p> node after the @current node
|
70
|
-
|
93
|
+
# @param attrs [Hash] attributes for the <p> element
|
94
|
+
# @yieldreturn [String] the text to be added to the <p> element
|
95
|
+
# @return [REXML::Element] the Element which was just added
|
96
|
+
def content(attrs={}, &block)
|
71
97
|
temp = REXML::Element.new("p")
|
72
98
|
temp.add_attributes(attrs)
|
73
99
|
@div_middle.insert_after(@current, temp)
|
74
100
|
@current = temp
|
101
|
+
raise "Block argument is mandatory" unless block_given?
|
102
|
+
text = block.call()
|
75
103
|
@current.add_text(text)
|
76
104
|
return @current
|
77
105
|
end
|
78
106
|
|
79
107
|
# insert arbitrary xml code after the @current element in the content pane (div middle)
|
108
|
+
# @param text [String] valid xhtml code which is included into the document
|
109
|
+
# @return [REXML::Element] the Element which was just added
|
80
110
|
def html(text)
|
81
111
|
# we need to create a new document with a pseudo root
|
82
112
|
doc = REXML::Document.new("<root>"+text+"</root>")
|
@@ -87,15 +117,22 @@ module Custom
|
|
87
117
|
end
|
88
118
|
return @current
|
89
119
|
end
|
90
|
-
|
91
|
-
#
|
120
|
+
|
121
|
+
# Scans all REXML::Text children of an REXML::Element for any occurrences of regex.
|
122
|
+
# The text will be matched as one, not line by line as you might think.
|
123
|
+
# If you want to write a regexp matching multiple lines keep in mind that the dot "." by default doesn't
|
124
|
+
# match newline characters. Consider using the "m" option (e.g. /regex/m ) which makes dot match newlines
|
125
|
+
# or match newlines explicitly.
|
126
|
+
# highlight_captures then puts a <span> </span> tag around all captures of the regex
|
92
127
|
# NOTE: nested captures are not supported and don't make sense in this context!!
|
93
128
|
# @param regex [Regexp] a regular expression that will be matched
|
94
129
|
# @param color [String] at this point one of "y", "r", "g", "b" (yellow, red, green, blue) is supported
|
95
|
-
# @param el [REXML::Element] the Element (scope) which will be searched for pattern matches
|
96
|
-
|
130
|
+
# @param el [REXML::Element] the Element (scope) which will be searched for pattern matches, by default the last inserted element will be scanned
|
131
|
+
# @return [Fixnum] the number of highlighted captures
|
132
|
+
def highlight_captures(regex, color="y", el = @current)
|
97
133
|
# get all children of the current node
|
98
134
|
arr = el.to_a()
|
135
|
+
num_matches = 0
|
99
136
|
# depth first recursion into grand-children
|
100
137
|
for i in arr do
|
101
138
|
# detach from current
|
@@ -106,32 +143,40 @@ module Custom
|
|
106
143
|
|
107
144
|
# We get an array of [[start,length], [start,length], ...] for all our regex SUB-matches
|
108
145
|
positions = i.value().enum_for(:scan, regex).flat_map {
|
109
|
-
# Regexp.last_match is a MatchData object, the index 0 is the entire match
|
110
|
-
# indices 1..n are the captures (sub expressions)
|
146
|
+
# Regexp.last_match is a MatchData object, the index 0 is the entire match, 1 to n are captures
|
111
147
|
array = Array.new
|
112
148
|
for k in 1..Regexp.last_match.length - 1 do
|
113
149
|
array.push([Regexp.last_match.begin(k),
|
114
150
|
Regexp.last_match.end(k)-Regexp.last_match.begin(k)])
|
115
151
|
end
|
152
|
+
# return the array for the flat_map
|
116
153
|
array
|
117
154
|
}
|
118
|
-
|
155
|
+
num_matches += positions.length
|
156
|
+
replace_text_with_elements(el, i, "span", {"class" => color}, positions)
|
119
157
|
else
|
120
158
|
# for non-text nodes we recurse into it and finally reattach to our parent to preserve ordering
|
121
|
-
|
159
|
+
num_matches += highlight_captures(regex, color, i)
|
122
160
|
el.add(i)
|
123
161
|
end # if i.class.to_s() == "REXML::Text"
|
124
162
|
end # for i in arr do
|
125
|
-
|
163
|
+
return num_matches
|
126
164
|
end
|
127
165
|
|
128
|
-
#
|
166
|
+
# Scans all REXML::Text children of an REXML::Element for any occurrences of regex.
|
167
|
+
# The text will be matched as one, not line by line as you might think.
|
168
|
+
# If you want to write a regexp matching multiple lines keep in mind that the dot "." by default doesn't
|
169
|
+
# match newline characters. Consider using the "m" option (e.g. /regex/m ) which makes dot match newlines
|
170
|
+
# or match newlines explicitly.
|
171
|
+
# highlight then puts a <span> </span> tag around all matches of regex
|
129
172
|
# @param regex [Regexp] a regular expression that will be matched
|
130
173
|
# @param color [String] at this point one of "y", "r", "g", "b" (yellow, red, green, blue) is supported
|
131
174
|
# @param el [REXML::Element] the Element (scope) which will be searched for pattern matches
|
175
|
+
# @return [Fixnum] the number of highlighted captures
|
132
176
|
def highlight(regex, color="y", el = @current)
|
133
177
|
# get all children of the current node
|
134
178
|
arr = el.to_a()
|
179
|
+
num_matches = 0
|
135
180
|
#puts arr.inspect
|
136
181
|
# depth first recursion into grand-children
|
137
182
|
for i in arr do
|
@@ -147,23 +192,26 @@ module Custom
|
|
147
192
|
[Regexp.last_match.begin(0),
|
148
193
|
Regexp.last_match.end(0)-Regexp.last_match.begin(0)]
|
149
194
|
}
|
150
|
-
|
195
|
+
num_matches += positions.length
|
196
|
+
replace_text_with_elements(el, i, "span", {"class" => color}, positions)
|
151
197
|
else
|
152
198
|
# for non-text nodes we recurse into it and finally reattach to our parent to preserve ordering
|
153
199
|
# puts "recurse"
|
154
|
-
highlight(regex, color, i)
|
200
|
+
num_matches += highlight(regex, color, i)
|
155
201
|
el.add(i)
|
156
202
|
end # if i.class.to_s() == "REXML::Text"
|
157
203
|
end # for i in arr do
|
204
|
+
return num_matches
|
158
205
|
end
|
159
206
|
|
160
207
|
# creates a html table from two dimensional array of the form Array[row][col]
|
161
|
-
# @param table_data [Array] containing all data, the '.to_s' method will be called on each element
|
208
|
+
# @param table_data [Array<Array>] of the form Array[row][column] containing all data, the '.to_s' method will be called on each element,
|
162
209
|
# @param headers [Number] either of 0, 1, 2, 3. Where 0 is no headers (<th>) at all, 1 is only the first row,
|
163
210
|
# 2 is only the first column and 3 is both, first row and first column as <th> elements. Every other number
|
164
211
|
# is equivalent to the bitwise AND of the two least significant bits with 1, 2 or 3
|
165
|
-
|
166
|
-
|
212
|
+
# @return [REXML::Element] the Element which was just added
|
213
|
+
def table(table_data, headers=0, table_attrs={}, tr_attrs={}, th_attrs={}, td_attrs={})
|
214
|
+
|
167
215
|
temp = REXML::Element.new("table")
|
168
216
|
temp.add_attributes(table_attrs)
|
169
217
|
|
@@ -189,60 +237,63 @@ module Custom
|
|
189
237
|
end
|
190
238
|
|
191
239
|
# Appends a new heading element to body, and sets current to this new heading
|
192
|
-
# @param
|
193
|
-
# @param
|
194
|
-
# @
|
195
|
-
#
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
opts = {"class" => "bothtoc"}
|
202
|
-
else
|
203
|
-
opts = {}
|
204
|
-
end
|
205
|
-
|
206
|
-
temp = REXML::Element.new(type)
|
207
|
-
temp.add_attributes(opts)
|
240
|
+
# @param tag_type [String] specifiy "h1", "h2", "h3" for the heading, defaults to "h1"
|
241
|
+
# @param attrs [Hash] attributes for the <h#> element, any valid html attributes can be specified
|
242
|
+
# @option attrs [String] "class" by default every heading is added to the left table of contents (toc)
|
243
|
+
# use the class "onlyrtoc" or "bothtoc" to add a heading only to the right toc or to both tocs respectively
|
244
|
+
# @yieldreturn [String] the text to be added to the <h#> element
|
245
|
+
# @return [REXML::Element] the Element which was just added
|
246
|
+
def heading(tag_type="h1", attrs={}, &block)
|
247
|
+
temp = REXML::Element.new(tag_type)
|
248
|
+
temp.add_attributes(attrs)
|
208
249
|
|
209
250
|
@div_middle.insert_after(@current, temp)
|
210
251
|
@current = temp
|
252
|
+
raise "Block argument is mandatory" unless block_given?
|
253
|
+
text = block.call()
|
211
254
|
@current.text = text
|
212
255
|
return @current
|
213
256
|
end
|
214
|
-
|
215
|
-
# Inserts a new heading element at the very beginning of the middle div section, and points @current to this heading
|
216
|
-
# @param text [String] the heading text
|
217
|
-
# @param type [String] specifiy "h1", "h2", "h3" for the heading
|
218
|
-
# @param toc [symbol] one of :ltoc, :rtoc, :btoc depending on in which toc you want to display the heading
|
219
|
-
# @return the added element
|
220
|
-
def headingTop(text, type="h1", toc=:ltoc)
|
221
|
-
case toc
|
222
|
-
when :rtoc
|
223
|
-
opts = {"class" => "onlyrtoc"}
|
224
|
-
when :btoc
|
225
|
-
opts = {"class" => "bothtoc"}
|
226
|
-
else
|
227
|
-
opts = {}
|
228
|
-
end
|
229
257
|
|
230
|
-
|
231
|
-
|
232
|
-
#
|
233
|
-
@
|
234
|
-
|
235
|
-
@
|
236
|
-
return
|
237
|
-
|
258
|
+
# Inserts a new heading element at the very beginning of the middle div section, and points @current to this heading
|
259
|
+
# @param tag_type [String] specifiy "h1", "h2", "h3" for the heading, defaults to "h1"
|
260
|
+
# @param attrs [Hash] attributes for the <h#> element, any valid html attributes can be specified
|
261
|
+
# @option attrs [String] "class" by default every heading is added to the left table of contents (toc)
|
262
|
+
# use the class "onlyrtoc" or "bothtoc" to add a heading only to the right toc or to both tocs respectively
|
263
|
+
# @yieldreturn [String] the text to be added to the <h#> element
|
264
|
+
# @return [REXML::Element] the Element which was just added
|
265
|
+
def heading_top(tag_type="h1", attrs={}, &block)
|
266
|
+
temp = REXML::Element.new(tag_type)
|
267
|
+
temp.add_attributes(attrs)
|
268
|
+
# insert before the first child of div middle
|
269
|
+
@div_middle.insert_before("//div[@class='middle']/*[1]", temp)
|
270
|
+
@current = temp
|
271
|
+
raise "Block argument is mandatory" unless block_given?
|
272
|
+
text = block.call()
|
273
|
+
@current.text = text
|
274
|
+
return @current
|
275
|
+
end
|
238
276
|
|
277
|
+
# Helper Method for the highlight methods. it will introduce specific xhtml tags around parts of a text child of an xml element.
|
278
|
+
# @example
|
279
|
+
# we have the following xml part
|
280
|
+
# <test>
|
281
|
+
# some arbitrary
|
282
|
+
# text child content
|
283
|
+
# </test>
|
284
|
+
# now we call replace_text_with_elements to place <span> around the word "arbitrary"
|
285
|
+
# =>
|
286
|
+
# <test>
|
287
|
+
# some <span>arbitrary</span>
|
288
|
+
# text child content
|
289
|
+
# </test>
|
239
290
|
# @param element [REXML::Element] the element in whose text tags will be added at the specified indices of @index_length_array
|
240
291
|
# @param parent [REXML::Element] the parent to which @element should be attached after parsing
|
241
292
|
# @param tagname [String] the tag that will be introduced as <tagname> at the indices specified
|
242
293
|
# @param attribs [Hash] Attributes that will be added to the inserted tag e.g. <tagname attrib="test">
|
243
294
|
# @param index_length_array [Array] Array of the form [[index, lenght], [index, lenght], ...] that specifies
|
244
295
|
# the start position and length of the substring around which the tags will be introduced
|
245
|
-
def
|
296
|
+
def replace_text_with_elements(parent, element, tagname, attribs, index_length_array)
|
246
297
|
last_end = 0
|
247
298
|
index = 0
|
248
299
|
#puts index_length_array.inspect
|
@@ -275,7 +326,7 @@ end
|
|
275
326
|
|
276
327
|
end
|
277
328
|
|
278
|
-
#private_instance_methods(:
|
329
|
+
#private_instance_methods(:replace_text_with_elements)
|
279
330
|
|
280
331
|
end
|
281
332
|
|
@@ -1,2 +1 @@
|
|
1
|
-
|
2
|
-
$(document).ready(function(){$("td").each(function(b){b=$(this);null!==b.html().match(/passed/)&&b.attr("style","background-color:#00FF00;");null!==b.html().match(/failed/)&&b.attr("style","background-color:#FF0000;")});$("[class=rtoconly],[class=bothtoc]").each(function(b){var a=$(this);type=a.attr("class");a.attr("id",type+b);$("#rtoc").append("<a href='#"+type+b+"'>"+a.html()+"</a> <br />\n")});h3index=h2index=h1index=0;$("h1, h2, h3, a.h2, a.h1").each(function(b){var a=$(this);void 0==a.attr("id")&& a.attr("id","title"+b);if("h1"==a.prop("tagName"))h1index+=1,h3index=h2index=0,a.prepend(h1index+" "),$("#ltoc").append("<br />\n"),lasth1="#"+a.attr("id"),lasth1cont=a.html();else if("h2"==a.prop("tagName"))h2index+=1,h3index=0,a.prepend(h1index+"."+h2index+" "),lasth2="#"+a.attr("id"),lasth2cont=a.html();else if("h3"==a.prop("tagName"))h3index+=1,a.prepend(h1index+"."+h2index+"."+h3index+" ");else{if("h1"==a.attr("class"))return a.attr("href",lasth1),a.html(lasth1cont),0;if("h2"==a.attr("class"))return a.attr("href", lasth2),a.html(lasth2cont),0}if("rtoconly"==a.attr("class"))return 0;$("#ltoc").append("<a id='link"+b+"' href='#"+a.attr("id")+"' >"+a.html()+"</a> <br />\n");return 0})});
|
1
|
+
$(document).ready(function(){$("td").each(function(b){b=$(this);null!==b.html().match(/passed/)&&b.attr("style","background-color:#00FF00;");null!==b.html().match(/failed/)&&b.attr("style","background-color:#FF0000;")});$("[class=rtoconly],[class=bothtoc]").each(function(b){var a=$(this);type=a.attr("class");a.attr("id",type+b);$("#rtoc").append("<a href='#"+type+b+"'>"+a.html()+"</a> <br />\n")});h3index=h2index=h1index=0;$("h1, h2, h3, a.h2, a.h1").each(function(b){var a=$(this);void 0==a.attr("id")&&a.attr("id","title"+b);if("h1"==a.prop("tagName"))h1index+=1,h3index=h2index=0,a.prepend(h1index+" "),$("#ltoc").append("<br />\n"),lasth1="#"+a.attr("id"),lasth1cont=a.html();else if("h2"==a.prop("tagName"))h2index+=1,h3index=0,a.prepend(h1index+"."+h2index+" "),lasth2="#"+a.attr("id"),lasth2cont=a.html();else if("h3"==a.prop("tagName"))h3index+=1,a.prepend(h1index+"."+h2index+"."+h3index+" ");else{if("h1"==a.attr("class"))return a.attr("href",lasth1),a.html(lasth1cont),0;if("h2"==a.attr("class"))return a.attr("href",lasth2),a.html(lasth2cont),0}if("rtoconly"==a.attr("class"))return 0;$("#ltoc").append("<a id='link"+b+"' href='#"+a.attr("id")+"' >"+a.html()+"</a> <br />\n");return 0})});
|
metadata
CHANGED
@@ -1,61 +1,64 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xhtml_report_generator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Manuel Widmer
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date: 2015-
|
12
|
+
date: 2015-08-19 00:00:00.000000000 Z
|
12
13
|
dependencies: []
|
13
|
-
description: "The generator can be used to create xhtml files. It comes with some
|
14
|
+
description: ! "The generator can be used to create xhtml files. It comes with some
|
14
15
|
default utility functions.\n== Here is an example usage\n gen1 = XhtmlReportGenerator::Generator.new\n
|
15
|
-
\ gen1.
|
16
|
-
\"
|
17
|
-
\
|
18
|
-
>red span test</span>\", {\"class\"=>\"bold\"}
|
19
|
-
function: Hallo welt <br /> html test <span class=\"r\" >red span test</span></p>\")\n
|
20
|
-
javascript to render the table of contents,
|
21
|
-
sheet all can be\nsupplied by your own,
|
16
|
+
\ gen1.create_layout(\"Title\")\n gen1.heading(\"h1\", {\"class\" => \"bothtoc\"})
|
17
|
+
{\"titel\"}\n gen1.heading(\"h2\") {\"subtitel\"}\n gen1.heading(\"h3\") {\"section\"}\n
|
18
|
+
\ gen1.content() {\"content function: Hallo welt <br /> html test <span class=\"r\"
|
19
|
+
>red span test</span>\", {\"class\"=>\"bold\"}}\n gen1.html(\"<p class=\"italic\">html
|
20
|
+
function: Hallo welt <br /> html test <span class=\"r\" >red span test</span></p>\")\n
|
21
|
+
\ gen1.highlight(/Ha.*lt/)\n \nThe javascript to render the table of contents,
|
22
|
+
the custom generator functions and style sheet all can be\nsupplied by your own,
|
23
|
+
if necessary. \n"
|
22
24
|
email: m-widmer@gmx.ch
|
23
25
|
executables: []
|
24
26
|
extensions: []
|
25
27
|
extra_rdoc_files: []
|
26
28
|
files:
|
27
|
-
- LICENSE
|
28
|
-
- README.md
|
29
|
-
- lib/xhtml_report_generator.rb
|
30
29
|
- lib/xhtml_report_generator/custom.rb
|
31
30
|
- lib/xhtml_report_generator/jquery.js
|
32
31
|
- lib/xhtml_report_generator/print_template.css
|
33
32
|
- lib/xhtml_report_generator/style_template.css
|
34
33
|
- lib/xhtml_report_generator/toc.js
|
35
34
|
- lib/xhtml_report_generator/version.rb
|
35
|
+
- lib/xhtml_report_generator.rb
|
36
|
+
- LICENSE
|
37
|
+
- README.md
|
36
38
|
homepage: https://rubygems.org/gems/xhtml_report_generator
|
37
39
|
licenses:
|
38
40
|
- MIT
|
39
|
-
metadata: {}
|
40
41
|
post_install_message:
|
41
42
|
rdoc_options: []
|
42
43
|
require_paths:
|
43
44
|
- lib
|
44
45
|
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
+
none: false
|
45
47
|
requirements:
|
46
|
-
- - '>='
|
48
|
+
- - ! '>='
|
47
49
|
- !ruby/object:Gem::Version
|
48
50
|
version: 1.8.7
|
49
51
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
50
53
|
requirements:
|
51
|
-
- - '>='
|
54
|
+
- - ! '>='
|
52
55
|
- !ruby/object:Gem::Version
|
53
56
|
version: '0'
|
54
57
|
requirements: []
|
55
58
|
rubyforge_project:
|
56
|
-
rubygems_version:
|
59
|
+
rubygems_version: 1.8.30
|
57
60
|
signing_key:
|
58
|
-
specification_version:
|
61
|
+
specification_version: 3
|
59
62
|
summary: A simple and quick xhtml report generator
|
60
63
|
test_files: []
|
61
64
|
has_rdoc:
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: 8245325d398df596821aad2471b7fe703e541f1c
|
4
|
-
data.tar.gz: 8090a12abf591da6ee1f7af51483f142228dd029
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: f1195b1d581cfc0c25c47d077603e8f53a77e85d79e0ad28f5805a62464bd7427f040fafd6405fd112f390f69f6428b721c109e2dfdb9d9481796ddb1f8095ef
|
7
|
-
data.tar.gz: 39a0c261ac28951b05c1ed55bea11111f0cb00f66e0696cde7b800ee07ba1b9a0e6b1b55b3f9af1c27809d0c1b00e0569a44643edc826bb87ac18b24f5640316
|