tigefa 1.0.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (249) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.markdown +91 -0
  3. data/Gemfile +2 -0
  4. data/History.markdown +871 -0
  5. data/LICENSE +15 -14
  6. data/README.markdown +59 -0
  7. data/Rakefile +298 -0
  8. data/bin/tigefa +158 -0
  9. data/cucumber.yml +3 -0
  10. data/features/create_sites.feature +141 -0
  11. data/features/data.feature +65 -0
  12. data/features/drafts.feature +25 -0
  13. data/features/embed_filters.feature +60 -0
  14. data/features/include_tag.feature +57 -0
  15. data/features/markdown.feature +67 -0
  16. data/features/pagination.feature +82 -0
  17. data/features/permalinks.feature +85 -0
  18. data/features/post_data.feature +214 -0
  19. data/features/post_excerpts.feature +50 -0
  20. data/features/site_configuration.feature +235 -0
  21. data/features/site_data.feature +107 -0
  22. data/features/step_definitions/tigefa_steps.rb +189 -0
  23. data/features/support/env.rb +75 -0
  24. data/lib/site_template/.gitignore +1 -0
  25. data/lib/site_template/_config.yml +3 -0
  26. data/lib/site_template/_layouts/default.html +44 -0
  27. data/lib/site_template/_layouts/post.html +9 -0
  28. data/lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb +24 -0
  29. data/lib/site_template/css/main.css +160 -0
  30. data/lib/site_template/css/syntax.css +60 -0
  31. data/lib/site_template/index.html +13 -0
  32. data/lib/tigefa/cleaner.rb +73 -0
  33. data/lib/tigefa/command.rb +27 -0
  34. data/lib/tigefa/commands/build.rb +70 -0
  35. data/lib/tigefa/commands/doctor.rb +67 -0
  36. data/lib/tigefa/commands/new.rb +67 -0
  37. data/lib/tigefa/commands/serve.rb +65 -0
  38. data/lib/tigefa/configuration.rb +238 -0
  39. data/lib/tigefa/converter.rb +48 -0
  40. data/lib/tigefa/converters/identity.rb +21 -0
  41. data/lib/tigefa/converters/markdown/kramdown_parser.rb +29 -0
  42. data/lib/tigefa/converters/markdown/maruku_parser.rb +56 -0
  43. data/lib/tigefa/converters/markdown/rdiscount_parser.rb +37 -0
  44. data/lib/tigefa/converters/markdown/redcarpet_parser.rb +70 -0
  45. data/lib/tigefa/converters/markdown.rb +43 -0
  46. data/lib/tigefa/converters/textile.rb +50 -0
  47. data/lib/tigefa/convertible.rb +174 -0
  48. data/lib/tigefa/core_ext.rb +90 -0
  49. data/lib/tigefa/deprecator.rb +36 -0
  50. data/lib/tigefa/draft.rb +35 -0
  51. data/lib/tigefa/entry_filter.rb +35 -0
  52. data/lib/tigefa/errors.rb +4 -0
  53. data/lib/tigefa/excerpt.rb +113 -0
  54. data/lib/tigefa/filters.rb +174 -0
  55. data/lib/tigefa/generator.rb +4 -0
  56. data/lib/tigefa/generators/pagination.rb +217 -0
  57. data/lib/tigefa/layout.rb +45 -0
  58. data/lib/tigefa/mime.types +85 -0
  59. data/lib/tigefa/page.rb +160 -0
  60. data/lib/tigefa/plugin.rb +75 -0
  61. data/lib/tigefa/post.rb +312 -0
  62. data/lib/tigefa/related_posts.rb +59 -0
  63. data/lib/tigefa/site.rb +427 -0
  64. data/lib/tigefa/static_file.rb +70 -0
  65. data/lib/tigefa/stevenson.rb +89 -0
  66. data/lib/tigefa/tags/gist.rb +48 -0
  67. data/lib/tigefa/tags/highlight.rb +85 -0
  68. data/lib/tigefa/tags/include.rb +134 -0
  69. data/lib/tigefa/tags/post_url.rb +63 -0
  70. data/lib/tigefa/url.rb +69 -0
  71. data/lib/tigefa.rb +98 -4
  72. data/script/bootstrap +2 -0
  73. data/site/.gitignore +4 -0
  74. data/site/CNAME +1 -0
  75. data/site/README +1 -0
  76. data/site/_config.yml +6 -0
  77. data/site/_includes/analytics.html +32 -0
  78. data/site/_includes/docs_contents.html +16 -0
  79. data/site/_includes/docs_contents_mobile.html +23 -0
  80. data/site/_includes/docs_option.html +11 -0
  81. data/site/_includes/docs_ul.html +20 -0
  82. data/site/_includes/footer.html +15 -0
  83. data/site/_includes/header.html +18 -0
  84. data/site/_includes/news_contents.html +23 -0
  85. data/site/_includes/news_contents_mobile.html +11 -0
  86. data/site/_includes/news_item.html +24 -0
  87. data/site/_includes/primary-nav-items.html +14 -0
  88. data/site/_includes/section_nav.html +22 -0
  89. data/site/_includes/top.html +17 -0
  90. data/site/_layouts/default.html +12 -0
  91. data/site/_layouts/docs.html +23 -0
  92. data/site/_layouts/news.html +19 -0
  93. data/site/_layouts/news_item.html +27 -0
  94. data/site/_posts/2013-05-06-jekyll-1-0-0-released.markdown +23 -0
  95. data/site/_posts/2013-05-08-jekyll-1-0-1-released.markdown +27 -0
  96. data/site/_posts/2013-05-12-jekyll-1-0-2-released.markdown +28 -0
  97. data/site/_posts/2013-06-07-jekyll-1-0-3-released.markdown +25 -0
  98. data/site/_posts/2013-07-14-jekyll-1-1-0-released.markdown +27 -0
  99. data/site/_posts/2013-07-24-jekyll-1-1-1-released.markdown +31 -0
  100. data/site/_posts/2013-07-25-jekyll-1-0-4-released.markdown +20 -0
  101. data/site/_posts/2013-07-25-jekyll-1-1-2-released.markdown +20 -0
  102. data/site/_posts/2013-09-06-jekyll-1-2-0-released.markdown +23 -0
  103. data/site/_posts/2013-09-14-jekyll-1-2-1-released.markdown +19 -0
  104. data/site/_posts/2013-10-28-jekyll-1-3-0-rc1-released.markdown +19 -0
  105. data/site/_posts/2013-11-04-jekyll-1-3-0-released.markdown +43 -0
  106. data/site/_posts/2013-11-26-jekyll-1-3-1-released.markdown +21 -0
  107. data/site/_posts/2013-12-07-jekyll-1-4-0-released.markdown +30 -0
  108. data/site/_posts/2013-12-16-jekyll-1-4-2-released.markdown +18 -0
  109. data/site/_posts/2014-01-13-jekyll-1-4-3-released.markdown +27 -0
  110. data/site/css/gridism.css +110 -0
  111. data/site/css/normalize.css +1 -0
  112. data/site/css/pygments.css +70 -0
  113. data/site/css/style.css +946 -0
  114. data/site/docs/configuration.md +375 -0
  115. data/site/docs/contributing.md +128 -0
  116. data/site/docs/datafiles.md +63 -0
  117. data/site/docs/deployment-methods.md +109 -0
  118. data/site/docs/drafts.md +21 -0
  119. data/site/docs/extras.md +56 -0
  120. data/site/docs/frontmatter.md +180 -0
  121. data/site/docs/github-pages.md +91 -0
  122. data/site/docs/heroku.md +9 -0
  123. data/site/docs/history.md +866 -0
  124. data/site/docs/index.md +52 -0
  125. data/site/docs/installation.md +76 -0
  126. data/site/docs/migrations.md +11 -0
  127. data/site/docs/pages.md +86 -0
  128. data/site/docs/pagination.md +211 -0
  129. data/site/docs/permalinks.md +180 -0
  130. data/site/docs/plugins.md +534 -0
  131. data/site/docs/posts.md +181 -0
  132. data/site/docs/quickstart.md +32 -0
  133. data/site/docs/resources.md +46 -0
  134. data/site/docs/sites.md +29 -0
  135. data/site/docs/structure.md +190 -0
  136. data/site/docs/templates.md +339 -0
  137. data/site/docs/troubleshooting.md +150 -0
  138. data/site/docs/upgrading.md +146 -0
  139. data/site/docs/usage.md +63 -0
  140. data/site/docs/variables.md +322 -0
  141. data/site/favicon.png +0 -0
  142. data/site/feed.xml +36 -0
  143. data/site/freenode.txt +1 -0
  144. data/site/img/article-footer.png +0 -0
  145. data/site/img/footer-arrow.png +0 -0
  146. data/site/img/footer-logo.png +0 -0
  147. data/site/img/logo-2x.png +0 -0
  148. data/site/img/octojekyll.png +0 -0
  149. data/site/img/tube.png +0 -0
  150. data/site/img/tube1x.png +0 -0
  151. data/site/index.html +90 -0
  152. data/site/js/modernizr-2.5.3.min.js +4 -0
  153. data/site/news/index.html +10 -0
  154. data/site/news/releases/index.html +10 -0
  155. data/test/fixtures/broken_front_matter1.erb +5 -0
  156. data/test/fixtures/broken_front_matter2.erb +4 -0
  157. data/test/fixtures/broken_front_matter3.erb +7 -0
  158. data/test/fixtures/exploit_front_matter.erb +4 -0
  159. data/test/fixtures/front_matter.erb +4 -0
  160. data/test/helper.rb +65 -0
  161. data/test/source/+/foo.md +7 -0
  162. data/test/source/.htaccess +8 -0
  163. data/test/source/_config.dev.toml +2 -0
  164. data/test/source/_data/languages.yml +2 -0
  165. data/test/source/_data/members.yaml +7 -0
  166. data/test/source/_data/products.yml +1 -0
  167. data/test/source/_includes/params.html +7 -0
  168. data/test/source/_includes/sig.markdown +3 -0
  169. data/test/source/_includes/tmp +1 -0
  170. data/test/source/_layouts/default.html +27 -0
  171. data/test/source/_layouts/post/simple.html +1 -0
  172. data/test/source/_layouts/simple.html +1 -0
  173. data/test/source/_plugins/dummy.rb +8 -0
  174. data/test/source/_posts/2008-02-02-not-published.textile +8 -0
  175. data/test/source/_posts/2008-02-02-published.textile +8 -0
  176. data/test/source/_posts/2008-10-18-foo-bar.textile +8 -0
  177. data/test/source/_posts/2008-11-21-complex.textile +8 -0
  178. data/test/source/_posts/2008-12-03-permalinked-post.textile +9 -0
  179. data/test/source/_posts/2008-12-13-include.markdown +8 -0
  180. data/test/source/_posts/2009-01-27-array-categories.textile +10 -0
  181. data/test/source/_posts/2009-01-27-categories.textile +7 -0
  182. data/test/source/_posts/2009-01-27-category.textile +7 -0
  183. data/test/source/_posts/2009-01-27-empty-categories.textile +7 -0
  184. data/test/source/_posts/2009-01-27-empty-category.textile +7 -0
  185. data/test/source/_posts/2009-03-12-hash-#1.markdown +6 -0
  186. data/test/source/_posts/2009-05-18-empty-tag.textile +6 -0
  187. data/test/source/_posts/2009-05-18-empty-tags.textile +6 -0
  188. data/test/source/_posts/2009-05-18-tag.textile +6 -0
  189. data/test/source/_posts/2009-05-18-tags.textile +9 -0
  190. data/test/source/_posts/2009-06-22-empty-yaml.textile +3 -0
  191. data/test/source/_posts/2009-06-22-no-yaml.textile +1 -0
  192. data/test/source/_posts/2010-01-08-triple-dash.markdown +5 -0
  193. data/test/source/_posts/2010-01-09-date-override.textile +7 -0
  194. data/test/source/_posts/2010-01-09-time-override.textile +7 -0
  195. data/test/source/_posts/2010-01-09-timezone-override.textile +7 -0
  196. data/test/source/_posts/2010-01-16-override-data.textile +4 -0
  197. data/test/source/_posts/2011-04-12-md-extension.md +7 -0
  198. data/test/source/_posts/2011-04-12-text-extension.text +0 -0
  199. data/test/source/_posts/2013-01-02-post-excerpt.markdown +14 -0
  200. data/test/source/_posts/2013-01-12-nil-layout.textile +6 -0
  201. data/test/source/_posts/2013-01-12-no-layout.textile +5 -0
  202. data/test/source/_posts/2013-03-19-not-a-post.markdown/.gitkeep +0 -0
  203. data/test/source/_posts/2013-04-11-custom-excerpt.markdown +10 -0
  204. data/test/source/_posts/2013-05-10-number-category.textile +7 -0
  205. data/test/source/_posts/2013-07-22-post-excerpt-with-layout.markdown +23 -0
  206. data/test/source/_posts/2013-08-01-mkdn-extension.mkdn +0 -0
  207. data/test/source/_posts/2014-01-06-permalink-traversal.md +5 -0
  208. data/test/source/_posts/es/2008-11-21-nested.textile +8 -0
  209. data/test/source/about.html +6 -0
  210. data/test/source/category/_posts/2008-9-23-categories.textile +6 -0
  211. data/test/source/contacts/bar.html +5 -0
  212. data/test/source/contacts/index.html +5 -0
  213. data/test/source/contacts.html +5 -0
  214. data/test/source/css/screen.css +76 -0
  215. data/test/source/deal.with.dots.html +7 -0
  216. data/test/source/exploit.md +5 -0
  217. data/test/source/foo/_posts/bar/2008-12-12-topical-post.textile +8 -0
  218. data/test/source/index.html +22 -0
  219. data/test/source/products.yml +4 -0
  220. data/test/source/sitemap.xml +32 -0
  221. data/test/source/symlink-test/_data +1 -0
  222. data/test/source/symlink-test/symlinked-dir +1 -0
  223. data/test/source/symlink-test/symlinked-file +1 -0
  224. data/test/source/win/_posts/2009-05-24-yaml-linebreak.markdown +7 -0
  225. data/test/source/z_category/_posts/2008-9-23-categories.textile +6 -0
  226. data/test/suite.rb +11 -0
  227. data/test/test_command.rb +39 -0
  228. data/test/test_configuration.rb +181 -0
  229. data/test/test_convertible.rb +51 -0
  230. data/test/test_core_ext.rb +88 -0
  231. data/test/test_entry_filter.rb +74 -0
  232. data/test/test_excerpt.rb +78 -0
  233. data/test/test_filters.rb +113 -0
  234. data/test/test_generated_site.rb +83 -0
  235. data/test/test_kramdown.rb +62 -0
  236. data/test/test_new_command.rb +104 -0
  237. data/test/test_page.rb +212 -0
  238. data/test/test_pager.rb +116 -0
  239. data/test/test_post.rb +592 -0
  240. data/test/test_rdiscount.rb +22 -0
  241. data/test/test_redcarpet.rb +61 -0
  242. data/test/test_redcloth.rb +86 -0
  243. data/test/test_related_posts.rb +47 -0
  244. data/test/test_site.rb +333 -0
  245. data/test/test_tags.rb +490 -0
  246. data/test/test_url.rb +28 -0
  247. data/tigefa.gemspec +306 -0
  248. metadata +575 -45
  249. data/README.md +0 -4
@@ -0,0 +1,70 @@
1
+ module Tigefa
2
+ module Commands
3
+ class Build < Command
4
+ def self.process(options)
5
+ site = Tigefa::Site.new(options)
6
+
7
+ self.build(site, options)
8
+ self.watch(site, options) if options['watch']
9
+ end
10
+
11
+ # Private: Build the site from source into destination.
12
+ #
13
+ # site - A Tigefa::Site instance
14
+ # options - A Hash of options passed to the command
15
+ #
16
+ # Returns nothing.
17
+ def self.build(site, options)
18
+ source = options['source']
19
+ destination = options['destination']
20
+ Tigefa.logger.info "Source:", source
21
+ Tigefa.logger.info "Destination:", destination
22
+ print Tigefa.logger.formatted_topic "Generating..."
23
+ self.process_site(site)
24
+ puts "done."
25
+ end
26
+
27
+ # Private: Watch for file changes and rebuild the site.
28
+ #
29
+ # site - A Tigefa::Site instance
30
+ # options - A Hash of options passed to the command
31
+ #
32
+ # Returns nothing.
33
+ def self.watch(site, options)
34
+ require 'listen'
35
+
36
+ source = options['source']
37
+ destination = options['destination']
38
+
39
+ begin
40
+ dest = Pathname.new(destination).relative_path_from(Pathname.new(source)).to_s
41
+ ignored = Regexp.new(Regexp.escape(dest))
42
+ rescue ArgumentError
43
+ # Destination is outside the source, no need to ignore it.
44
+ ignored = nil
45
+ end
46
+
47
+ Tigefa.logger.info "Auto-regeneration:", "enabled"
48
+
49
+ listener = Listen::Listener.new(source, :ignore => ignored) do |modified, added, removed|
50
+ t = Time.now.strftime("%Y-%m-%d %H:%M:%S")
51
+ n = modified.length + added.length + removed.length
52
+ print Tigefa.logger.formatted_topic("Regenerating:") + "#{n} files at #{t} "
53
+ self.process_site(site)
54
+ puts "...done."
55
+ end
56
+ listener.start
57
+
58
+ unless options['serving']
59
+ trap("INT") do
60
+ listener.stop
61
+ puts " Halting auto-regeneration."
62
+ exit 0
63
+ end
64
+
65
+ loop { sleep 1000 }
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,67 @@
1
+ module Tigefa
2
+ module Commands
3
+ class Doctor < Command
4
+ class << self
5
+ def process(options)
6
+ site = Tigefa::Site.new(options)
7
+ site.read
8
+
9
+ if healthy?(site)
10
+ Tigefa.logger.info "Your test results", "are in. Everything looks fine."
11
+ else
12
+ abort
13
+ end
14
+ end
15
+
16
+ def healthy?(site)
17
+ [
18
+ !deprecated_relative_permalinks(site),
19
+ !conflicting_urls(site)
20
+ ].all?
21
+ end
22
+
23
+ def deprecated_relative_permalinks(site)
24
+ contains_deprecated_pages = false
25
+ site.pages.each do |page|
26
+ if page.uses_relative_permalinks
27
+ Tigefa.logger.warn "Deprecation:", "'#{page.path}' uses relative" +
28
+ " permalinks which will be deprecated in" +
29
+ " Tigefa v1.2 and beyond."
30
+ contains_deprecated_pages = true
31
+ end
32
+ end
33
+ contains_deprecated_pages
34
+ end
35
+
36
+ def conflicting_urls(site)
37
+ conflicting_urls = false
38
+ urls = {}
39
+ urls = collect_urls(urls, site.pages, site.dest)
40
+ urls = collect_urls(urls, site.posts, site.dest)
41
+ urls.each do |url, paths|
42
+ if paths.size > 1
43
+ conflicting_urls = true
44
+ Tigefa.logger.warn "Conflict:", "The URL '#{url}' is the destination" +
45
+ " for the following pages: #{paths.join(", ")}"
46
+ end
47
+ end
48
+ conflicting_urls
49
+ end
50
+
51
+ private
52
+
53
+ def collect_urls(urls, things, destination)
54
+ things.each do |thing|
55
+ dest = thing.destination(destination)
56
+ if urls[dest]
57
+ urls[dest] << thing.path
58
+ else
59
+ urls[dest] = [thing.path]
60
+ end
61
+ end
62
+ urls
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,67 @@
1
+ require 'erb'
2
+
3
+ module Tigefa
4
+ module Commands
5
+ class New < Command
6
+ def self.process(args, options = {})
7
+ raise ArgumentError.new('You must specify a path.') if args.empty?
8
+
9
+ new_blog_path = File.expand_path(args.join(" "), Dir.pwd)
10
+ FileUtils.mkdir_p new_blog_path
11
+ if preserve_source_location?(new_blog_path, options)
12
+ Tigefa.logger.error "Conflict:", "#{new_blog_path} exists and is not empty."
13
+ exit(1)
14
+ end
15
+
16
+ if options[:blank]
17
+ create_blank_site new_blog_path
18
+ else
19
+ create_sample_files new_blog_path
20
+
21
+ File.open(File.expand_path(self.initialized_post_name, new_blog_path), "w") do |f|
22
+ f.write(self.scaffold_post_content)
23
+ end
24
+ end
25
+
26
+ puts "New tigefa site installed in #{new_blog_path}."
27
+ end
28
+
29
+ def self.create_blank_site(path)
30
+ Dir.chdir(path) do
31
+ FileUtils.mkdir(%w(_layouts _posts _drafts))
32
+ FileUtils.touch("index.html")
33
+ end
34
+ end
35
+
36
+ def self.scaffold_post_content
37
+ ERB.new(File.read(File.expand_path(scaffold_path, site_template))).result
38
+ end
39
+
40
+ # Internal: Gets the filename of the sample post to be created
41
+ #
42
+ # Returns the filename of the sample post, as a String
43
+ def self.initialized_post_name
44
+ "_posts/#{Time.now.strftime('%Y-%m-%d')}-welcome-to-jekyll.markdown"
45
+ end
46
+
47
+ private
48
+
49
+ def self.preserve_source_location?(path, options)
50
+ !options[:force] && !Dir["#{path}/**/*"].empty?
51
+ end
52
+
53
+ def self.create_sample_files(path)
54
+ FileUtils.cp_r site_template + '/.', path
55
+ FileUtils.rm File.expand_path(scaffold_path, path)
56
+ end
57
+
58
+ def self.site_template
59
+ File.expand_path("../../site_template", File.dirname(__FILE__))
60
+ end
61
+
62
+ def self.scaffold_path
63
+ "_posts/0000-00-00-welcome-to-jekyll.markdown.erb"
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,65 @@
1
+ # -*- encoding: utf-8 -*-
2
+ module Jekyll
3
+ module Commands
4
+ class Serve < Command
5
+ def self.process(options)
6
+ require 'webrick'
7
+ include WEBrick
8
+
9
+ destination = options['destination']
10
+
11
+ FileUtils.mkdir_p(destination)
12
+
13
+ # recreate NondisclosureName under utf-8 circumstance
14
+ fh_option = WEBrick::Config::FileHandler
15
+ fh_option[:NondisclosureName] = ['.ht*','~*']
16
+
17
+ s = HTTPServer.new(webrick_options(options))
18
+
19
+ s.mount(options['baseurl'], HTTPServlet::FileHandler, destination, fh_option)
20
+
21
+ Jekyll.logger.info "Server address:", "http://#{s.config[:BindAddress]}:#{s.config[:Port]}"
22
+
23
+ if options['detach'] # detach the server
24
+ pid = Process.fork { s.start }
25
+ Process.detach(pid)
26
+ Jekyll.logger.info "Server detatched with pid '#{pid}'.", "Run `kill -9 #{pid}' to stop the server."
27
+ else # create a new server thread, then join it with current terminal
28
+ t = Thread.new { s.start }
29
+ trap("INT") { s.shutdown }
30
+ t.join()
31
+ end
32
+ end
33
+
34
+ def self.webrick_options(config)
35
+ opts = {
36
+ :Port => config['port'],
37
+ :BindAddress => config['host'],
38
+ :MimeTypes => self.mime_types,
39
+ :DoNotReverseLookup => true,
40
+ :StartCallback => start_callback(config['detach'])
41
+ }
42
+
43
+ if !config['verbose']
44
+ opts.merge!({
45
+ :AccessLog => [],
46
+ :Logger => Log::new([], Log::WARN)
47
+ })
48
+ end
49
+
50
+ opts
51
+ end
52
+
53
+ def self.start_callback(detached)
54
+ unless detached
55
+ Proc.new { Jekyll.logger.info "Server running...", "press ctrl-c to stop." }
56
+ end
57
+ end
58
+
59
+ def self.mime_types
60
+ mime_types_file = File.expand_path('../mime.types', File.dirname(__FILE__))
61
+ WEBrick::HTTPUtils::load_mime_types(mime_types_file)
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,238 @@
1
+ # encoding: UTF-8
2
+
3
+ module Tigefa
4
+ class Configuration < Hash
5
+
6
+ # Default options. Overridden by values in _config.yml.
7
+ # Strings rather than symbols are used for compatibility with YAML.
8
+ DEFAULTS = {
9
+ 'source' => Dir.pwd,
10
+ 'destination' => File.join(Dir.pwd, '_site'),
11
+ 'plugins' => '_plugins',
12
+ 'layouts' => '_layouts',
13
+ 'data_source' => '_data',
14
+ 'keep_files' => ['.git','.svn'],
15
+ 'gems' => [],
16
+
17
+ 'timezone' => nil, # use the local timezone
18
+
19
+ 'encoding' => nil, # use the system encoding
20
+
21
+ 'safe' => false,
22
+ 'detach' => false, # default to not detaching the server
23
+ 'show_drafts' => nil,
24
+ 'limit_posts' => 0,
25
+ 'lsi' => false,
26
+ 'future' => true, # remove and make true just default
27
+ 'pygments' => true,
28
+
29
+ 'relative_permalinks' => true, # backwards-compatibility with < 1.0
30
+ # will be set to false once 2.0 hits
31
+
32
+ 'markdown' => 'maruku',
33
+ 'permalink' => 'date',
34
+ 'baseurl' => '/',
35
+ 'include' => ['.htaccess'],
36
+ 'exclude' => [],
37
+ 'paginate_path' => '/page:num',
38
+
39
+ 'markdown_ext' => 'markdown,mkd,mkdn,md',
40
+ 'textile_ext' => 'textile',
41
+
42
+ 'port' => '4000',
43
+ 'host' => '0.0.0.0',
44
+
45
+ 'excerpt_separator' => "\n\n",
46
+
47
+ 'maruku' => {
48
+ 'fenced_code_blocks' => true,
49
+ 'use_tex' => false,
50
+ 'use_divs' => false,
51
+ 'png_engine' => 'blahtex',
52
+ 'png_dir' => 'images/latex',
53
+ 'png_url' => '/images/latex'
54
+ },
55
+
56
+ 'rdiscount' => {
57
+ 'extensions' => []
58
+ },
59
+
60
+ 'redcarpet' => {
61
+ 'extensions' => []
62
+ },
63
+
64
+ 'kramdown' => {
65
+ 'auto_ids' => true,
66
+ 'footnote_nr' => 1,
67
+ 'entity_output' => 'as_char',
68
+ 'toc_levels' => '1..6',
69
+ 'smart_quotes' => 'lsquo,rsquo,ldquo,rdquo',
70
+ 'use_coderay' => false,
71
+
72
+ 'coderay' => {
73
+ 'coderay_wrap' => 'div',
74
+ 'coderay_line_numbers' => 'inline',
75
+ 'coderay_line_number_start' => 1,
76
+ 'coderay_tab_width' => 4,
77
+ 'coderay_bold_every' => 10,
78
+ 'coderay_css' => 'style'
79
+ }
80
+ },
81
+
82
+ 'redcloth' => {
83
+ 'hard_breaks' => true
84
+ }
85
+ }
86
+
87
+ # Public: Turn all keys into string
88
+ #
89
+ # Return a copy of the hash where all its keys are strings
90
+ def stringify_keys
91
+ reduce({}) { |hsh,(k,v)| hsh.merge(k.to_s => v) }
92
+ end
93
+
94
+ # Public: Directory of the Tigefa source folder
95
+ #
96
+ # override - the command-line options hash
97
+ #
98
+ # Returns the path to the Tigefa source directory
99
+ def source(override)
100
+ override['source'] || self['source'] || DEFAULTS['source']
101
+ end
102
+
103
+ def safe_load_file(filename)
104
+ case File.extname(filename)
105
+ when '.toml'
106
+ TOML.load_file(filename)
107
+ when /\.y(a)?ml/
108
+ YAML.safe_load_file(filename)
109
+ else
110
+ raise ArgumentError, "No parser for '#{filename}' is available. Use a .toml or .y(a)ml file instead."
111
+ end
112
+ end
113
+
114
+ # Public: Generate list of configuration files from the override
115
+ #
116
+ # override - the command-line options hash
117
+ #
118
+ # Returns an Array of config files
119
+ def config_files(override)
120
+ # Get configuration from <source>/_config.yml or <source>/<config_file>
121
+ config_files = override.delete('config')
122
+ if config_files.to_s.empty?
123
+ config_files = File.join(source(override), "_config.yml")
124
+ @default_config_file = true
125
+ end
126
+ config_files = [config_files] unless config_files.is_a? Array
127
+ config_files
128
+ end
129
+
130
+ # Public: Read configuration and return merged Hash
131
+ #
132
+ # file - the path to the YAML file to be read in
133
+ #
134
+ # Returns this configuration, overridden by the values in the file
135
+ def read_config_file(file)
136
+ next_config = safe_load_file(file)
137
+ raise ArgumentError.new("Configuration file: (INVALID) #{file}".yellow) unless next_config.is_a?(Hash)
138
+ Tigefa.logger.info "Configuration file:", file
139
+ next_config
140
+ rescue SystemCallError
141
+ if @default_config_file
142
+ Tigefa.logger.warn "Configuration file:", "none"
143
+ {}
144
+ else
145
+ Tigefa.logger.error "Fatal:", "The configuration file '#{file}' could not be found."
146
+ raise LoadError, "The Configuration file '#{file}' could not be found."
147
+ end
148
+ end
149
+
150
+ # Public: Read in a list of configuration files and merge with this hash
151
+ #
152
+ # files - the list of configuration file paths
153
+ #
154
+ # Returns the full configuration, with the defaults overridden by the values in the
155
+ # configuration files
156
+ def read_config_files(files)
157
+ configuration = clone
158
+
159
+ begin
160
+ files.each do |config_file|
161
+ new_config = read_config_file(config_file)
162
+ configuration = configuration.deep_merge(new_config)
163
+ end
164
+ rescue ArgumentError => err
165
+ Tigefa.logger.warn "WARNING:", "Error reading configuration. " +
166
+ "Using defaults (and options)."
167
+ $stderr.puts "#{err}"
168
+ end
169
+
170
+ configuration.fix_common_issues.backwards_compatibilize
171
+ end
172
+
173
+ # Public: Split a CSV string into an array containing its values
174
+ #
175
+ # csv - the string of comma-separated values
176
+ #
177
+ # Returns an array of the values contained in the CSV
178
+ def csv_to_array(csv)
179
+ csv.split(",").map(&:strip)
180
+ end
181
+
182
+ # Public: Ensure the proper options are set in the configuration to allow for
183
+ # backwards-compatibility with Jekyll pre-1.0
184
+ #
185
+ # Returns the backwards-compatible configuration
186
+ def backwards_compatibilize
187
+ config = clone
188
+ # Provide backwards-compatibility
189
+ if config.has_key?('auto') || config.has_key?('watch')
190
+ Tigefa.logger.warn "Deprecation:", "Auto-regeneration can no longer" +
191
+ " be set from your configuration file(s). Use the"+
192
+ " --watch/-w command-line option instead."
193
+ config.delete('auto')
194
+ config.delete('watch')
195
+ end
196
+
197
+ if config.has_key? 'server'
198
+ Tigefa.logger.warn "Deprecation:", "The 'server' configuration option" +
199
+ " is no longer accepted. Use the 'jekyll serve'" +
200
+ " subcommand to serve your site with WEBrick."
201
+ config.delete('server')
202
+ end
203
+
204
+ if config.has_key? 'server_port'
205
+ Tigefa.logger.warn "Deprecation:", "The 'server_port' configuration option" +
206
+ " has been renamed to 'port'. Please update your config" +
207
+ " file accordingly."
208
+ # copy but don't overwrite:
209
+ config['port'] = config['server_port'] unless config.has_key?('port')
210
+ config.delete('server_port')
211
+ end
212
+
213
+ %w[include exclude].each do |option|
214
+ if config.fetch(option, []).is_a?(String)
215
+ Tigefa.logger.warn "Deprecation:", "The '#{option}' configuration option" +
216
+ " must now be specified as an array, but you specified" +
217
+ " a string. For now, we've treated the string you provided" +
218
+ " as a list of comma-separated values."
219
+ config[option] = csv_to_array(config[option])
220
+ end
221
+ end
222
+ config
223
+ end
224
+
225
+ def fix_common_issues
226
+ config = clone
227
+
228
+ if config.has_key?('paginate') && (!config['paginate'].is_a?(Integer) || config['paginate'] < 1)
229
+ Tigefa.logger.warn "Config Warning:", "The `paginate` key must be a" +
230
+ " positive integer or nil. It's currently set to '#{config['paginate'].inspect}'."
231
+ config['paginate'] = nil
232
+ end
233
+
234
+ config
235
+ end
236
+
237
+ end
238
+ end
@@ -0,0 +1,48 @@
1
+ module Tigefa
2
+ class Converter < Plugin
3
+ # Public: Get or set the pygments prefix. When an argument is specified,
4
+ # the prefix will be set. If no argument is specified, the current prefix
5
+ # will be returned.
6
+ #
7
+ # pygments_prefix - The String prefix (default: nil).
8
+ #
9
+ # Returns the String prefix.
10
+ def self.pygments_prefix(pygments_prefix = nil)
11
+ @pygments_prefix = pygments_prefix if pygments_prefix
12
+ @pygments_prefix
13
+ end
14
+
15
+ # Public: Get or set the pygments suffix. When an argument is specified,
16
+ # the suffix will be set. If no argument is specified, the current suffix
17
+ # will be returned.
18
+ #
19
+ # pygments_suffix - The String suffix (default: nil).
20
+ #
21
+ # Returns the String suffix.
22
+ def self.pygments_suffix(pygments_suffix = nil)
23
+ @pygments_suffix = pygments_suffix if pygments_suffix
24
+ @pygments_suffix
25
+ end
26
+
27
+ # Initialize the converter.
28
+ #
29
+ # Returns an initialized Converter.
30
+ def initialize(config = {})
31
+ @config = config
32
+ end
33
+
34
+ # Get the pygments prefix.
35
+ #
36
+ # Returns the String prefix.
37
+ def pygments_prefix
38
+ self.class.pygments_prefix
39
+ end
40
+
41
+ # Get the pygments suffix.
42
+ #
43
+ # Returns the String suffix.
44
+ def pygments_suffix
45
+ self.class.pygments_suffix
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,21 @@
1
+ module Tigefa
2
+ module Converters
3
+ class Identity < Converter
4
+ safe true
5
+
6
+ priority :lowest
7
+
8
+ def matches(ext)
9
+ true
10
+ end
11
+
12
+ def output_ext(ext)
13
+ ext
14
+ end
15
+
16
+ def convert(content)
17
+ content
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,29 @@
1
+ module Tigefa
2
+ module Converters
3
+ class Markdown
4
+ class KramdownParser
5
+ def initialize(config)
6
+ require 'kramdown'
7
+ @config = config
8
+ rescue LoadError
9
+ STDERR.puts 'You are missing a library required for Markdown. Please run:'
10
+ STDERR.puts ' $ [sudo] gem install kramdown'
11
+ raise FatalException.new("Missing dependency: kramdown")
12
+ end
13
+
14
+ def convert(content)
15
+ # Check for use of coderay
16
+ if @config['kramdown']['use_coderay']
17
+ %w[wrap line_numbers line_numbers_start tab_width bold_every css default_lang].each do |opt|
18
+ key = "coderay_#{opt}"
19
+ @config['kramdown'][key] = @config['kramdown']['coderay'][key] unless @config['kramdown'].has_key?(key)
20
+ end
21
+ end
22
+
23
+ Kramdown::Document.new(content, @config["kramdown"].symbolize_keys).to_html
24
+ end
25
+
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,56 @@
1
+ module Tigefa
2
+ module Converters
3
+ class Markdown
4
+ class MarukuParser
5
+ def initialize(config)
6
+ require 'maruku'
7
+ @config = config
8
+ @errors = []
9
+ load_divs_library if @config['maruku']['use_divs']
10
+ load_blahtext_library if @config['maruku']['use_tex']
11
+ enable_fenced_code_blocks if @config['maruku']['fenced_code_blocks']
12
+ rescue LoadError
13
+ STDERR.puts 'You are missing a library required for Markdown. Please run:'
14
+ STDERR.puts ' $ [sudo] gem install maruku'
15
+ raise FatalException.new("Missing dependency: maruku")
16
+ end
17
+
18
+ def load_divs_library
19
+ require 'maruku/ext/div'
20
+ STDERR.puts 'Maruku: Using extended syntax for div elements.'
21
+ end
22
+
23
+ def load_blahtext_library
24
+ require 'maruku/ext/math'
25
+ STDERR.puts "Maruku: Using LaTeX extension. Images in `#{@config['maruku']['png_dir']}`."
26
+
27
+ # Switch off MathML output
28
+ MaRuKu::Globals[:html_math_output_mathml] = false
29
+ MaRuKu::Globals[:html_math_engine] = 'none'
30
+
31
+ # Turn on math to PNG support with blahtex
32
+ # Resulting PNGs stored in `images/latex`
33
+ MaRuKu::Globals[:html_math_output_png] = true
34
+ MaRuKu::Globals[:html_png_engine] = @config['maruku']['png_engine']
35
+ MaRuKu::Globals[:html_png_dir] = @config['maruku']['png_dir']
36
+ MaRuKu::Globals[:html_png_url] = @config['maruku']['png_url']
37
+ end
38
+
39
+ def enable_fenced_code_blocks
40
+ MaRuKu::Globals[:fenced_code_blocks] = true
41
+ end
42
+
43
+ def print_errors_and_fail
44
+ print @errors.join
45
+ raise MaRuKu::Exception, "MaRuKu encountered problem(s) while converting your markup."
46
+ end
47
+
48
+ def convert(content)
49
+ converted = Maruku.new(content, :error_stream => @errors).to_html.strip
50
+ print_errors_and_fail unless @errors.empty?
51
+ converted
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end