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 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
+