xhtml_report_generator 0.0.1 → 0.0.2
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
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 38ba586873ac2380d55080740068cfbd34564413
|
4
|
+
data.tar.gz: 794724eeb48ba9c1815fb4087510d1b1d2197e1d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 67ab6ba2bf9fc04633b9ae0304ca80ae2731208b5d61892ffebc8ade79548bd9148ae5d5381589b7f29bf7fd6b9e4098863b6927ab9be33b9c41c5399d75e2c5
|
7
|
+
data.tar.gz: a30a760b5de3eaf866b231ca06c3821a95188b8fb0c4fa0fffdd731f43ba91b922a6cf8ebf09eb5e1de122399e8b17fc91c8a3baae6ed1b85962a1340c109ccc
|
@@ -1,78 +1,78 @@
|
|
1
|
-
# logfile.title("mein title")
|
2
|
-
# logfile.section
|
3
|
-
# logfil.content("mein resultat")
|
4
|
-
# logfile.markup(regexstart, regex end, :yellow)
|
5
|
-
require 'rexml/document'
|
6
|
-
|
7
|
-
module XhtmlReportGenerator
|
8
|
-
class Generator
|
9
|
-
attr_accessor :document
|
10
|
-
# @param opts [Hash]
|
11
|
-
# :jquery if specified, path to a version of jquery, that will be inlined into the html header section
|
12
|
-
# :toc if specified, path to a javascript.js.rb file that contains the magic to generate all
|
13
|
-
# :css if specified, path to a css file that contains the markup rules for your generated reports
|
14
|
-
# :custom_rb if specified, path to a custom Module containing
|
15
|
-
def initialize(opts = {})
|
16
|
-
# define the default values
|
17
|
-
path = File.expand_path("../xhtml_report_generator", __FILE__)
|
18
|
-
symbols = {
|
19
|
-
:jquery => File.expand_path("jquery.js",path),
|
20
|
-
:toc => File.expand_path("toc.js",path),
|
21
|
-
:css => File.expand_path("style_template.css",path),
|
22
|
-
:custom_rb => File.expand_path("custom.rb",path)
|
23
|
-
}
|
24
|
-
# either use the default files provided with the gem, or those provided by the caller
|
25
|
-
symbols = symbols.merge(opts)
|
26
|
-
for key in symbols.keys do
|
27
|
-
# read the contents into the symbols hash
|
28
|
-
symbols[key] = File.read(symbols[key])
|
29
|
-
end
|
30
|
-
# load the custom module and extend it, use instance_eval otherwise the module will affect
|
31
|
-
# all existing Generator classes
|
32
|
-
instance_eval symbols[:custom_rb]
|
33
|
-
|
34
|
-
@document = Generator.createXhtml("Title")
|
35
|
-
head = @document.elements["//head"]
|
36
|
-
# insert the custom css, and javascript files
|
37
|
-
style = head.add_element("style", {"type" => "text/css"})
|
38
|
-
# remove all newlines
|
39
|
-
style.add_text(REXML::CData.new("\n"+symbols[:css].gsub(/\n/, "")+"\n"))
|
40
|
-
|
41
|
-
script = head.add_element("script", {"type" => "text/javascript"})
|
42
|
-
script.add_text(REXML::CData.new("\n"+symbols[:jquery]+"\n"))
|
43
|
-
|
44
|
-
script = head.add_element("script", {"type" => "text/javascript"})
|
45
|
-
script.add_text(REXML::CData.new("\n"+symbols[:toc]+"\n"))
|
46
|
-
end
|
47
|
-
|
48
|
-
# Creates a minimal valid xhtml document including header title and body elements
|
49
|
-
# @param title [String] Title in the header section
|
50
|
-
def self.createXhtml(title)
|
51
|
-
header = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>'
|
52
|
-
header += '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
|
53
|
-
|
54
|
-
doc = REXML::Document.new(header)
|
55
|
-
html = doc.add_element("html", {"xmlns" => "http://www.w3.org/1999/xhtml"})
|
56
|
-
# create header
|
57
|
-
head = html.add_element("head")
|
58
|
-
t = head.add_element("title")
|
59
|
-
t.text = title
|
60
|
-
html.add_element("body")
|
61
|
-
return doc
|
62
|
-
end
|
63
|
-
|
64
|
-
def to_s(indent = 0)
|
65
|
-
output = ""
|
66
|
-
# note transitive is needed to preserve newlines in <pre> tags
|
67
|
-
@document.write(:output=>output,:indent=>indent, :transitive=>true)
|
68
|
-
return output
|
69
|
-
end
|
70
|
-
|
71
|
-
def writeToFile(file, mode='w')
|
72
|
-
File.open(file, "#{mode}:UTF-8") {|f| f.write(self.to_s)}
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
|
78
|
-
|
1
|
+
# logfile.title("mein title")
|
2
|
+
# logfile.section
|
3
|
+
# logfil.content("mein resultat")
|
4
|
+
# logfile.markup(regexstart, regex end, :yellow)
|
5
|
+
require 'rexml/document'
|
6
|
+
|
7
|
+
module XhtmlReportGenerator
|
8
|
+
class Generator
|
9
|
+
attr_accessor :document
|
10
|
+
# @param opts [Hash]
|
11
|
+
# :jquery if specified, path to a version of jquery, that will be inlined into the html header section
|
12
|
+
# :toc if specified, path to a javascript.js.rb file that contains the magic to generate all
|
13
|
+
# :css if specified, path to a css file that contains the markup rules for your generated reports
|
14
|
+
# :custom_rb if specified, path to a custom Module containing
|
15
|
+
def initialize(opts = {})
|
16
|
+
# define the default values
|
17
|
+
path = File.expand_path("../xhtml_report_generator", __FILE__)
|
18
|
+
symbols = {
|
19
|
+
:jquery => File.expand_path("jquery.js",path),
|
20
|
+
:toc => File.expand_path("toc.js",path),
|
21
|
+
:css => File.expand_path("style_template.css",path),
|
22
|
+
:custom_rb => File.expand_path("custom.rb",path)
|
23
|
+
}
|
24
|
+
# either use the default files provided with the gem, or those provided by the caller
|
25
|
+
symbols = symbols.merge(opts)
|
26
|
+
for key in symbols.keys do
|
27
|
+
# read the contents into the symbols hash
|
28
|
+
symbols[key] = File.read(symbols[key])
|
29
|
+
end
|
30
|
+
# load the custom module and extend it, use instance_eval otherwise the module will affect
|
31
|
+
# all existing Generator classes
|
32
|
+
instance_eval symbols[:custom_rb]
|
33
|
+
|
34
|
+
@document = Generator.createXhtml("Title")
|
35
|
+
head = @document.elements["//head"]
|
36
|
+
# insert the custom css, and javascript files
|
37
|
+
style = head.add_element("style", {"type" => "text/css"})
|
38
|
+
# remove all newlines
|
39
|
+
style.add_text(REXML::CData.new("\n"+symbols[:css].gsub(/\n/, "")+"\n"))
|
40
|
+
|
41
|
+
script = head.add_element("script", {"type" => "text/javascript"})
|
42
|
+
script.add_text(REXML::CData.new("\n"+symbols[:jquery]+"\n"))
|
43
|
+
|
44
|
+
script = head.add_element("script", {"type" => "text/javascript"})
|
45
|
+
script.add_text(REXML::CData.new("\n"+symbols[:toc]+"\n"))
|
46
|
+
end
|
47
|
+
|
48
|
+
# Creates a minimal valid xhtml document including header title and body elements
|
49
|
+
# @param title [String] Title in the header section
|
50
|
+
def self.createXhtml(title)
|
51
|
+
header = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>'
|
52
|
+
header += '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
|
53
|
+
|
54
|
+
doc = REXML::Document.new(header)
|
55
|
+
html = doc.add_element("html", {"xmlns" => "http://www.w3.org/1999/xhtml"})
|
56
|
+
# create header
|
57
|
+
head = html.add_element("head")
|
58
|
+
t = head.add_element("title")
|
59
|
+
t.text = title
|
60
|
+
html.add_element("body")
|
61
|
+
return doc
|
62
|
+
end
|
63
|
+
|
64
|
+
def to_s(indent = 0)
|
65
|
+
output = ""
|
66
|
+
# note transitive is needed to preserve newlines in <pre> tags
|
67
|
+
@document.write(:output=>output,:indent=>indent, :transitive=>true)
|
68
|
+
return output
|
69
|
+
end
|
70
|
+
|
71
|
+
def writeToFile(file, mode='w')
|
72
|
+
File.open(file, "#{mode}:UTF-8") {|f| f.write(self.to_s)}
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
|
@@ -62,51 +62,69 @@ module Custom
|
|
62
62
|
def contentBefore(locaiton, text)
|
63
63
|
end
|
64
64
|
|
65
|
-
|
65
|
+
# puts a <span> </span> tag around all captures of the regex
|
66
|
+
# NOTE: nested captures are not supported and don't make sense in this context!!
|
67
|
+
# @param regex [Regexp] a regular expression that will be matched
|
68
|
+
# @param color [String] at this point one of "y", "r", "g", "b" (yellow, red, green, blue) is supported
|
69
|
+
# @param el [REXML::Element] the Element (scope) which will be searched for pattern matches
|
70
|
+
def highlightCaptures(regex, color="y", el = @current)
|
66
71
|
# get all children of the current node
|
67
72
|
arr = el.to_a()
|
73
|
+
# depth first recursion into grand-children
|
74
|
+
for i in arr do
|
75
|
+
# detach from current
|
76
|
+
i.parent = nil
|
77
|
+
if i.class.to_s() == "REXML::Text"
|
78
|
+
# in general a text looks as follows:
|
79
|
+
# .*(matchstring|.*)*
|
80
|
+
|
81
|
+
# We get an array of [[start,length], [start,length], ...] for all our regex SUB-matches
|
82
|
+
positions = i.value().enum_for(:scan, regex).flat_map {
|
83
|
+
# Regexp.last_match is a MatchData object, the index 0 is the entire match and
|
84
|
+
# indices 1..n are the captures (sub expressions)
|
85
|
+
array = Array.new
|
86
|
+
for k in 1..Regexp.last_match.length - 1 do
|
87
|
+
array.push([Regexp.last_match.begin(k),
|
88
|
+
Regexp.last_match.end(k)-Regexp.last_match.begin(k)])
|
89
|
+
end
|
90
|
+
array
|
91
|
+
}
|
92
|
+
replaceTextWithElements(el, i, "span", {"class" => color}, positions)
|
93
|
+
else
|
94
|
+
# for non-text nodes we recurse into it and finally reattach to our parent to preserve ordering
|
95
|
+
highlight(regex, color, i)
|
96
|
+
el.add(i)
|
97
|
+
end # if i.class.to_s() == "REXML::Text"
|
98
|
+
end # for i in arr do
|
99
|
+
|
100
|
+
end
|
68
101
|
|
102
|
+
# puts a <span> </span> tag around all matches of regex
|
103
|
+
# @param regex [Regexp] a regular expression that will be matched
|
104
|
+
# @param color [String] at this point one of "y", "r", "g", "b" (yellow, red, green, blue) is supported
|
105
|
+
# @param el [REXML::Element] the Element (scope) which will be searched for pattern matches
|
106
|
+
def highlight(regex, color="y", el = @current)
|
107
|
+
# get all children of the current node
|
108
|
+
arr = el.to_a()
|
109
|
+
#puts arr.inspect
|
69
110
|
# depth first recursion into grand-children
|
70
111
|
for i in arr do
|
71
112
|
# detach from current
|
72
113
|
i.parent = nil
|
114
|
+
#puts i.class.to_s()
|
73
115
|
if i.class.to_s() == "REXML::Text"
|
74
116
|
# in general a text looks as follows:
|
75
117
|
# .*(matchstring|.*)*
|
118
|
+
|
76
119
|
# We get an array of [[start,length], [start,length], ...] for all our regex matches
|
77
120
|
positions = i.value().enum_for(:scan, regex).map {
|
78
121
|
[Regexp.last_match.begin(0),
|
79
122
|
Regexp.last_match.end(0)-Regexp.last_match.begin(0)]
|
80
123
|
}
|
81
|
-
|
82
|
-
last_end = 0
|
83
|
-
index = 0
|
84
|
-
for j in positions do
|
85
|
-
# reattach normal (unmatched) text
|
86
|
-
if j[0] > last_end
|
87
|
-
text = REXML::Text.new(i.value()[ last_end, j[0] - last_end ])
|
88
|
-
el.add_text(text)
|
89
|
-
end
|
90
|
-
#create the span node with color and add the text to it
|
91
|
-
span = el.add_element(REXML::Element.new("span"), {"class" => color})
|
92
|
-
span.add_text(i.value()[ j[0], j[1] ])
|
93
|
-
last_end = j[0]+j[1]
|
94
|
-
# in the last round check for any remaining text
|
95
|
-
if index == positions.length - 1
|
96
|
-
if last_end < i.value().length
|
97
|
-
text = REXML::Text.new(i.value()[ last_end, i.value().length - last_end ])
|
98
|
-
el.add(text)
|
99
|
-
end
|
100
|
-
end
|
101
|
-
index += 1
|
102
|
-
end # for j in positions do
|
103
|
-
|
104
|
-
# don't forget to reattach the textnode if there are no regex matches at all
|
105
|
-
if index == 0
|
106
|
-
el.add(i)
|
107
|
-
end
|
124
|
+
replaceTextWithElements(el, i, "span", {"class" => color}, positions)
|
108
125
|
else
|
109
|
-
# for non-text nodes we recurse into it and finally
|
126
|
+
# for non-text nodes we recurse into it and finally reattach to our parent to preserve ordering
|
127
|
+
# puts "recurse"
|
110
128
|
highlight(regex, color, i)
|
111
129
|
el.add(i)
|
112
130
|
end # if i.class.to_s() == "REXML::Text"
|
@@ -138,6 +156,48 @@ module Custom
|
|
138
156
|
return @current
|
139
157
|
end
|
140
158
|
|
159
|
+
#
|
160
|
+
# @param element [REXML::Element] the element in whose text tags will be added at the specified indices of @index_length_array
|
161
|
+
# @param parent [REXML::Element] the parent to which @element should be attached after parsing
|
162
|
+
# @param tagname [String] the tag that will be introduced as <tagname> at the indices specified
|
163
|
+
# @param attribs [Hash] Attributes that will be added to the inserted tag e.g. <tagname attrib="test">
|
164
|
+
# @param index_length_array [Array] Array of the form [[index, lenght], [index, lenght], ...] that specifies
|
165
|
+
# the start position and length of the substring around which the tags will be introduced
|
166
|
+
def replaceTextWithElements(parent, element, tagname, attribs, index_length_array)
|
167
|
+
last_end = 0
|
168
|
+
index = 0
|
169
|
+
#puts index_length_array.inspect
|
170
|
+
#puts element.inspect
|
171
|
+
for j in index_length_array do
|
172
|
+
# reattach normal (unmatched) text
|
173
|
+
if j[0] > last_end
|
174
|
+
text = REXML::Text.new(element.value()[ last_end, j[0] - last_end ])
|
175
|
+
parent.add_text(text)
|
176
|
+
end
|
177
|
+
#create the tag node with attributes and add the text to it
|
178
|
+
tag = parent.add_element(REXML::Element.new(tagname), attribs)
|
179
|
+
tag.add_text(element.value()[ j[0], j[1] ])
|
180
|
+
last_end = j[0]+j[1]
|
181
|
+
|
182
|
+
# in the last round check for any remaining text
|
183
|
+
if index == index_length_array.length - 1
|
184
|
+
if last_end < element.value().length
|
185
|
+
text = REXML::Text.new(element.value()[ last_end, element.value().length - last_end ])
|
186
|
+
parent.add(text)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
index += 1
|
190
|
+
end # for j in positions do
|
191
|
+
|
192
|
+
# don't forget to reattach the textnode if there are no regex matches at all
|
193
|
+
if index == 0
|
194
|
+
parent.add(element)
|
195
|
+
end
|
196
|
+
|
197
|
+
end
|
198
|
+
|
199
|
+
#private_instance_methods(:replaceTextWithElements)
|
200
|
+
|
141
201
|
end
|
142
202
|
|
143
203
|
extend Custom
|
@@ -1,166 +1,166 @@
|
|
1
|
-
/* general styles */
|
2
|
-
body {
|
3
|
-
background: #FFFFFF;
|
4
|
-
font: 100% Arial, Helvetica, sans-serif;
|
5
|
-
color: #555555;
|
6
|
-
line-height: 100%;
|
7
|
-
margin: 0;
|
8
|
-
}
|
9
|
-
|
10
|
-
p {
|
11
|
-
background: #FFFFFF;
|
12
|
-
font: 100% Arial, Helvetica, sans-serif;
|
13
|
-
color: #555;
|
14
|
-
line-height: 100%;
|
15
|
-
text-align: left;
|
16
|
-
}
|
17
|
-
|
18
|
-
/***********************
|
19
|
-
div classes
|
20
|
-
************************/
|
21
|
-
div.head {
|
22
|
-
font: 200% Arial, Helvetica, sans-serif, bold;
|
23
|
-
text-align: center;
|
24
|
-
width: 100%;
|
25
|
-
position: fixed;
|
26
|
-
top: 0px;
|
27
|
-
height: 100px;
|
28
|
-
background: #FFFFFF;
|
29
|
-
z-index: 99;
|
30
|
-
}
|
31
|
-
|
32
|
-
/* div.headleft{
|
33
|
-
margin-top:40px;
|
34
|
-
margin-left:20px;
|
35
|
-
float:left;
|
36
|
-
width:20%;
|
37
|
-
}
|
38
|
-
|
39
|
-
div.headmiddle{
|
40
|
-
float:left;
|
41
|
-
width:39%;
|
42
|
-
margin-top:10px;
|
43
|
-
}
|
44
|
-
|
45
|
-
div.headright{
|
46
|
-
float:right;
|
47
|
-
width:40%;
|
48
|
-
margin-top:10px;
|
49
|
-
} */
|
50
|
-
div.overlay {
|
51
|
-
position: fixed;
|
52
|
-
size: auto;
|
53
|
-
display: none;
|
54
|
-
}
|
55
|
-
|
56
|
-
div.lefttoc {
|
57
|
-
position: fixed;
|
58
|
-
width: 25%;
|
59
|
-
/*height:90%;*/
|
60
|
-
top: 100px;
|
61
|
-
left: 5px;
|
62
|
-
bottom: 10px;
|
63
|
-
border: solid 1px #000000;
|
64
|
-
overflow: auto;
|
65
|
-
white-space: nowrap;
|
66
|
-
/*display:none;*/ /*uncomment on the left for printing*/
|
67
|
-
}
|
68
|
-
|
69
|
-
div.middle {
|
70
|
-
position: relative;
|
71
|
-
margin: 100px 160px 0 27%; /*top right bottom left */
|
72
|
-
/* margin: x y = Xpx each - botten and top, ypx each - left and right */
|
73
|
-
}
|
74
|
-
|
75
|
-
div.righttoc {
|
76
|
-
position: fixed;
|
77
|
-
width: 150px;
|
78
|
-
top: 100px;
|
79
|
-
right: 5px;
|
80
|
-
border: solid 1px #000000;
|
81
|
-
/*display:none;*/ /*uncomment on the left for printing*/
|
82
|
-
}
|
83
|
-
|
84
|
-
button {
|
85
|
-
width: 100%;
|
86
|
-
}
|
87
|
-
|
88
|
-
/*code*/
|
89
|
-
pre {
|
90
|
-
background: #E5F1F4;
|
91
|
-
font-size: 80%;
|
92
|
-
border: 1px dotted;
|
93
|
-
}
|
94
|
-
|
95
|
-
/*default highlight yellow*/
|
96
|
-
span {
|
97
|
-
background: #FFFF00;
|
98
|
-
}
|
99
|
-
|
100
|
-
/*red*/
|
101
|
-
span.r {
|
102
|
-
background: #FF0000;
|
103
|
-
}
|
104
|
-
|
105
|
-
/*green*/
|
106
|
-
span.g {
|
107
|
-
background: #00FF00;
|
108
|
-
}
|
109
|
-
/*blue*/
|
110
|
-
span.b {
|
111
|
-
background: #00FFFF;
|
112
|
-
}
|
113
|
-
|
114
|
-
a {
|
115
|
-
text-decoration: none;
|
116
|
-
color: #057fac;
|
117
|
-
}
|
118
|
-
|
119
|
-
a:hover {
|
120
|
-
text-decoration: none;
|
121
|
-
color: #999999;
|
122
|
-
}
|
123
|
-
|
124
|
-
h1 {
|
125
|
-
font-size: 140%;
|
126
|
-
margin: 20px 0px;
|
127
|
-
}
|
128
|
-
|
129
|
-
h2 {
|
130
|
-
font-size: 120%;
|
131
|
-
}
|
132
|
-
|
133
|
-
/* work-around for margin/padding issues with hash-tag links */
|
134
|
-
/* http://css-tricks.com/hash-tag-links-padding/ */
|
135
|
-
h1:before {
|
136
|
-
font-size: 140%;
|
137
|
-
display: block;
|
138
|
-
content: " ";
|
139
|
-
margin-top: -120px;
|
140
|
-
height: 120px;
|
141
|
-
visibility: hidden;
|
142
|
-
}
|
143
|
-
|
144
|
-
h2:before {
|
145
|
-
font-size: 120%;
|
146
|
-
display: block;
|
147
|
-
content: " ";
|
148
|
-
margin-top: -100px;
|
149
|
-
height: 100px;
|
150
|
-
visibility: hidden;
|
151
|
-
}
|
152
|
-
|
153
|
-
h3:before {
|
154
|
-
display: block;
|
155
|
-
content: " ";
|
156
|
-
margin-top: -100px;
|
157
|
-
height: 100px;
|
158
|
-
visibility: hidden;
|
159
|
-
}
|
160
|
-
|
161
|
-
/*End of work-around*/
|
162
|
-
form {
|
163
|
-
margin: 1em 0;
|
164
|
-
padding: .2em 20px;
|
165
|
-
background: #eeeeee;
|
1
|
+
/* general styles */
|
2
|
+
body {
|
3
|
+
background: #FFFFFF;
|
4
|
+
font: 100% Arial, Helvetica, sans-serif;
|
5
|
+
color: #555555;
|
6
|
+
line-height: 100%;
|
7
|
+
margin: 0;
|
8
|
+
}
|
9
|
+
|
10
|
+
p {
|
11
|
+
background: #FFFFFF;
|
12
|
+
font: 100% Arial, Helvetica, sans-serif;
|
13
|
+
color: #555;
|
14
|
+
line-height: 100%;
|
15
|
+
text-align: left;
|
16
|
+
}
|
17
|
+
|
18
|
+
/***********************
|
19
|
+
div classes
|
20
|
+
************************/
|
21
|
+
div.head {
|
22
|
+
font: 200% Arial, Helvetica, sans-serif, bold;
|
23
|
+
text-align: center;
|
24
|
+
width: 100%;
|
25
|
+
position: fixed;
|
26
|
+
top: 0px;
|
27
|
+
height: 100px;
|
28
|
+
background: #FFFFFF;
|
29
|
+
z-index: 99;
|
30
|
+
}
|
31
|
+
|
32
|
+
/* div.headleft{
|
33
|
+
margin-top:40px;
|
34
|
+
margin-left:20px;
|
35
|
+
float:left;
|
36
|
+
width:20%;
|
37
|
+
}
|
38
|
+
|
39
|
+
div.headmiddle{
|
40
|
+
float:left;
|
41
|
+
width:39%;
|
42
|
+
margin-top:10px;
|
43
|
+
}
|
44
|
+
|
45
|
+
div.headright{
|
46
|
+
float:right;
|
47
|
+
width:40%;
|
48
|
+
margin-top:10px;
|
49
|
+
} */
|
50
|
+
div.overlay {
|
51
|
+
position: fixed;
|
52
|
+
size: auto;
|
53
|
+
display: none;
|
54
|
+
}
|
55
|
+
|
56
|
+
div.lefttoc {
|
57
|
+
position: fixed;
|
58
|
+
width: 25%;
|
59
|
+
/*height:90%;*/
|
60
|
+
top: 100px;
|
61
|
+
left: 5px;
|
62
|
+
bottom: 10px;
|
63
|
+
border: solid 1px #000000;
|
64
|
+
overflow: auto;
|
65
|
+
white-space: nowrap;
|
66
|
+
/*display:none;*/ /*uncomment on the left for printing*/
|
67
|
+
}
|
68
|
+
|
69
|
+
div.middle {
|
70
|
+
position: relative;
|
71
|
+
margin: 100px 160px 0 27%; /*top right bottom left */
|
72
|
+
/* margin: x y = Xpx each - botten and top, ypx each - left and right */
|
73
|
+
}
|
74
|
+
|
75
|
+
div.righttoc {
|
76
|
+
position: fixed;
|
77
|
+
width: 150px;
|
78
|
+
top: 100px;
|
79
|
+
right: 5px;
|
80
|
+
border: solid 1px #000000;
|
81
|
+
/*display:none;*/ /*uncomment on the left for printing*/
|
82
|
+
}
|
83
|
+
|
84
|
+
button {
|
85
|
+
width: 100%;
|
86
|
+
}
|
87
|
+
|
88
|
+
/*code*/
|
89
|
+
pre {
|
90
|
+
background: #E5F1F4;
|
91
|
+
font-size: 80%;
|
92
|
+
border: 1px dotted;
|
93
|
+
}
|
94
|
+
|
95
|
+
/*default highlight yellow*/
|
96
|
+
span {
|
97
|
+
background: #FFFF00;
|
98
|
+
}
|
99
|
+
|
100
|
+
/*red*/
|
101
|
+
span.r {
|
102
|
+
background: #FF0000;
|
103
|
+
}
|
104
|
+
|
105
|
+
/*green*/
|
106
|
+
span.g {
|
107
|
+
background: #00FF00;
|
108
|
+
}
|
109
|
+
/*blue*/
|
110
|
+
span.b {
|
111
|
+
background: #00FFFF;
|
112
|
+
}
|
113
|
+
|
114
|
+
a {
|
115
|
+
text-decoration: none;
|
116
|
+
color: #057fac;
|
117
|
+
}
|
118
|
+
|
119
|
+
a:hover {
|
120
|
+
text-decoration: none;
|
121
|
+
color: #999999;
|
122
|
+
}
|
123
|
+
|
124
|
+
h1 {
|
125
|
+
font-size: 140%;
|
126
|
+
margin: 20px 0px;
|
127
|
+
}
|
128
|
+
|
129
|
+
h2 {
|
130
|
+
font-size: 120%;
|
131
|
+
}
|
132
|
+
|
133
|
+
/* work-around for margin/padding issues with hash-tag links */
|
134
|
+
/* http://css-tricks.com/hash-tag-links-padding/ */
|
135
|
+
h1:before {
|
136
|
+
font-size: 140%;
|
137
|
+
display: block;
|
138
|
+
content: " ";
|
139
|
+
margin-top: -120px;
|
140
|
+
height: 120px;
|
141
|
+
visibility: hidden;
|
142
|
+
}
|
143
|
+
|
144
|
+
h2:before {
|
145
|
+
font-size: 120%;
|
146
|
+
display: block;
|
147
|
+
content: " ";
|
148
|
+
margin-top: -100px;
|
149
|
+
height: 100px;
|
150
|
+
visibility: hidden;
|
151
|
+
}
|
152
|
+
|
153
|
+
h3:before {
|
154
|
+
display: block;
|
155
|
+
content: " ";
|
156
|
+
margin-top: -100px;
|
157
|
+
height: 100px;
|
158
|
+
visibility: hidden;
|
159
|
+
}
|
160
|
+
|
161
|
+
/*End of work-around*/
|
162
|
+
form {
|
163
|
+
margin: 1em 0;
|
164
|
+
padding: .2em 20px;
|
165
|
+
background: #eeeeee;
|
166
166
|
}
|
@@ -1,2 +1,2 @@
|
|
1
|
-
// "THE BEER-WARE LICENSE" (Revision 42): m-widmer@gmx wrote this file. As long as you retain this notice you can do whatever you want with this stuff. If we meet some day, and you think this stuff is worth it, you can buy me a beer in return Manuel Widmer
|
1
|
+
// "THE BEER-WARE LICENSE" (Revision 42): m-widmer@gmx wrote this file. As long as you retain this notice you can do whatever you want with this stuff. If we meet some day, and you think this stuff is worth it, you can buy me a beer in return Manuel Widmer
|
2
2
|
$(document).ready(function(){$("[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,5 +1,5 @@
|
|
1
|
-
module XhtmlReportGenerator
|
2
|
-
VERSION = '0.0.
|
3
|
-
end
|
4
|
-
|
1
|
+
module XhtmlReportGenerator
|
2
|
+
VERSION = '0.0.2'
|
3
|
+
end
|
4
|
+
|
5
5
|
puts XhtmlReportGenerator::VERSION
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xhtml_report_generator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Manuel Widmer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-12-
|
11
|
+
date: 2014-12-18 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |
|
14
14
|
Here is an example usage:
|
@@ -28,14 +28,14 @@ executables: []
|
|
28
28
|
extensions: []
|
29
29
|
extra_rdoc_files: []
|
30
30
|
files:
|
31
|
+
- LICENSE
|
32
|
+
- README.md
|
33
|
+
- lib/xhtml_report_generator.rb
|
31
34
|
- lib/xhtml_report_generator/custom.rb
|
32
35
|
- lib/xhtml_report_generator/jquery.js
|
33
36
|
- lib/xhtml_report_generator/style_template.css
|
34
37
|
- lib/xhtml_report_generator/toc.js
|
35
38
|
- lib/xhtml_report_generator/version.rb
|
36
|
-
- lib/xhtml_report_generator.rb
|
37
|
-
- LICENSE
|
38
|
-
- README.md
|
39
39
|
homepage: http://rubygems.org/gems/hrg
|
40
40
|
licenses:
|
41
41
|
- MIT
|
@@ -56,7 +56,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
56
56
|
version: '0'
|
57
57
|
requirements: []
|
58
58
|
rubyforge_project:
|
59
|
-
rubygems_version: 2.
|
59
|
+
rubygems_version: 2.4.5
|
60
60
|
signing_key:
|
61
61
|
specification_version: 4
|
62
62
|
summary: A simple and quick xhtml report generator
|