monad 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (143) hide show
  1. data/CONTRIBUTING.md +68 -0
  2. data/Gemfile +2 -0
  3. data/LICENSE +21 -0
  4. data/README.md +88 -0
  5. data/Rakefile +136 -0
  6. data/bin/monad +102 -0
  7. data/cucumber.yml +3 -0
  8. data/features/create_sites.feature +112 -0
  9. data/features/data_sources.feature +76 -0
  10. data/features/drafts.feature +25 -0
  11. data/features/embed_filters.feature +60 -0
  12. data/features/markdown.feature +30 -0
  13. data/features/pagination.feature +54 -0
  14. data/features/permalinks.feature +65 -0
  15. data/features/post_data.feature +214 -0
  16. data/features/site_configuration.feature +206 -0
  17. data/features/site_data.feature +101 -0
  18. data/features/step_definitions/monad_steps.rb +175 -0
  19. data/features/support/env.rb +25 -0
  20. data/lib/monad.rb +90 -0
  21. data/lib/monad/command.rb +27 -0
  22. data/lib/monad/commands/build.rb +64 -0
  23. data/lib/monad/commands/doctor.rb +29 -0
  24. data/lib/monad/commands/new.rb +50 -0
  25. data/lib/monad/commands/serve.rb +33 -0
  26. data/lib/monad/configuration.rb +183 -0
  27. data/lib/monad/converter.rb +48 -0
  28. data/lib/monad/converters/identity.rb +21 -0
  29. data/lib/monad/converters/markdown.rb +43 -0
  30. data/lib/monad/converters/markdown/kramdown_parser.rb +44 -0
  31. data/lib/monad/converters/markdown/maruku_parser.rb +47 -0
  32. data/lib/monad/converters/markdown/rdiscount_parser.rb +35 -0
  33. data/lib/monad/converters/markdown/redcarpet_parser.rb +70 -0
  34. data/lib/monad/converters/textile.rb +50 -0
  35. data/lib/monad/convertible.rb +152 -0
  36. data/lib/monad/core_ext.rb +68 -0
  37. data/lib/monad/deprecator.rb +32 -0
  38. data/lib/monad/draft.rb +35 -0
  39. data/lib/monad/drivers/json_driver.rb +39 -0
  40. data/lib/monad/drivers/yaml_driver.rb +23 -0
  41. data/lib/monad/errors.rb +4 -0
  42. data/lib/monad/filters.rb +154 -0
  43. data/lib/monad/generator.rb +4 -0
  44. data/lib/monad/generators/pagination.rb +143 -0
  45. data/lib/monad/layout.rb +42 -0
  46. data/lib/monad/logger.rb +54 -0
  47. data/lib/monad/mime.types +85 -0
  48. data/lib/monad/page.rb +163 -0
  49. data/lib/monad/plugin.rb +75 -0
  50. data/lib/monad/post.rb +377 -0
  51. data/lib/monad/site.rb +455 -0
  52. data/lib/monad/static_file.rb +70 -0
  53. data/lib/monad/tags/gist.rb +30 -0
  54. data/lib/monad/tags/highlight.rb +85 -0
  55. data/lib/monad/tags/include.rb +37 -0
  56. data/lib/monad/tags/post_url.rb +61 -0
  57. data/lib/site_template/.gitignore +1 -0
  58. data/lib/site_template/_config.yml +2 -0
  59. data/lib/site_template/_layouts/default.html +46 -0
  60. data/lib/site_template/_layouts/post.html +9 -0
  61. data/lib/site_template/_posts/0000-00-00-welcome-to-monad.markdown.erb +24 -0
  62. data/lib/site_template/css/main.css +165 -0
  63. data/lib/site_template/css/syntax.css +60 -0
  64. data/lib/site_template/index.html +13 -0
  65. data/monad.gemspec +197 -0
  66. data/script/bootstrap +2 -0
  67. data/test/fixtures/broken_front_matter1.erb +5 -0
  68. data/test/fixtures/broken_front_matter2.erb +4 -0
  69. data/test/fixtures/broken_front_matter3.erb +7 -0
  70. data/test/fixtures/exploit_front_matter.erb +4 -0
  71. data/test/fixtures/front_matter.erb +4 -0
  72. data/test/fixtures/members.yaml +7 -0
  73. data/test/helper.rb +62 -0
  74. data/test/source/.htaccess +8 -0
  75. data/test/source/_includes/sig.markdown +3 -0
  76. data/test/source/_layouts/default.html +27 -0
  77. data/test/source/_layouts/simple.html +1 -0
  78. data/test/source/_plugins/dummy.rb +8 -0
  79. data/test/source/_posts/2008-02-02-not-published.textile +8 -0
  80. data/test/source/_posts/2008-02-02-published.textile +8 -0
  81. data/test/source/_posts/2008-10-18-foo-bar.textile +8 -0
  82. data/test/source/_posts/2008-11-21-complex.textile +8 -0
  83. data/test/source/_posts/2008-12-03-permalinked-post.textile +9 -0
  84. data/test/source/_posts/2008-12-13-include.markdown +8 -0
  85. data/test/source/_posts/2009-01-27-array-categories.textile +10 -0
  86. data/test/source/_posts/2009-01-27-categories.textile +7 -0
  87. data/test/source/_posts/2009-01-27-category.textile +7 -0
  88. data/test/source/_posts/2009-01-27-empty-categories.textile +7 -0
  89. data/test/source/_posts/2009-01-27-empty-category.textile +7 -0
  90. data/test/source/_posts/2009-03-12-hash-#1.markdown +6 -0
  91. data/test/source/_posts/2009-05-18-empty-tag.textile +6 -0
  92. data/test/source/_posts/2009-05-18-empty-tags.textile +6 -0
  93. data/test/source/_posts/2009-05-18-tag.textile +6 -0
  94. data/test/source/_posts/2009-05-18-tags.textile +9 -0
  95. data/test/source/_posts/2009-06-22-empty-yaml.textile +3 -0
  96. data/test/source/_posts/2009-06-22-no-yaml.textile +1 -0
  97. data/test/source/_posts/2010-01-08-triple-dash.markdown +5 -0
  98. data/test/source/_posts/2010-01-09-date-override.textile +7 -0
  99. data/test/source/_posts/2010-01-09-time-override.textile +7 -0
  100. data/test/source/_posts/2010-01-09-timezone-override.textile +7 -0
  101. data/test/source/_posts/2010-01-16-override-data.textile +4 -0
  102. data/test/source/_posts/2011-04-12-md-extension.md +7 -0
  103. data/test/source/_posts/2011-04-12-text-extension.text +0 -0
  104. data/test/source/_posts/2013-01-02-post-excerpt.markdown +14 -0
  105. data/test/source/_posts/2013-01-12-nil-layout.textile +6 -0
  106. data/test/source/_posts/2013-01-12-no-layout.textile +5 -0
  107. data/test/source/_posts/2013-03-19-not-a-post.markdown/.gitkeep +0 -0
  108. data/test/source/_posts/2013-04-11-custom-excerpt.markdown +10 -0
  109. data/test/source/_posts/2013-05-10-number-category.textile +7 -0
  110. data/test/source/_posts/es/2008-11-21-nested.textile +8 -0
  111. data/test/source/about.html +6 -0
  112. data/test/source/category/_posts/2008-9-23-categories.textile +6 -0
  113. data/test/source/contacts.html +5 -0
  114. data/test/source/contacts/bar.html +5 -0
  115. data/test/source/contacts/index.html +5 -0
  116. data/test/source/css/screen.css +76 -0
  117. data/test/source/deal.with.dots.html +7 -0
  118. data/test/source/foo/_posts/bar/2008-12-12-topical-post.textile +8 -0
  119. data/test/source/index.html +22 -0
  120. data/test/source/sitemap.xml +32 -0
  121. data/test/source/symlink-test/symlinked-file +22 -0
  122. data/test/source/win/_posts/2009-05-24-yaml-linebreak.markdown +7 -0
  123. data/test/source/z_category/_posts/2008-9-23-categories.textile +6 -0
  124. data/test/suite.rb +11 -0
  125. data/test/test_command.rb +39 -0
  126. data/test/test_configuration.rb +137 -0
  127. data/test/test_convertible.rb +51 -0
  128. data/test/test_core_ext.rb +88 -0
  129. data/test/test_filters.rb +102 -0
  130. data/test/test_generated_site.rb +83 -0
  131. data/test/test_json_driver.rb +63 -0
  132. data/test/test_kramdown.rb +35 -0
  133. data/test/test_new_command.rb +104 -0
  134. data/test/test_page.rb +193 -0
  135. data/test/test_pager.rb +115 -0
  136. data/test/test_post.rb +573 -0
  137. data/test/test_rdiscount.rb +22 -0
  138. data/test/test_redcarpet.rb +61 -0
  139. data/test/test_redcloth.rb +86 -0
  140. data/test/test_site.rb +374 -0
  141. data/test/test_tags.rb +310 -0
  142. data/test/test_yaml_driver.rb +35 -0
  143. metadata +554 -0
@@ -0,0 +1,70 @@
1
+ module Monad
2
+ class StaticFile
3
+ # The cache of last modification times [path] -> mtime.
4
+ @@mtimes = Hash.new
5
+
6
+ # Initialize a new StaticFile.
7
+ #
8
+ # site - The Site.
9
+ # base - The String path to the <source>.
10
+ # dir - The String path between <source> and the file.
11
+ # name - The String filename of the file.
12
+ def initialize(site, base, dir, name)
13
+ @site = site
14
+ @base = base
15
+ @dir = dir
16
+ @name = name
17
+ end
18
+
19
+ # Returns source file path.
20
+ def path
21
+ File.join(@base, @dir, @name)
22
+ end
23
+
24
+ # Obtain destination path.
25
+ #
26
+ # dest - The String path to the destination dir.
27
+ #
28
+ # Returns destination file path.
29
+ def destination(dest)
30
+ File.join(dest, @dir, @name)
31
+ end
32
+
33
+ # Returns last modification time for this file.
34
+ def mtime
35
+ File.stat(path).mtime.to_i
36
+ end
37
+
38
+ # Is source path modified?
39
+ #
40
+ # Returns true if modified since last write.
41
+ def modified?
42
+ @@mtimes[path] != mtime
43
+ end
44
+
45
+ # Write the static file to the destination directory (if modified).
46
+ #
47
+ # dest - The String path to the destination dir.
48
+ #
49
+ # Returns false if the file was not modified since last time (no-op).
50
+ def write(dest)
51
+ dest_path = destination(dest)
52
+
53
+ return false if File.exist?(dest_path) and !modified?
54
+ @@mtimes[path] = mtime
55
+
56
+ FileUtils.mkdir_p(File.dirname(dest_path))
57
+ FileUtils.cp(path, dest_path)
58
+
59
+ true
60
+ end
61
+
62
+ # Reset the mtimes cache (for testing purposes).
63
+ #
64
+ # Returns nothing.
65
+ def self.reset_cache
66
+ @@mtimes = Hash.new
67
+ nil
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,30 @@
1
+ # Gist Liquid Tag
2
+ #
3
+ # Example:
4
+ # {% gist 1234567 %}
5
+ # {% gist 1234567 file.rb %}
6
+
7
+ module Monad
8
+ class GistTag < Liquid::Tag
9
+ def render(context)
10
+ if tag_contents = @markup.strip.match(/\A(\d+) ?(\S*)\Z/)
11
+ gist_id, filename = tag_contents[1].strip, tag_contents[2].strip
12
+ gist_script_tag(gist_id, filename)
13
+ else
14
+ "Error parsing gist id"
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def gist_script_tag(gist_id, filename=nil)
21
+ if filename.empty?
22
+ "<script src=\"https://gist.github.com/#{gist_id}.js\"> </script>"
23
+ else
24
+ "<script src=\"https://gist.github.com/#{gist_id}.js?file=#{filename}\"> </script>"
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ Liquid::Template.register_tag('gist', Monad::GistTag)
@@ -0,0 +1,85 @@
1
+ module Monad
2
+ module Tags
3
+ class HighlightBlock < Liquid::Block
4
+ include Liquid::StandardFilters
5
+
6
+ # The regular expression syntax checker. Start with the language specifier.
7
+ # Follow that by zero or more space separated options that take one of two
8
+ # forms:
9
+ #
10
+ # 1. name
11
+ # 2. name=value
12
+ SYNTAX = /^([a-zA-Z0-9.+#-]+)((\s+\w+(=\w+)?)*)$/
13
+
14
+ def initialize(tag_name, markup, tokens)
15
+ super
16
+ if markup.strip =~ SYNTAX
17
+ @lang = $1
18
+ @options = {}
19
+ if defined?($2) && $2 != ''
20
+ $2.split.each do |opt|
21
+ key, value = opt.split('=')
22
+ if value.nil?
23
+ if key == 'linenos'
24
+ value = 'inline'
25
+ else
26
+ value = true
27
+ end
28
+ end
29
+ @options[key] = value
30
+ end
31
+ end
32
+ else
33
+ raise SyntaxError.new <<-eos
34
+ Syntax Error in tag 'highlight' while parsing the following markup:
35
+
36
+ #{markup}
37
+
38
+ Valid syntax: highlight <lang> [linenos]
39
+ eos
40
+ end
41
+ end
42
+
43
+ def render(context)
44
+ if context.registers[:site].pygments
45
+ render_pygments(context, super)
46
+ else
47
+ render_codehighlighter(context, super)
48
+ end
49
+ end
50
+
51
+ def render_pygments(context, code)
52
+ require 'pygments'
53
+
54
+ @options[:encoding] = 'utf-8'
55
+
56
+ output = add_code_tags(
57
+ Pygments.highlight(code, :lexer => @lang, :options => @options),
58
+ @lang
59
+ )
60
+
61
+ output = context["pygments_prefix"] + output if context["pygments_prefix"]
62
+ output = output + context["pygments_suffix"] if context["pygments_suffix"]
63
+ output
64
+ end
65
+
66
+ def render_codehighlighter(context, code)
67
+ #The div is required because RDiscount blows ass
68
+ <<-HTML
69
+ <div>
70
+ <pre><code class='#{@lang}'>#{h(code).strip}</code></pre>
71
+ </div>
72
+ HTML
73
+ end
74
+
75
+ def add_code_tags(code, lang)
76
+ # Add nested <code> tags to code blocks
77
+ code = code.sub(/<pre>/,'<pre><code class="' + lang + '">')
78
+ code = code.sub(/<\/pre>/,"</code></pre>")
79
+ end
80
+
81
+ end
82
+ end
83
+ end
84
+
85
+ Liquid::Template.register_tag('highlight', Monad::Tags::HighlightBlock)
@@ -0,0 +1,37 @@
1
+ module Monad
2
+ module Tags
3
+ class IncludeTag < Liquid::Tag
4
+ def initialize(tag_name, file, tokens)
5
+ super
6
+ @file = file.strip
7
+ end
8
+
9
+ def render(context)
10
+ includes_dir = File.join(context.registers[:site].source, '_includes')
11
+
12
+ if File.symlink?(includes_dir)
13
+ return "Includes directory '#{includes_dir}' cannot be a symlink"
14
+ end
15
+
16
+ if @file !~ /^[a-zA-Z0-9_\/\.-]+$/ || @file =~ /\.\// || @file =~ /\/\./
17
+ return "Include file '#{@file}' contains invalid characters or sequences"
18
+ end
19
+
20
+ Dir.chdir(includes_dir) do
21
+ choices = Dir['**/*'].reject { |x| File.symlink?(x) }
22
+ if choices.include?(@file)
23
+ source = File.read(@file)
24
+ partial = Liquid::Template.parse(source)
25
+ context.stack do
26
+ partial.render(context)
27
+ end
28
+ else
29
+ "Included file '#{@file}' not found in _includes directory"
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ Liquid::Template.register_tag('include', Monad::Tags::IncludeTag)
@@ -0,0 +1,61 @@
1
+ module Monad
2
+ module Tags
3
+ class PostComparer
4
+ MATCHER = /^(.+\/)*(\d+-\d+-\d+)-(.*)$/
5
+
6
+ attr_accessor :date, :slug
7
+
8
+ def initialize(name)
9
+ all, path, date, slug = *name.sub(/^\//, "").match(MATCHER)
10
+ @slug = path ? path + slug : slug
11
+ @date = Time.parse(date)
12
+ end
13
+
14
+ def ==(other)
15
+ slug == post_slug(other) &&
16
+ date.year == other.date.year &&
17
+ date.month == other.date.month &&
18
+ date.day == other.date.day
19
+ end
20
+
21
+ private
22
+ # Construct the directory-aware post slug for a Monad::Post
23
+ #
24
+ # other - the Monad::Post
25
+ #
26
+ # Returns the post slug with the subdirectory (relative to _posts)
27
+ def post_slug(other)
28
+ path = other.name.split("/")[0...-1].join("/")
29
+ if path.nil? || path == ""
30
+ other.slug
31
+ else
32
+ path + '/' + other.slug
33
+ end
34
+ end
35
+ end
36
+
37
+ class PostUrl < Liquid::Tag
38
+ def initialize(tag_name, post, tokens)
39
+ super
40
+ @orig_post = post.strip
41
+ @post = PostComparer.new(@orig_post)
42
+ end
43
+
44
+ def render(context)
45
+ site = context.registers[:site]
46
+
47
+ site.posts.each do |p|
48
+ if @post == p
49
+ return p.url
50
+ end
51
+ end
52
+
53
+ puts "ERROR: post_url: \"#{@orig_post}\" could not be found"
54
+
55
+ return "#"
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ Liquid::Template.register_tag('post_url', Monad::Tags::PostUrl)
@@ -0,0 +1 @@
1
+ _site
@@ -0,0 +1,2 @@
1
+ name: Your New Monad Site
2
+ pygments: true
@@ -0,0 +1,46 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
6
+ <title>{{ page.title }}</title>
7
+ <meta name="viewport" content="width=device-width">
8
+
9
+ <!-- syntax highlighting CSS -->
10
+ <link rel="stylesheet" href="/css/syntax.css">
11
+
12
+ <!-- Custom CSS -->
13
+ <link rel="stylesheet" href="/css/main.css">
14
+
15
+ </head>
16
+ <body>
17
+
18
+ <div class="container">
19
+ <div class="site">
20
+ <div class="header">
21
+ <h1 class="title"><a href="/">{{ site.name }}</a></h1>
22
+ <a class="extra" href="/">home</a>
23
+ </div>
24
+
25
+ {{ content }}
26
+
27
+ <div class="footer">
28
+ <div class="contact">
29
+ <p>
30
+ Your Name<br />
31
+ What You Are<br />
32
+ your@email.com
33
+ </p>
34
+ </div>
35
+ <div class="contact">
36
+ <p>
37
+ <a href="http://github.com/yourusername/">github.com/yourusername</a><br />
38
+ <a href="http://twitter.com/yourusername/">twitter.com/yourusername</a><br />
39
+ </p>
40
+ </div>
41
+ </div>
42
+ </div>
43
+ </div> <!-- /container -->
44
+
45
+ </body>
46
+ </html>
@@ -0,0 +1,9 @@
1
+ ---
2
+ layout: default
3
+ ---
4
+ <h2>{{ page.title }}</h2>
5
+ <p class="meta">{{ page.date | date_to_string }}</p>
6
+
7
+ <div id="post">
8
+ {{ content }}
9
+ </div>
@@ -0,0 +1,24 @@
1
+ ---
2
+ layout: post
3
+ title: "Welcome to Monad!"
4
+ date: <%= Time.now.strftime('%Y-%m-%d %H:%M:%S') %>
5
+ categories: monad update
6
+ ---
7
+
8
+ You'll find this post in your `_posts` directory - edit this post and re-build (or run with the `-w` switch) to see your changes!
9
+ To add new posts, simply add a file in the `_posts` directory that follows the convention: YYYY-MM-DD-name-of-post.ext.
10
+
11
+ Monad also offers powerful support for code snippets:
12
+
13
+ {% highlight ruby %}
14
+ def print_hi(name)
15
+ puts "Hi, #{name}"
16
+ end
17
+ print_hi('Tom')
18
+ #=> prints 'Hi, Tom' to STDOUT.
19
+ {% endhighlight %}
20
+
21
+ Check out the [Monad docs][monad] for more info on how to get the most out of Monad. File all bugs/feature requests at [Monad's GitHub repo][monad-gh].
22
+
23
+ [monad-gh]: https://github.com/mojombo/monad
24
+ [monad]: http://monadrb.com
@@ -0,0 +1,165 @@
1
+ /*****************************************************************************/
2
+ /*
3
+ /* Common
4
+ /*
5
+ /*****************************************************************************/
6
+
7
+ /* Global Reset */
8
+ * {
9
+ margin: 0;
10
+ padding: 0;
11
+ }
12
+
13
+ html, body { height: 100%; }
14
+
15
+ body {
16
+ background-color: #FFF;
17
+ font: 13.34px Helvetica, Arial, sans-serif;
18
+ font-size: small;
19
+ text-align: center;
20
+ }
21
+
22
+ h1, h2, h3, h4, h5, h6 {
23
+ font-size: 100%; }
24
+
25
+ h1 { margin-bottom: 1em; }
26
+ p { margin: 1em 0; }
27
+
28
+ a { color: #00a; }
29
+ a:hover { color: #000; }
30
+ a:visited { color: #a0a; }
31
+
32
+ table {
33
+ font-size: inherit;
34
+ font: 100%;
35
+ }
36
+
37
+ /*****************************************************************************/
38
+ /*
39
+ /* Home
40
+ /*
41
+ /*****************************************************************************/
42
+ ul.posts {
43
+ list-style-type: none;
44
+ margin-bottom: 2em;
45
+ }
46
+
47
+ ul.posts li {
48
+ line-height: 1.75em;
49
+ }
50
+
51
+ ul.posts span {
52
+ color: #aaa;
53
+ font-family: Monaco, "Courier New", monospace;
54
+ font-size: 80%;
55
+ }
56
+
57
+ /*****************************************************************************/
58
+ /*
59
+ /* Site
60
+ /*
61
+ /*****************************************************************************/
62
+
63
+ .site {
64
+ font-size: 115%;
65
+ text-align: justify;
66
+ width: 42em;
67
+ margin: 3em auto 2em;
68
+ line-height: 1.5em;
69
+ }
70
+
71
+ .site .header a {
72
+ font-weight: bold;
73
+ text-decoration: none;
74
+ }
75
+
76
+ .site .header h1.title {
77
+ display: inline-block;
78
+ margin-bottom: 2em;
79
+ }
80
+
81
+ .site .header h1.title a {
82
+ color: #a00;
83
+ }
84
+
85
+ .site .header h1.title a:hover {
86
+ color: #000;
87
+ }
88
+
89
+ .site .header a.extra {
90
+ color: #aaa;
91
+ margin-left: 1em;
92
+ }
93
+
94
+ .site .header a.extra:hover {
95
+ color: #000;
96
+ }
97
+
98
+ .site .meta {
99
+ color: #aaa;
100
+ }
101
+
102
+ .site .footer {
103
+ font-size: 80%;
104
+ color: #666;
105
+ border-top: 4px solid #eee;
106
+ margin-top: 2em;
107
+ overflow: hidden;
108
+ }
109
+
110
+ .site .footer .contact {
111
+ float: left;
112
+ margin-right: 3em;
113
+ }
114
+
115
+ .site .footer .contact a {
116
+ color: #8085C1;
117
+ }
118
+
119
+ .site .footer .rss {
120
+ margin-top: 1.1em;
121
+ margin-right: -.2em;
122
+ float: right;
123
+ }
124
+
125
+ .site .footer .rss img {
126
+ border: 0;
127
+ }
128
+
129
+ /*****************************************************************************/
130
+ /*
131
+ /* Posts
132
+ /*
133
+ /*****************************************************************************/
134
+
135
+ /* standard */
136
+ #post pre {
137
+ border: 1px solid #ddd;
138
+ background-color: #eef;
139
+ padding: 0 .4em;
140
+ }
141
+
142
+ #post ul, #post ol {
143
+ margin-left: 1.35em;
144
+ }
145
+
146
+ #post code {
147
+ border: 1px solid #ddd;
148
+ background-color: #eef;
149
+ padding: 0 .2em;
150
+ }
151
+
152
+ #post pre code {
153
+ border: none;
154
+ }
155
+
156
+ /* terminal */
157
+ #post pre.terminal {
158
+ border: 1px solid #000;
159
+ background-color: #333;
160
+ color: #FFF;
161
+ }
162
+
163
+ #post pre.terminal code {
164
+ background-color: #333;
165
+ }