madness 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/styles/_anchor.scss +15 -15
- data/app/styles/_breadcrumbs.scss +8 -8
- data/app/styles/_code.scss +54 -54
- data/app/styles/_coderay.scss +9 -9
- data/app/styles/_general.scss +33 -33
- data/app/styles/_image.scss +7 -7
- data/app/styles/_keyboard.scss +14 -14
- data/app/styles/_line.scss +28 -28
- data/app/styles/_list.scss +44 -44
- data/app/styles/_manifest.scss +14 -14
- data/app/styles/_nav.scss +35 -35
- data/app/styles/_search.scss +24 -24
- data/app/styles/_table.scss +28 -28
- data/app/styles/_typography.scss +62 -62
- data/app/styles/main.scss +28 -28
- data/app/views/_breadcrumbs.slim +8 -8
- data/app/views/_content.slim +6 -6
- data/app/views/_index_nav.slim +5 -5
- data/app/views/_nav.slim +11 -11
- data/app/views/document.slim +11 -11
- data/app/views/layout.slim +7 -7
- data/app/views/search.slim +25 -25
- data/lib/madness.rb +1 -1
- data/lib/madness/breadcrumbs.rb +36 -36
- data/lib/madness/command_line.rb +77 -77
- data/lib/madness/docopt.txt +40 -40
- data/lib/madness/document.rb +98 -98
- data/lib/madness/navigation.rb +60 -60
- data/lib/madness/search.rb +63 -63
- data/lib/madness/server.rb +39 -39
- data/lib/madness/server_base.rb +36 -36
- data/lib/madness/server_helper.rb +21 -21
- data/lib/madness/settings.rb +65 -65
- data/lib/madness/version.rb +1 -1
- metadata +3 -4
data/lib/madness/navigation.rb
CHANGED
@@ -1,61 +1,61 @@
|
|
1
|
-
module Madness
|
2
|
-
# Handle the navigation links for a given directory
|
3
|
-
class Navigation
|
4
|
-
include ServerHelper
|
5
|
-
|
6
|
-
attr_reader :links, :caption
|
7
|
-
|
8
|
-
def initialize(dir)
|
9
|
-
@links = make_links dir
|
10
|
-
# @caption = File.basename(dir) unless dir == docroot
|
11
|
-
@caption = dir == docroot ? "Index" : File.basename(dir)
|
12
|
-
end
|
13
|
-
|
14
|
-
def with_search?
|
15
|
-
@with_search ||= Search.new.has_index?
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
|
20
|
-
# Prepare a list of links from all the accepted items in the directory
|
21
|
-
def make_links(dir)
|
22
|
-
files = get_files dir
|
23
|
-
dirs = get_dirs dir
|
24
|
-
|
25
|
-
links = []
|
26
|
-
|
27
|
-
dirs.sort.each do |item|
|
28
|
-
links.push link(item, :dir)
|
29
|
-
end
|
30
|
-
|
31
|
-
files.each do |item|
|
32
|
-
links.push link(item, :file)
|
33
|
-
end
|
34
|
-
|
35
|
-
links
|
36
|
-
end
|
37
|
-
|
38
|
-
def get_files(dir)
|
39
|
-
files = Dir["#{dir}/*.md"].map { |f| f.sub(/\.md$/, '') }
|
40
|
-
files.reject! { |f| File.basename(f) == 'README' }
|
41
|
-
files.sort
|
42
|
-
end
|
43
|
-
|
44
|
-
def get_dirs(dir)
|
45
|
-
dirs = Dir["#{dir}/*"].select { |f| File.directory? f }
|
46
|
-
dirs.reject! do |f|
|
47
|
-
basename = File.basename(f)
|
48
|
-
basename[0] == '_' || basename == 'public'
|
49
|
-
end
|
50
|
-
dirs
|
51
|
-
end
|
52
|
-
|
53
|
-
def link(item, type)
|
54
|
-
OpenStruct.new({
|
55
|
-
label: File.basename(item).tr('-', ' '),
|
56
|
-
href: URI.escape(item.sub(/^#{docroot}/, '')),
|
57
|
-
type: type
|
58
|
-
})
|
59
|
-
end
|
60
|
-
end
|
1
|
+
module Madness
|
2
|
+
# Handle the navigation links for a given directory
|
3
|
+
class Navigation
|
4
|
+
include ServerHelper
|
5
|
+
|
6
|
+
attr_reader :links, :caption
|
7
|
+
|
8
|
+
def initialize(dir)
|
9
|
+
@links = make_links dir
|
10
|
+
# @caption = File.basename(dir) unless dir == docroot
|
11
|
+
@caption = dir == docroot ? "Index" : File.basename(dir)
|
12
|
+
end
|
13
|
+
|
14
|
+
def with_search?
|
15
|
+
@with_search ||= Search.new.has_index?
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
# Prepare a list of links from all the accepted items in the directory
|
21
|
+
def make_links(dir)
|
22
|
+
files = get_files dir
|
23
|
+
dirs = get_dirs dir
|
24
|
+
|
25
|
+
links = []
|
26
|
+
|
27
|
+
dirs.sort.each do |item|
|
28
|
+
links.push link(item, :dir)
|
29
|
+
end
|
30
|
+
|
31
|
+
files.each do |item|
|
32
|
+
links.push link(item, :file)
|
33
|
+
end
|
34
|
+
|
35
|
+
links
|
36
|
+
end
|
37
|
+
|
38
|
+
def get_files(dir)
|
39
|
+
files = Dir["#{dir}/*.md"].map { |f| f.sub(/\.md$/, '') }
|
40
|
+
files.reject! { |f| File.basename(f) == 'README' }
|
41
|
+
files.sort
|
42
|
+
end
|
43
|
+
|
44
|
+
def get_dirs(dir)
|
45
|
+
dirs = Dir["#{dir}/*"].select { |f| File.directory? f }
|
46
|
+
dirs.reject! do |f|
|
47
|
+
basename = File.basename(f)
|
48
|
+
basename[0] == '_' || basename == 'public'
|
49
|
+
end
|
50
|
+
dirs
|
51
|
+
end
|
52
|
+
|
53
|
+
def link(item, type)
|
54
|
+
OpenStruct.new({
|
55
|
+
label: File.basename(item).tr('-', ' '),
|
56
|
+
href: URI.escape(item.sub(/^#{docroot}/, '')),
|
57
|
+
type: type
|
58
|
+
})
|
59
|
+
end
|
60
|
+
end
|
61
61
|
end
|
data/lib/madness/search.rb
CHANGED
@@ -1,63 +1,63 @@
|
|
1
|
-
module Madness
|
2
|
-
|
3
|
-
class Search
|
4
|
-
include ServerHelper
|
5
|
-
include Ferret
|
6
|
-
include Ferret::Index
|
7
|
-
|
8
|
-
def initialize(path=nil)
|
9
|
-
@path = path || docroot
|
10
|
-
end
|
11
|
-
|
12
|
-
def has_index?
|
13
|
-
Dir.exist? index_dir
|
14
|
-
end
|
15
|
-
|
16
|
-
def build_index
|
17
|
-
Dir.mkdir index_dir unless Dir.exist? index_dir
|
18
|
-
|
19
|
-
index = Index.new path: index_dir, create: true
|
20
|
-
|
21
|
-
Dir["#{@path}/**/*.md"].each do |file|
|
22
|
-
index << { file: file, content: File.read(file) }
|
23
|
-
end
|
24
|
-
|
25
|
-
index.optimize()
|
26
|
-
index.close()
|
27
|
-
end
|
28
|
-
|
29
|
-
def search(query)
|
30
|
-
index = Index.new path: index_dir
|
31
|
-
|
32
|
-
results = []
|
33
|
-
index.search_each(query, limit: 20) do |doc_id, score|
|
34
|
-
filename = index[doc_id][:file].sub("#{@path}/", '')[0...-3]
|
35
|
-
highlights = index.highlight "content:(#{query.tr(' ',' OR ')}) ", doc_id, field: :content,
|
36
|
-
pre_tag: "", post_tag: "",
|
37
|
-
excerpt_length: 100
|
38
|
-
|
39
|
-
highlights.map! { |excerpt| CGI.escapeHTML excerpt } if highlights
|
40
|
-
|
41
|
-
results << {
|
42
|
-
score: score,
|
43
|
-
file: filename,
|
44
|
-
label: filename.gsub("/", " / "),
|
45
|
-
highlights: highlights
|
46
|
-
}
|
47
|
-
end
|
48
|
-
|
49
|
-
index.close()
|
50
|
-
results
|
51
|
-
end
|
52
|
-
|
53
|
-
def remove_index_dir
|
54
|
-
return unless Dir.exist? index_dir
|
55
|
-
FileUtils.rm_r index_dir
|
56
|
-
end
|
57
|
-
|
58
|
-
def index_dir
|
59
|
-
"#{@path}/_index"
|
60
|
-
end
|
61
|
-
|
62
|
-
end
|
63
|
-
end
|
1
|
+
module Madness
|
2
|
+
|
3
|
+
class Search
|
4
|
+
include ServerHelper
|
5
|
+
include Ferret
|
6
|
+
include Ferret::Index
|
7
|
+
|
8
|
+
def initialize(path=nil)
|
9
|
+
@path = path || docroot
|
10
|
+
end
|
11
|
+
|
12
|
+
def has_index?
|
13
|
+
Dir.exist? index_dir
|
14
|
+
end
|
15
|
+
|
16
|
+
def build_index
|
17
|
+
Dir.mkdir index_dir unless Dir.exist? index_dir
|
18
|
+
|
19
|
+
index = Index.new path: index_dir, create: true
|
20
|
+
|
21
|
+
Dir["#{@path}/**/*.md"].each do |file|
|
22
|
+
index << { file: file, content: File.read(file) }
|
23
|
+
end
|
24
|
+
|
25
|
+
index.optimize()
|
26
|
+
index.close()
|
27
|
+
end
|
28
|
+
|
29
|
+
def search(query)
|
30
|
+
index = Index.new path: index_dir
|
31
|
+
|
32
|
+
results = []
|
33
|
+
index.search_each(query, limit: 20) do |doc_id, score|
|
34
|
+
filename = index[doc_id][:file].sub("#{@path}/", '')[0...-3]
|
35
|
+
highlights = index.highlight "content:(#{query.tr(' ',' OR ')}) ", doc_id, field: :content,
|
36
|
+
pre_tag: "", post_tag: "",
|
37
|
+
excerpt_length: 100
|
38
|
+
|
39
|
+
highlights.map! { |excerpt| CGI.escapeHTML excerpt } if highlights
|
40
|
+
|
41
|
+
results << {
|
42
|
+
score: score,
|
43
|
+
file: filename,
|
44
|
+
label: filename.gsub("/", " / "),
|
45
|
+
highlights: highlights
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
index.close()
|
50
|
+
results
|
51
|
+
end
|
52
|
+
|
53
|
+
def remove_index_dir
|
54
|
+
return unless Dir.exist? index_dir
|
55
|
+
FileUtils.rm_r index_dir
|
56
|
+
end
|
57
|
+
|
58
|
+
def index_dir
|
59
|
+
"#{@path}/_index"
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
data/lib/madness/server.rb
CHANGED
@@ -1,40 +1,40 @@
|
|
1
|
-
require 'madness/server_base'
|
2
|
-
|
3
|
-
module Madness
|
4
|
-
|
5
|
-
# The Sinatra server
|
6
|
-
class Server < ServerBase
|
7
|
-
get '/_search' do
|
8
|
-
query = params[:q]
|
9
|
-
results = query ? Search.new.search(query) : false
|
10
|
-
nav = Navigation.new docroot
|
11
|
-
slim :search, locals: {
|
12
|
-
nav: nav,
|
13
|
-
results: results
|
14
|
-
}
|
15
|
-
end
|
16
|
-
|
17
|
-
get '/*' do
|
18
|
-
path = params[:splat].first
|
19
|
-
|
20
|
-
doc = Document.new path
|
21
|
-
dir = doc.dir
|
22
|
-
content = doc.content
|
23
|
-
|
24
|
-
nav = Navigation.new(dir)
|
25
|
-
breadcrumbs = Breadcrumbs.new(path).links
|
26
|
-
|
27
|
-
if nav.links.count == 1 and doc.type == :empty
|
28
|
-
redirect to(nav.links.first.href)
|
29
|
-
end
|
30
|
-
|
31
|
-
slim :document, locals: {
|
32
|
-
content: content,
|
33
|
-
type: doc.type,
|
34
|
-
title: doc.title,
|
35
|
-
nav: nav,
|
36
|
-
breadcrumbs: breadcrumbs
|
37
|
-
}
|
38
|
-
end
|
39
|
-
end
|
1
|
+
require 'madness/server_base'
|
2
|
+
|
3
|
+
module Madness
|
4
|
+
|
5
|
+
# The Sinatra server
|
6
|
+
class Server < ServerBase
|
7
|
+
get '/_search' do
|
8
|
+
query = params[:q]
|
9
|
+
results = query ? Search.new.search(query) : false
|
10
|
+
nav = Navigation.new docroot
|
11
|
+
slim :search, locals: {
|
12
|
+
nav: nav,
|
13
|
+
results: results
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
get '/*' do
|
18
|
+
path = params[:splat].first
|
19
|
+
|
20
|
+
doc = Document.new path
|
21
|
+
dir = doc.dir
|
22
|
+
content = doc.content
|
23
|
+
|
24
|
+
nav = Navigation.new(dir)
|
25
|
+
breadcrumbs = Breadcrumbs.new(path).links
|
26
|
+
|
27
|
+
if nav.links.count == 1 and doc.type == :empty
|
28
|
+
redirect to(nav.links.first.href)
|
29
|
+
end
|
30
|
+
|
31
|
+
slim :document, locals: {
|
32
|
+
content: content,
|
33
|
+
type: doc.type,
|
34
|
+
title: doc.title,
|
35
|
+
nav: nav,
|
36
|
+
breadcrumbs: breadcrumbs
|
37
|
+
}
|
38
|
+
end
|
39
|
+
end
|
40
40
|
end
|
data/lib/madness/server_base.rb
CHANGED
@@ -1,36 +1,36 @@
|
|
1
|
-
|
2
|
-
module Madness
|
3
|
-
|
4
|
-
# The base class for the sinatra server.
|
5
|
-
# Initialize what we can here, but since there are values that will
|
6
|
-
# become known only later, the #prepare method is provided.
|
7
|
-
class ServerBase < Sinatra::Application
|
8
|
-
helpers ServerHelper
|
9
|
-
|
10
|
-
Sass::Plugin.options[:template_location] = 'app/styles'
|
11
|
-
Sass::Plugin.options[:css_location] = 'app/public/css'
|
12
|
-
Slim::Engine.set_options pretty: true
|
13
|
-
|
14
|
-
use Sass::Plugin::Rack
|
15
|
-
|
16
|
-
set :root, File.expand_path('../../', __dir__)
|
17
|
-
set :views, File.expand_path('../../app/views', __dir__)
|
18
|
-
set :public_folder, File.expand_path('../../app/public', __dir__)
|
19
|
-
|
20
|
-
# Since we cannot use any config values in the main body of the class,
|
21
|
-
# since they will be updated later, we need to set anything that relys
|
22
|
-
# on the config values just before running the server.
|
23
|
-
# The CommandLine class and the test suite should both call
|
24
|
-
# `Server.prepare` before calling Server.run!
|
25
|
-
def self.prepare
|
26
|
-
use Rack::TryStatic, :root => "#{config.path}/public/", :urls => %w[/]
|
27
|
-
set :bind, config.bind
|
28
|
-
set :port, config.port
|
29
|
-
end
|
30
|
-
|
31
|
-
def self.config
|
32
|
-
Settings.instance
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
end
|
1
|
+
|
2
|
+
module Madness
|
3
|
+
|
4
|
+
# The base class for the sinatra server.
|
5
|
+
# Initialize what we can here, but since there are values that will
|
6
|
+
# become known only later, the #prepare method is provided.
|
7
|
+
class ServerBase < Sinatra::Application
|
8
|
+
helpers ServerHelper
|
9
|
+
|
10
|
+
Sass::Plugin.options[:template_location] = 'app/styles'
|
11
|
+
Sass::Plugin.options[:css_location] = 'app/public/css'
|
12
|
+
Slim::Engine.set_options pretty: true
|
13
|
+
|
14
|
+
use Sass::Plugin::Rack
|
15
|
+
|
16
|
+
set :root, File.expand_path('../../', __dir__)
|
17
|
+
set :views, File.expand_path('../../app/views', __dir__)
|
18
|
+
set :public_folder, File.expand_path('../../app/public', __dir__)
|
19
|
+
|
20
|
+
# Since we cannot use any config values in the main body of the class,
|
21
|
+
# since they will be updated later, we need to set anything that relys
|
22
|
+
# on the config values just before running the server.
|
23
|
+
# The CommandLine class and the test suite should both call
|
24
|
+
# `Server.prepare` before calling Server.run!
|
25
|
+
def self.prepare
|
26
|
+
use Rack::TryStatic, :root => "#{config.path}/public/", :urls => %w[/]
|
27
|
+
set :bind, config.bind
|
28
|
+
set :port, config.port
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.config
|
32
|
+
Settings.instance
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -1,22 +1,22 @@
|
|
1
|
-
module Madness
|
2
|
-
|
3
|
-
# All the methods that we may need inside of any server route.
|
4
|
-
# The module can also be included manually anywhere else.
|
5
|
-
module ServerHelper
|
6
|
-
def config
|
7
|
-
@config ||= Settings.instance
|
8
|
-
end
|
9
|
-
|
10
|
-
def docroot
|
11
|
-
@docroot ||= File.expand_path(config.path, Dir.pwd)
|
12
|
-
end
|
13
|
-
|
14
|
-
def log(obj)
|
15
|
-
#:nocov:
|
16
|
-
open('madness.log', 'a') { |f|
|
17
|
-
f.puts obj.inspect
|
18
|
-
}
|
19
|
-
#:nocov:
|
20
|
-
end
|
21
|
-
end
|
1
|
+
module Madness
|
2
|
+
|
3
|
+
# All the methods that we may need inside of any server route.
|
4
|
+
# The module can also be included manually anywhere else.
|
5
|
+
module ServerHelper
|
6
|
+
def config
|
7
|
+
@config ||= Settings.instance
|
8
|
+
end
|
9
|
+
|
10
|
+
def docroot
|
11
|
+
@docroot ||= File.expand_path(config.path, Dir.pwd)
|
12
|
+
end
|
13
|
+
|
14
|
+
def log(obj)
|
15
|
+
#:nocov:
|
16
|
+
open('madness.log', 'a') { |f|
|
17
|
+
f.puts obj.inspect
|
18
|
+
}
|
19
|
+
#:nocov:
|
20
|
+
end
|
21
|
+
end
|
22
22
|
end
|
data/lib/madness/settings.rb
CHANGED
@@ -1,66 +1,66 @@
|
|
1
|
-
module Madness
|
2
|
-
|
3
|
-
# Handle teh configuration options
|
4
|
-
# Each configuration option has three sources
|
5
|
-
# 1. The default value
|
6
|
-
# 2. The setting as provided in the ./.madness.yml
|
7
|
-
# 3. Any override provided later (for example, by the CommandLine
|
8
|
-
# class)
|
9
|
-
class Settings
|
10
|
-
include Singleton
|
11
|
-
|
12
|
-
attr_accessor :port, :bind, :path, :autoh1,
|
13
|
-
:highlighter, :line_numbers, :index
|
14
|
-
|
15
|
-
def initialize
|
16
|
-
reset
|
17
|
-
end
|
18
|
-
|
19
|
-
# Force reload of the config file, set defaults, and then read from
|
20
|
-
# file.
|
21
|
-
def reset
|
22
|
-
@config_file = nil
|
23
|
-
set_defaults
|
24
|
-
load_from_file if config_file
|
25
|
-
end
|
26
|
-
|
27
|
-
def file_exist?
|
28
|
-
File.exist? filename
|
29
|
-
end
|
30
|
-
|
31
|
-
def filename
|
32
|
-
'.madness.yml'
|
33
|
-
end
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
|
-
def set_defaults
|
38
|
-
self.port = '3000'
|
39
|
-
self.bind = '0.0.0.0'
|
40
|
-
self.path = '.'
|
41
|
-
self.autoh1 = true
|
42
|
-
self.highlighter = true
|
43
|
-
self.line_numbers = true
|
44
|
-
self.index = false
|
45
|
-
end
|
46
|
-
|
47
|
-
def load_from_file
|
48
|
-
config_file.each do |key, value|
|
49
|
-
instance_variable_set("@#{key}", value)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def config_file
|
54
|
-
@config_file ||= config_file!
|
55
|
-
end
|
56
|
-
|
57
|
-
def config_file!
|
58
|
-
if file_exist?
|
59
|
-
YAML.load_file filename
|
60
|
-
else
|
61
|
-
{}
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
end
|
1
|
+
module Madness
|
2
|
+
|
3
|
+
# Handle teh configuration options
|
4
|
+
# Each configuration option has three sources
|
5
|
+
# 1. The default value
|
6
|
+
# 2. The setting as provided in the ./.madness.yml
|
7
|
+
# 3. Any override provided later (for example, by the CommandLine
|
8
|
+
# class)
|
9
|
+
class Settings
|
10
|
+
include Singleton
|
11
|
+
|
12
|
+
attr_accessor :port, :bind, :path, :autoh1,
|
13
|
+
:highlighter, :line_numbers, :index
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
reset
|
17
|
+
end
|
18
|
+
|
19
|
+
# Force reload of the config file, set defaults, and then read from
|
20
|
+
# file.
|
21
|
+
def reset
|
22
|
+
@config_file = nil
|
23
|
+
set_defaults
|
24
|
+
load_from_file if config_file
|
25
|
+
end
|
26
|
+
|
27
|
+
def file_exist?
|
28
|
+
File.exist? filename
|
29
|
+
end
|
30
|
+
|
31
|
+
def filename
|
32
|
+
'.madness.yml'
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def set_defaults
|
38
|
+
self.port = '3000'
|
39
|
+
self.bind = '0.0.0.0'
|
40
|
+
self.path = '.'
|
41
|
+
self.autoh1 = true
|
42
|
+
self.highlighter = true
|
43
|
+
self.line_numbers = true
|
44
|
+
self.index = false
|
45
|
+
end
|
46
|
+
|
47
|
+
def load_from_file
|
48
|
+
config_file.each do |key, value|
|
49
|
+
instance_variable_set("@#{key}", value)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def config_file
|
54
|
+
@config_file ||= config_file!
|
55
|
+
end
|
56
|
+
|
57
|
+
def config_file!
|
58
|
+
if file_exist?
|
59
|
+
YAML.load_file filename
|
60
|
+
else
|
61
|
+
{}
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
66
|
end
|