helphelp 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +21 -0
- data/README +30 -0
- data/Rakefile +8 -0
- data/bin/helphelp +67 -0
- data/lib/helphelp.rb +12 -0
- data/lib/output.rb +205 -0
- data/lib/page.rb +88 -0
- data/lib/parse_error.rb +2 -0
- data/lib/version.rb +5 -0
- data/test/page_test.rb +56 -0
- data/test/test_helper.rb +3 -0
- metadata +80 -0
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
(The MIT License)
|
2
|
+
|
3
|
+
Copyright (c) 2012 SUSE Linux Products GmbH
|
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 all
|
13
|
+
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 THE
|
21
|
+
SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# Helphelp - generating online help
|
2
|
+
|
3
|
+
The helphelp tool takes a directory of files formatted using Markdown [1] and
|
4
|
+
converts it to a set of static HTML pages. It supports the usual Markdown syntax
|
5
|
+
and the extensions provided by Maruku [2].
|
6
|
+
|
7
|
+
The Mardown converted to HTML is inserted into templates provided by helphelp or
|
8
|
+
by the caller on the command line. The support a few additional features like
|
9
|
+
generation of a table of contents.
|
10
|
+
|
11
|
+
The structure of the source directory, its subdirectories, and the files in them
|
12
|
+
is reflected in the generated output. As a convention the tool expects file and
|
13
|
+
directory names to start with a three digit number. This number is used to
|
14
|
+
define the sequence of files in the structure of the online help. The numbers
|
15
|
+
don't show up in the output.
|
16
|
+
|
17
|
+
Source files are expected to have the suffix ".md".
|
18
|
+
|
19
|
+
Picture files which are referenced from the markdown are scaled and copied to
|
20
|
+
the output destination at the same location in the directory hierarchy as they
|
21
|
+
are in the sources.
|
22
|
+
|
23
|
+
There are another few non-Markdown features which are supported in the source
|
24
|
+
files by the helphelp tool. If you insert a "#dir_toc" at the beginning of a
|
25
|
+
line, it is replaced by a table of contents for the content of the subdirectory
|
26
|
+
the file is located.
|
27
|
+
|
28
|
+
|
29
|
+
[1]: http://daringfireball.net/projects/markdown/
|
30
|
+
[2]: http://maruku.rubyforge.org/
|
data/Rakefile
ADDED
data/bin/helphelp
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require File.expand_path('../../lib/helphelp',__FILE__)
|
4
|
+
|
5
|
+
output_dir = "html"
|
6
|
+
do_pull = false
|
7
|
+
input_repo = nil
|
8
|
+
|
9
|
+
opt = OptionParser.new
|
10
|
+
opt.banner = "Usage: helphelp <input-repository>"
|
11
|
+
|
12
|
+
opt.on( "-h", "--help", "Print this message" ) do
|
13
|
+
puts opt
|
14
|
+
exit
|
15
|
+
end
|
16
|
+
|
17
|
+
opt.on( "-o <dir>", "--output-dir <dir>", "Output directory" ) do |value|
|
18
|
+
output_dir = value
|
19
|
+
end
|
20
|
+
|
21
|
+
opt.on( "--pull", "Pull git before creating output" ) do
|
22
|
+
do_pull = true
|
23
|
+
end
|
24
|
+
|
25
|
+
opt.on( "--raw-convert <file>", "Just run the raw markdown conversion on the given file" ) do |file|
|
26
|
+
puts Maruku.new( File.read file ).to_html
|
27
|
+
end
|
28
|
+
|
29
|
+
begin
|
30
|
+
opt.parse!( ARGV )
|
31
|
+
rescue OptionParser::InvalidOption
|
32
|
+
STDERR.puts $!
|
33
|
+
STDERR.puts opt
|
34
|
+
exit
|
35
|
+
end
|
36
|
+
|
37
|
+
if ARGV.size == 1
|
38
|
+
input_repo = ARGV[0]
|
39
|
+
else
|
40
|
+
puts opt
|
41
|
+
exit
|
42
|
+
end
|
43
|
+
|
44
|
+
if do_pull
|
45
|
+
puts "Updating git repository..."
|
46
|
+
cmd = "cd #{File.dirname input_repo}; git pull"
|
47
|
+
system cmd
|
48
|
+
end
|
49
|
+
|
50
|
+
puts "Reading repository #{input_repo}"
|
51
|
+
|
52
|
+
puts "Writing output..."
|
53
|
+
if !output_dir
|
54
|
+
STDERR.puts "You need to specify an output directory."
|
55
|
+
exit 1
|
56
|
+
end
|
57
|
+
|
58
|
+
output = Output.new input_repo
|
59
|
+
|
60
|
+
begin
|
61
|
+
output.create output_dir
|
62
|
+
rescue ParseError => e
|
63
|
+
STDERR.puts "Parse error: e.message"
|
64
|
+
exit 1
|
65
|
+
end
|
66
|
+
|
67
|
+
puts "Done."
|
data/lib/helphelp.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
|
3
|
+
require "haml"
|
4
|
+
require "date"
|
5
|
+
require "maruku"
|
6
|
+
|
7
|
+
require "optparse"
|
8
|
+
|
9
|
+
require File.expand_path('../version', __FILE__)
|
10
|
+
require File.expand_path('../parse_error', __FILE__)
|
11
|
+
require File.expand_path('../page', __FILE__)
|
12
|
+
require File.expand_path('../output', __FILE__)
|
data/lib/output.rb
ADDED
@@ -0,0 +1,205 @@
|
|
1
|
+
class Output
|
2
|
+
|
3
|
+
def initialize input_repo
|
4
|
+
@input_repo = input_repo
|
5
|
+
|
6
|
+
@content_width = 600
|
7
|
+
end
|
8
|
+
|
9
|
+
def create output_dir
|
10
|
+
@output_dir = output_dir
|
11
|
+
|
12
|
+
if !File.exists? output_dir
|
13
|
+
Dir::mkdir output_dir
|
14
|
+
end
|
15
|
+
|
16
|
+
public_source_dir = File.expand_path("_view/public", @input_repo )
|
17
|
+
if File.exists? public_source_dir
|
18
|
+
public_dir = File.expand_path( "public", output_dir )
|
19
|
+
if !File.exists? public_dir
|
20
|
+
Dir::mkdir public_dir
|
21
|
+
end
|
22
|
+
|
23
|
+
cmd = "cp #{public_source_dir}/* #{public_dir}"
|
24
|
+
system cmd
|
25
|
+
end
|
26
|
+
|
27
|
+
@input_path = Array.new
|
28
|
+
@output_path = Array.new
|
29
|
+
|
30
|
+
@root_page = Page.new
|
31
|
+
@root_page.directory_path = @output_path
|
32
|
+
@root_page.level = -1
|
33
|
+
|
34
|
+
process_directory @input_repo, @root_page
|
35
|
+
|
36
|
+
postprocess_page @root_page
|
37
|
+
|
38
|
+
create_pages @root_page
|
39
|
+
end
|
40
|
+
|
41
|
+
def postprocess_page parent_page
|
42
|
+
parent_page.postprocess
|
43
|
+
parent_page.children.each do |page|
|
44
|
+
postprocess_page page
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def process_directory dir, parent_page
|
49
|
+
Dir.entries( dir ).sort.each do |entry|
|
50
|
+
if entry =~ /^\d\d\d_(.*)$/
|
51
|
+
input_name = $1
|
52
|
+
full_name = input_path + "/" + entry
|
53
|
+
if File.directory?( full_name )
|
54
|
+
@input_path.push entry
|
55
|
+
@output_path.push input_name
|
56
|
+
if !File.exists? output_path
|
57
|
+
Dir.mkdir output_path
|
58
|
+
end
|
59
|
+
|
60
|
+
page = Page.new
|
61
|
+
parent_page.add_child page
|
62
|
+
page.directory_path = full_name
|
63
|
+
|
64
|
+
process_directory full_name, page
|
65
|
+
@input_path.pop
|
66
|
+
@output_path.pop
|
67
|
+
else
|
68
|
+
file_basename = nil
|
69
|
+
file_format = nil
|
70
|
+
if input_name =~ /^(.*)\.(.*)$/
|
71
|
+
file_basename = $1
|
72
|
+
file_format = $2
|
73
|
+
if file_format != "md"
|
74
|
+
raise ParseError "Unsupported format '#{file_format}' in file " +
|
75
|
+
"#{input_name}."
|
76
|
+
end
|
77
|
+
else
|
78
|
+
raise ParseError "Input file #{input_name} doesn't have an
|
79
|
+
extension."
|
80
|
+
end
|
81
|
+
|
82
|
+
page = nil
|
83
|
+
if file_basename == "index"
|
84
|
+
page = parent_page
|
85
|
+
else
|
86
|
+
page = Page.new
|
87
|
+
parent_page.add_child page
|
88
|
+
end
|
89
|
+
|
90
|
+
page.file_basename = file_basename
|
91
|
+
page.path = input_path + "/" + entry
|
92
|
+
page.content = File.read( input_path + "/" + entry )
|
93
|
+
page.file_format = file_format
|
94
|
+
|
95
|
+
output_file_name = file_basename + ".html"
|
96
|
+
if ( @output_path.empty? )
|
97
|
+
page.target = output_file_name
|
98
|
+
else
|
99
|
+
page.target = @output_path.join( "/" ) + "/" + output_file_name
|
100
|
+
end
|
101
|
+
page.output_file = output_path + "/" + output_file_name
|
102
|
+
end
|
103
|
+
elsif entry =~ /.*\.png$/
|
104
|
+
cmd = "cp #{input_path}/#{entry} #{output_path}/#{entry}"
|
105
|
+
system cmd
|
106
|
+
cmd = "mogrify -resize #{@content_width}x5000 #{output_path}/#{entry}"
|
107
|
+
STDERR.puts "MOGRIFY: #{cmd}"
|
108
|
+
system cmd
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def create_pages parent_page
|
114
|
+
parent_page.children.each do |page|
|
115
|
+
if page.content
|
116
|
+
create_page page
|
117
|
+
end
|
118
|
+
create_pages page
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def input_path
|
123
|
+
@input_repo + "/" + @input_path.join( "/" )
|
124
|
+
end
|
125
|
+
|
126
|
+
def output_path
|
127
|
+
@output_dir + "/" + @output_path.join( "/" )
|
128
|
+
end
|
129
|
+
|
130
|
+
def create_page page
|
131
|
+
puts "CREATE PAGE #{page.path} #{page.output_file}"
|
132
|
+
@page = page
|
133
|
+
create_file "_view/template.haml", page.output_file
|
134
|
+
end
|
135
|
+
|
136
|
+
def create_file template_name, output_filename
|
137
|
+
template = File.read File.expand_path(template_name, @input_repo )
|
138
|
+
engine = Haml::Engine.new template
|
139
|
+
|
140
|
+
File.open output_filename, "w" do |file|
|
141
|
+
file.puts engine.render( binding )
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def css name
|
146
|
+
"<link rel='stylesheet' href='#{@page.relative_site_root}public/#{name}.css'" +
|
147
|
+
" type='text/css'>"
|
148
|
+
end
|
149
|
+
|
150
|
+
def title
|
151
|
+
@page.title
|
152
|
+
end
|
153
|
+
|
154
|
+
def render_content
|
155
|
+
@out = ""
|
156
|
+
|
157
|
+
doc = Maruku.new @page.content
|
158
|
+
o doc.to_html
|
159
|
+
|
160
|
+
@out
|
161
|
+
end
|
162
|
+
|
163
|
+
def render_toc
|
164
|
+
@out = ""
|
165
|
+
|
166
|
+
on "<h1>Table of contents</h1>"
|
167
|
+
render_toc_section @root_page
|
168
|
+
|
169
|
+
@out
|
170
|
+
end
|
171
|
+
|
172
|
+
def render_toc_section parent_page
|
173
|
+
on "<ul>"
|
174
|
+
parent_page.children.each do |page|
|
175
|
+
o "<li>"
|
176
|
+
title = page.title
|
177
|
+
if page.has_children?
|
178
|
+
title += " >"
|
179
|
+
end
|
180
|
+
if page == @page
|
181
|
+
o "<span class=\"current-page\">#{title}</span>"
|
182
|
+
else
|
183
|
+
if page.title && !page.title.empty?
|
184
|
+
o "<a href='#{@page.relative_site_root}#{page.target}'>#{title}</a>"
|
185
|
+
end
|
186
|
+
end
|
187
|
+
on "</li>"
|
188
|
+
if @page == page || ( page.has_children? && @page.has_parent( page ) )
|
189
|
+
render_toc_section page
|
190
|
+
end
|
191
|
+
end
|
192
|
+
on "</ul>"
|
193
|
+
end
|
194
|
+
|
195
|
+
protected
|
196
|
+
|
197
|
+
def o txt
|
198
|
+
@out += txt.to_s
|
199
|
+
end
|
200
|
+
|
201
|
+
def on txt
|
202
|
+
o txt + "\n"
|
203
|
+
end
|
204
|
+
|
205
|
+
end
|
data/lib/page.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
class Page
|
2
|
+
|
3
|
+
attr_accessor :children, :directory_path, :path, :target, :level,
|
4
|
+
:file_format, :output_file, :parent, :file_basename
|
5
|
+
attr_reader :content, :title
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@level = 0
|
9
|
+
@children = Array.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def add_child child
|
13
|
+
@children.push child
|
14
|
+
child.parent = self
|
15
|
+
child.level = self.level + 1
|
16
|
+
end
|
17
|
+
|
18
|
+
def has_children?
|
19
|
+
!@children.empty?
|
20
|
+
end
|
21
|
+
|
22
|
+
def has_parent p
|
23
|
+
if self.parent == p
|
24
|
+
return true
|
25
|
+
else
|
26
|
+
if self.parent.nil?
|
27
|
+
return false
|
28
|
+
else
|
29
|
+
return self.parent.has_parent p
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def content= content
|
35
|
+
@content = preprocess content
|
36
|
+
end
|
37
|
+
|
38
|
+
def postprocess
|
39
|
+
return unless @content
|
40
|
+
|
41
|
+
out = ""
|
42
|
+
@content.each_line do |line|
|
43
|
+
if line =~ /^#dir_toc/
|
44
|
+
if self.has_children?
|
45
|
+
out += "<ul>"
|
46
|
+
self.children.each do |child|
|
47
|
+
out += "<li>"
|
48
|
+
out += "<a href='#{self.relative_site_root}#{child.target}'>#{child.title}</a>"
|
49
|
+
out += "</li>"
|
50
|
+
end
|
51
|
+
out += "</ul>"
|
52
|
+
end
|
53
|
+
else
|
54
|
+
out += line
|
55
|
+
end
|
56
|
+
end
|
57
|
+
@content = out
|
58
|
+
end
|
59
|
+
|
60
|
+
def relative_site_root
|
61
|
+
out = ""
|
62
|
+
|
63
|
+
effective_level = self.level
|
64
|
+
if self.file_basename == "index"
|
65
|
+
effective_level += 1
|
66
|
+
end
|
67
|
+
|
68
|
+
effective_level.times do
|
69
|
+
out += "../"
|
70
|
+
end
|
71
|
+
|
72
|
+
out
|
73
|
+
end
|
74
|
+
|
75
|
+
protected
|
76
|
+
|
77
|
+
def preprocess content
|
78
|
+
out = ""
|
79
|
+
content.each_line do |line|
|
80
|
+
out += line
|
81
|
+
if !@title && line =~ /^# (.*)$/
|
82
|
+
@title = $1
|
83
|
+
end
|
84
|
+
end
|
85
|
+
out
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
data/lib/parse_error.rb
ADDED
data/test/page_test.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require File.expand_path('../test_helper', __FILE__)
|
2
|
+
|
3
|
+
class PageTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def test_title
|
6
|
+
p = Page.new
|
7
|
+
p.content = "# Hallo"
|
8
|
+
|
9
|
+
assert_equal "Hallo", p.title
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_preprocess
|
13
|
+
content = ""
|
14
|
+
content += "# My Title\n"
|
15
|
+
content += "\n"
|
16
|
+
content += "Some text"
|
17
|
+
content += "\n"
|
18
|
+
content += "## Sub Title\n"
|
19
|
+
content += "\n"
|
20
|
+
content += "# Sneaky wrong title"
|
21
|
+
|
22
|
+
p = Page.new
|
23
|
+
p.content = content
|
24
|
+
|
25
|
+
assert_equal content, p.content
|
26
|
+
assert_equal "My Title", p.title
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_has_parent
|
30
|
+
parent = Page.new
|
31
|
+
child1 = Page.new
|
32
|
+
parent.add_child child1
|
33
|
+
child2 = Page.new
|
34
|
+
parent.add_child child2
|
35
|
+
grandchild11 = Page.new
|
36
|
+
child1.add_child grandchild11
|
37
|
+
grandchild12 = Page.new
|
38
|
+
child1.add_child grandchild12
|
39
|
+
grandchild21 = Page.new
|
40
|
+
child2.add_child grandchild21
|
41
|
+
|
42
|
+
assert_equal true, child1.has_parent( parent )
|
43
|
+
assert_equal true, child2.has_parent( parent )
|
44
|
+
assert_equal true, grandchild11.has_parent( child1 )
|
45
|
+
assert_equal false, grandchild11.has_parent( child2 )
|
46
|
+
assert_equal true, grandchild11.has_parent( parent )
|
47
|
+
assert_equal true, grandchild12.has_parent( child1 )
|
48
|
+
assert_equal true, grandchild12.has_parent( parent )
|
49
|
+
assert_equal false, grandchild12.has_parent( child2 )
|
50
|
+
assert_equal true, grandchild12.has_parent( child1 )
|
51
|
+
assert_equal true, grandchild21.has_parent( child2 )
|
52
|
+
assert_equal false, grandchild21.has_parent( child1 )
|
53
|
+
assert_equal true, grandchild21.has_parent( parent )
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: helphelp
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Cornelius Schumacher
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-03-02 00:00:00 +01:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: |
|
23
|
+
Generator for turning a directory hierarchy of markdown files into a static
|
24
|
+
set of HTML pages. It's targeted at providing online help for web application.
|
25
|
+
|
26
|
+
email: cschum@suse.de
|
27
|
+
executables:
|
28
|
+
- helphelp
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files: []
|
32
|
+
|
33
|
+
files:
|
34
|
+
- README
|
35
|
+
- Rakefile
|
36
|
+
- LICENSE
|
37
|
+
- lib/parse_error.rb
|
38
|
+
- lib/version.rb
|
39
|
+
- lib/helphelp.rb
|
40
|
+
- lib/page.rb
|
41
|
+
- lib/output.rb
|
42
|
+
- bin/helphelp
|
43
|
+
- test/page_test.rb
|
44
|
+
- test/test_helper.rb
|
45
|
+
has_rdoc: true
|
46
|
+
homepage: http://github.com/susestudio/helphelp
|
47
|
+
licenses: []
|
48
|
+
|
49
|
+
post_install_message:
|
50
|
+
rdoc_options: []
|
51
|
+
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
hash: 3
|
60
|
+
segments:
|
61
|
+
- 0
|
62
|
+
version: "0"
|
63
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
hash: 3
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
version: "0"
|
72
|
+
requirements: []
|
73
|
+
|
74
|
+
rubyforge_project:
|
75
|
+
rubygems_version: 1.5.0
|
76
|
+
signing_key:
|
77
|
+
specification_version: 3
|
78
|
+
summary: Online help generator
|
79
|
+
test_files: []
|
80
|
+
|