smeagol 0.5.9 → 0.6.0

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.
Files changed (59) hide show
  1. data/.ruby +80 -0
  2. data/.yardopts +9 -0
  3. data/HISTORY.md +147 -0
  4. data/LICENSE.txt +30 -0
  5. data/README.md +132 -26
  6. data/bin/smeagol +9 -39
  7. data/bin/smeagol-init +3 -0
  8. data/bin/smeagol-preview +4 -0
  9. data/bin/smeagol-serve +4 -0
  10. data/bin/smeagol-update +4 -0
  11. data/bin/smeagold +1 -4
  12. data/lib/smeagol.rb +77 -6
  13. data/lib/smeagol/app.rb +121 -75
  14. data/lib/smeagol/cache.rb +43 -24
  15. data/lib/smeagol/cli.rb +166 -0
  16. data/lib/smeagol/config.rb +154 -0
  17. data/lib/smeagol/console.rb +369 -0
  18. data/lib/smeagol/controller.rb +275 -0
  19. data/lib/smeagol/core_ext.rb +12 -0
  20. data/lib/smeagol/gollum/blob_entry.rb +17 -0
  21. data/lib/smeagol/gollum/file.rb +44 -0
  22. data/lib/smeagol/gollum/page.rb +47 -0
  23. data/lib/smeagol/gollum/wiki.rb +31 -0
  24. data/lib/smeagol/helpers/rss.rb +96 -0
  25. data/lib/smeagol/helpers/toc.rb +69 -0
  26. data/lib/smeagol/public/assets/smeagol/gollum.css +716 -0
  27. data/lib/smeagol/public/{smeagol → assets/smeagol}/html5.js +0 -0
  28. data/lib/smeagol/public/{smeagol → assets/smeagol}/pygment.css +0 -0
  29. data/lib/smeagol/public/assets/smeagol/template.css +631 -0
  30. data/lib/smeagol/repository.rb +85 -0
  31. data/lib/smeagol/settings.rb +302 -0
  32. data/lib/smeagol/templates/layouts/page.mustache +19 -0
  33. data/lib/smeagol/templates/layouts/versions.mustache +16 -0
  34. data/lib/smeagol/templates/partials/footer.mustache +17 -0
  35. data/lib/smeagol/templates/partials/header.mustache +47 -0
  36. data/lib/smeagol/templates/settings.yml +64 -0
  37. data/lib/smeagol/version.rb +1 -1
  38. data/lib/smeagol/views/base.rb +188 -27
  39. data/lib/smeagol/views/form.rb +56 -0
  40. data/lib/smeagol/views/page.rb +126 -25
  41. data/lib/smeagol/views/post.rb +51 -0
  42. data/lib/smeagol/views/versions.rb +20 -6
  43. data/lib/smeagol/wiki.rb +25 -45
  44. data/test/helper.rb +72 -8
  45. data/test/test_app.rb +57 -0
  46. data/test/test_cache.rb +10 -11
  47. data/test/test_init.rb +27 -0
  48. data/test/test_update.rb +20 -0
  49. data/test/test_wiki.rb +13 -10
  50. metadata +142 -216
  51. data/bin/smeagol-static +0 -115
  52. data/lib/file.rb +0 -10
  53. data/lib/smeagol/hash.rb +0 -13
  54. data/lib/smeagol/option_parser.rb +0 -138
  55. data/lib/smeagol/public/smeagol/main.css +0 -234
  56. data/lib/smeagol/templates/page.mustache +0 -58
  57. data/lib/smeagol/templates/versions.mustache +0 -50
  58. data/test/test_file.rb +0 -12
  59. data/test/test_hash.rb +0 -18
@@ -0,0 +1,64 @@
1
+ ---
2
+ # Gollum wiki url.
3
+ # e.g. `git@github.com:trans/trans.github.com.wiki.git`
4
+
5
+ wiki_origin: {{ wiki_origin }}
6
+
7
+ # Website address.
8
+ # e.g. `http://trans.github.com`
9
+
10
+ url: {{ url }}
11
+
12
+ # Source site, if applicable.
13
+ # e.g. `http://github.com/trans`
14
+
15
+ source_url: {{ source_url }}
16
+
17
+ # Title of site.
18
+
19
+ title: My Site
20
+
21
+ # Single line description of site.
22
+
23
+ tagline: Welcome to My Site
24
+
25
+ # Detailed description of site.
26
+
27
+ description:
28
+ This is my awesome site.
29
+
30
+ # Webmaster of site.
31
+
32
+ author: {{ author }}
33
+
34
+ # Menu that can be used in site template.
35
+ #
36
+ # e.g.
37
+ #
38
+ # menu:
39
+ # - title: Home
40
+ # href: /
41
+ # - title: Projects
42
+ # href: /Projects/
43
+ # - title: Tools
44
+ # href: /Tools/
45
+ # - title: Reads
46
+ # href: /Reads/
47
+
48
+ menu:
49
+ - title: Home
50
+ href: /
51
+
52
+ # Google analytics tracking id. Could be used for other such
53
+ # services if custom template is used.
54
+
55
+ tracking_id: ~
56
+
57
+ # Include a GitHub "Fork Me" ribbon in corner of page. Entry
58
+ # should give color and position separated by a space.
59
+ # The resulting ribbon will have a link to `source_url`.
60
+ #
61
+ # NOTE: Will be renamed to `github_forkme` or something like that.
62
+
63
+ ribbon: red right
64
+
@@ -1,3 +1,3 @@
1
1
  module Smeagol
2
- VERSION = "0.5.9"
2
+ VERSION = "0.6.0"
3
3
  end
@@ -1,35 +1,80 @@
1
1
  module Smeagol
2
+
2
3
  module Views
4
+
5
+ # Base class for all views.
6
+ #
7
+ # FAQ: Why aren't layouts versioned, i.e. pulled from the git repo
8
+ # like pages and posts? B/c we might want to look at content
9
+ # history, but that doesn't mean we want to look at it via
10
+ # an old layout.
11
+ #
3
12
  class Base < ::Mustache
4
13
  # Initializes a new mustache view template data object.
5
14
  #
6
- # wiki - The wiki that this view represents.
15
+ # master - Master controller, which creates all the views.
16
+ # page - The individual wiki page that this view represents.
17
+ # version - The tagged version of the page.
7
18
  #
8
- # Returns a new view object.
9
- def initialize(wiki, version='master')
10
- @wiki = wiki
19
+ # Returns a new page object.
20
+ def initialize(master, file, version='master')
21
+ @master = master
22
+ @file = file
23
+ @wiki = file.wiki
11
24
  @version = version || 'master'
25
+
26
+ setup_template_path
12
27
  end
28
+
29
+ # The Gollum::Wiki that this view represents.
30
+ attr_reader :wiki
13
31
 
32
+ # The tagged version that is being viewed.
33
+ attr_reader :version
34
+
35
+ #
36
+ def setup_template_path
37
+ # See FAQ for Views::Base class
38
+ dir = ::File.join(wiki.path, settings.partials)
39
+ if ::File.directory?(dir)
40
+ self.class.template_path = dir
41
+ else
42
+ self.class.template_path = ::File.join(LIBDIR, 'templates', 'partials')
43
+ end
44
+ end
45
+
46
+ # The Gollum::Page or Gollum::File that this view represents.
47
+ attr_reader :file
48
+
49
+ #
50
+ def filename
51
+ file.filename
52
+ end
53
+
54
+ # Page name.
55
+ def name
56
+ file.name
57
+ end
58
+
14
59
  # Public: The title of the wiki. This is set in the settings file.
15
60
  def wiki_title
16
- wiki.settings.title
61
+ settings.title
17
62
  end
18
-
63
+
19
64
  # Public: The tagline for the wiki. This is set in the settings file.
20
65
  def tagline
21
- wiki.settings.tagline
66
+ settings.tagline
22
67
  end
23
68
 
24
69
  # Public: The URL of the project source code. This is set in the settings
25
70
  # file.
26
71
  def source_url
27
- wiki.settings.source_url
72
+ settings.source_url
28
73
  end
29
74
 
30
75
  # Public: The Google Analytics tracking id from the settings file.
31
76
  def tracking_id
32
- wiki.settings.tracking_id
77
+ settings.tracking_id
33
78
  end
34
79
 
35
80
  # Public: The HTML menu generated from the settings.yml file.
@@ -38,12 +83,13 @@ module Smeagol
38
83
  if !menu.nil?
39
84
  html = "<ul>\n"
40
85
  menu.each do |item|
41
- if version != 'master' && item.href.index('/') == 0
42
- prefix = "/#{version}"
86
+ title, href = item['title'], item['href']
87
+ if version != 'master' && item['href'].index('/') == 0
88
+ prefix = version.start_with?('v') ? "/#{version}" : "/v#{version}"
43
89
  else
44
90
  prefix = ""
45
91
  end
46
- html << "<li><a href=\"#{prefix}#{item.href}\">#{item.title}</a></li>\n"
92
+ html << "<li class=\"minibutton\"><a href=\"#{prefix}#{href}\">#{title}</a></li>\n"
47
93
  end
48
94
  html << "</ul>\n"
49
95
  end
@@ -62,23 +108,38 @@ module Smeagol
62
108
  end
63
109
  end
64
110
 
111
+ # Public: The string base path to prefix internal links.
112
+ def base_path
113
+ wiki.base_path
114
+ end
65
115
 
66
- ##########################################################################
67
- #
68
- # Internal Methods
69
- #
70
- ##########################################################################
71
-
72
- protected
73
-
74
- # The Gollum::Wiki that this view represents.
75
- attr_reader :wiki
76
-
77
- # The tagged version that is being viewed.
78
- attr_reader :version
79
-
116
+ # List of posts.
117
+ def posts
118
+ @posts ||= @master.posts
119
+ #@posts ||= (
120
+ # filter(@wiki.pages){ |p| p.post? }.map do |page|
121
+ # Smeagol::Views::Post.new(page, @version)
122
+ # end
123
+ #)
124
+ end
80
125
 
81
- private
126
+ =begin
127
+ #
128
+ def filter(paths, &selection)
129
+ result = []
130
+ paths.map do |file|
131
+ unless settings.include.any?{ |x| File.fnmatch?(x, file.path) }
132
+ next if file.path.split('/').any? do |x|
133
+ x.start_with?('_') or x.start_with?('.')
134
+ end
135
+ next if settings.exclude.any?{ |x| File.fnmatch?(x, file.path) }
136
+ end
137
+ result << file
138
+ end
139
+ result = result.select(&selection)
140
+ result
141
+ end
142
+ =end
82
143
 
83
144
  # Generates the correct ribbon url
84
145
  def ribbon_url(name, pos)
@@ -89,6 +150,106 @@ module Smeagol
89
150
  name
90
151
  end
91
152
  end
153
+
154
+ # TODO: Actual slug support ?
155
+ #def slug(page,blob)
156
+ # date = page.version.authored_date
157
+ # name = blob.name[name.index(/[A-Za-z]/)..-1]
158
+ #
159
+ # if slug = @wiki.settings.slug
160
+ # slug = date.strftime(slug)
161
+ # slug = slug.sub(':name', name)
162
+ # else
163
+ # slug = name
164
+ # end
165
+ # slug
166
+ #end
167
+
168
+ # Get the layout template for the view.
169
+ def layout
170
+ return nil if custom_layout? && !custom_layout
171
+ custom_layout || standard_layout || default_layout
172
+ end
173
+
174
+ # Does the metadata specify a custom layout?
175
+ def custom_layout?
176
+ metadata.key?('layout')
177
+ end
178
+
179
+ # Value of layout metadata setting.
180
+ def custom_layout
181
+ metadata['layout']
182
+ end
183
+
184
+ # The Mustache template to use for rendering.
185
+ #
186
+ # Returns the content of the specified template file in the
187
+ # wiki repository if it exists. Otherwise, it returns `nil`.
188
+ def standard_layout
189
+ name = metadata['layout'] || 'page.mustache'
190
+ dir = ::File.expand_path(::File.join(wiki.path, ::File.dirname(file.path)))
191
+ root = ::File.expand_path(wiki.path)
192
+ home = ::File.expand_path('~')
193
+ layout = nil
194
+ loop do
195
+ f = ::File.join(dir, '_layouts', name)
196
+ break (layout = IO.read(f)) if ::File.exist?(f)
197
+ break nil if dir == root
198
+ break nil if dir == home # just in case
199
+ break nil if dir == '/'
200
+ dir = ::File.dirname(dir)
201
+ end
202
+ return layout
203
+ #names.each do |name|
204
+ # file = "#{@wiki.path}/#{settings.layout_dir}/#{name}.mustache"
205
+ # if ::File.exists?(file)
206
+ # return IO.read(file)
207
+ # end
208
+ #end
209
+ #nil
210
+ end
211
+
212
+ # Default template.
213
+ #
214
+ # Returns [String] The template included with the Smeagol package.
215
+ def default_layout
216
+ @default_layout ||= (
217
+ IO.read(LIBDIR + "/templates/layouts/page.mustache")
218
+ )
219
+ end
220
+
221
+ #
222
+ def post?
223
+ false
224
+ end
225
+
226
+ # Support mathjax?
227
+ def mathjax
228
+ settings.mathjax
229
+ end
230
+
231
+ #
232
+ def settings
233
+ @master.settings
234
+ end
235
+
236
+ # Embedded metadata.
237
+ #
238
+ # TODO: Can use file.metadata in future version of Gollum.
239
+ #
240
+ # Returns [Hash] of metadata.
241
+ def metadata
242
+ @metadata ||= (
243
+ if md = /\<\!\-\-\-(.*?)\-{2,3}\>\s*\Z/m.match(content)
244
+ YAML.load(md[1])
245
+ else
246
+ {}
247
+ end
248
+ )
249
+ end
250
+
92
251
  end
252
+
93
253
  end
254
+
94
255
  end
@@ -0,0 +1,56 @@
1
+ module Smeagol
2
+
3
+ module Views
4
+
5
+ # The form view is used for generic files that are not
6
+ # Gollum wiki pages. These are typically html or xml
7
+ # files and they are rendered as mustache templates.
8
+ #
9
+ class Form < Base
10
+
11
+ # The Gollum::File that this view represents. This is
12
+ # the same as `#file`.
13
+ alias form file
14
+
15
+ # Public: Rendered content of the file.
16
+ def content
17
+ @content ||= Mustache.render(file.raw_data, self)
18
+ end
19
+
20
+ #
21
+ def title
22
+ filename # TODO: better idea for form title?
23
+ end
24
+ alias_method :page_title, :title
25
+
26
+ #
27
+ #def content=(text)
28
+ # @content = text
29
+ #end
30
+
31
+ # Public: A flag stating that this is not the home file.
32
+ def not_home?
33
+ filename != "index.html"
34
+ end
35
+
36
+ # Public: static href, used when generating static site.
37
+ def href
38
+ dir = ::File.dirname(file.path)
39
+ ext = ::File.extname(file.path)
40
+
41
+ if dir != '.'
42
+ ::File.join(dir, name.chomp(ext)) #file.path)
43
+ else
44
+ if name == settings.index #|| 'Home'
45
+ 'index.html'
46
+ else
47
+ name.chomp(ext) #file.path
48
+ end
49
+ end
50
+ end
51
+
52
+ end #Form
53
+
54
+ end
55
+
56
+ end
@@ -1,27 +1,32 @@
1
1
  module Smeagol
2
+
2
3
  module Views
4
+
3
5
  class Page < Base
4
- # Initializes a new page template data object.
5
- #
6
- # page - The individual wiki page that this view represents.
7
- # version - The tagged version of the page.
8
- #
9
- # Returns a new page object.
10
- def initialize(page, version='master')
11
- super(page.wiki, version)
12
- @page = page
13
- end
14
-
6
+
7
+ # The Gollum::Page that this view represents. This is
8
+ # the same as `#file`.
9
+ alias page file
10
+
15
11
  # Public: The title of the page.
16
- def page_title
12
+ def title
17
13
  page.title
18
14
  end
19
-
15
+
16
+ # TODO: temporary alias
17
+ alias_method :page_title, :title
18
+
20
19
  # Public: The HTML formatted content of the page.
21
20
  def content
22
21
  page.formatted_data
23
22
  end
24
23
 
24
+ #
25
+ def summary
26
+ i = content.index('</p>')
27
+ i ? content[0..i+3] : content # any other way if no i, 5 line limit?
28
+ end
29
+
25
30
  # Public: The last author of this page.
26
31
  def author
27
32
  page.version.author.name
@@ -29,25 +34,121 @@ module Smeagol
29
34
 
30
35
  # Public: The last edit date of this page.
31
36
  def date
32
- page.version.authored_date.strftime("%B %d, %Y")
37
+ post_date || commit_date
38
+ end
39
+
40
+ # Public: The last edit date of this page.
41
+ def commit_date
42
+ page.version.authored_date.strftime(settings.date_format)
33
43
  end
34
-
44
+
35
45
  # Public: A flag stating that this is not the home page.
36
46
  def not_home?
37
- page.title != "Home"
47
+ page.title != "Home" # settings.index
38
48
  end
39
49
 
40
-
41
- ##########################################################################
50
+ # Public: static href, used when generating static site.
51
+ def href
52
+ dir = ::File.dirname(page.path)
53
+ name = slug(page.filename_stripped)
54
+ ext = ::File.extname(page.path)
55
+
56
+ if dir != '.'
57
+ ::File.join(dir, name, 'index.html')
58
+ else
59
+ if name == settings.index #|| 'Home'
60
+ 'index.html'
61
+ else
62
+ ::File.join(name, 'index.html')
63
+ end
64
+ end
65
+ end
66
+
67
+ # Internal: Apply slug rules to name.
42
68
  #
43
- # Internal Methods
69
+ # TODO: Support configurable slugs.
44
70
  #
45
- ##########################################################################
46
-
47
- private
48
-
49
- # The Gollum::Page that this view represents.
50
- attr_reader :page
71
+ # Returns [String] Sluggified name.
72
+ def slug(name)
73
+ if /^\d\d+\-/ =~ name
74
+ dirs = []
75
+ parts = name.split('-')
76
+ while /^\d+$/ =~ parts.first
77
+ dirs << parts.shift
78
+ end
79
+ dirs << parts.join('-')
80
+ dirs.join('/')
81
+ else
82
+ name
83
+ end
84
+ end
85
+
86
+ # If the name of the page begins with a date, then it is the "post date"
87
+ # and is taken to be a blog entry, rather then an ordinary static page.
88
+ def post_date
89
+ if md = /^(\d\d\d\d-\d\d-\d\d)/.match(filename)
90
+ Time.parse(md[1]).strftime(settings.date_format)
91
+ end
92
+ end
93
+
94
+ #
95
+ def post?
96
+ /^(\d\d\d\d-\d\d-\d\d)/.match(filename)
97
+ end
98
+
99
+ def has_header
100
+ @header = (@page.header || false) if @header.nil?
101
+ !!@header
102
+ end
103
+
104
+ def header_content
105
+ has_header && @header.formatted_data
106
+ end
107
+
108
+ def header_format
109
+ has_header && @header.format.to_s
110
+ end
111
+
112
+ def has_footer
113
+ @footer = (@page.footer || false) if @footer.nil?
114
+ !!@footer
115
+ end
116
+
117
+ def footer_content
118
+ has_footer && @footer.formatted_data
119
+ end
120
+
121
+ def footer_format
122
+ has_footer && @footer.format.to_s
123
+ end
124
+
125
+ def has_sidebar
126
+ @sidebar = (@page.sidebar || false) if @sidebar.nil?
127
+ !!@sidebar
128
+ end
129
+
130
+ def sidebar_content
131
+ has_sidebar && @sidebar.formatted_data
132
+ end
133
+
134
+ def sidebar_format
135
+ has_sidebar && @sidebar.format.to_s
136
+ end
137
+
138
+ def has_toc
139
+ !@toc_content.nil?
140
+ end
141
+
142
+ def toc_content
143
+ @toc_content
144
+ end
145
+
146
+ def mathjax
147
+ @mathjax
148
+ end
149
+
51
150
  end
151
+
52
152
  end
153
+
53
154
  end