helphelp 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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/
@@ -0,0 +1,8 @@
1
+ task :default => "test"
2
+
3
+ require 'rake/testtask'
4
+ Rake::TestTask.new(:test) do |test|
5
+ test.libs << 'lib' << 'test'
6
+ test.pattern = 'test/**/*_test.rb'
7
+ test.verbose = true
8
+ end
@@ -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."
@@ -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__)
@@ -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
@@ -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
@@ -0,0 +1,2 @@
1
+ class ParseError < StandardError
2
+ end
@@ -0,0 +1,5 @@
1
+ module Helphelp
2
+
3
+ VERSION = "0.0.1"
4
+
5
+ end
@@ -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
@@ -0,0 +1,3 @@
1
+ require File.expand_path('../../lib/helphelp',__FILE__)
2
+
3
+ require 'test/unit'
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
+