PlainSite 1.2.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 (61) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +2 -0
  3. data/Gemfile.lock +43 -0
  4. data/LICENSE +20 -0
  5. data/PlainSite.gemspec +40 -0
  6. data/README.md +276 -0
  7. data/Rakefile +34 -0
  8. data/_config.yml +6 -0
  9. data/bin/plainsite +76 -0
  10. data/lib/PlainSite.rb +5 -0
  11. data/lib/PlainSite/Commands.rb +76 -0
  12. data/lib/PlainSite/Data/Category.rb +235 -0
  13. data/lib/PlainSite/Data/FrontMatterFile.rb +64 -0
  14. data/lib/PlainSite/Data/Post.rb +237 -0
  15. data/lib/PlainSite/Data/PostList.rb +164 -0
  16. data/lib/PlainSite/Data/PostListPage.rb +80 -0
  17. data/lib/PlainSite/RenderTask.rb +235 -0
  18. data/lib/PlainSite/Site.rb +330 -0
  19. data/lib/PlainSite/SocketPatch.rb +15 -0
  20. data/lib/PlainSite/Tpl/ExtMethods.rb +55 -0
  21. data/lib/PlainSite/Tpl/LayErb.rb +73 -0
  22. data/lib/PlainSite/Utils.rb +79 -0
  23. data/lib/PlainSite/_scaffold/_src/assets/README.md +5 -0
  24. data/lib/PlainSite/_scaffold/_src/assets/css/style.css +506 -0
  25. data/lib/PlainSite/_scaffold/_src/assets/favicon.ico +0 -0
  26. data/lib/PlainSite/_scaffold/_src/config.yml +10 -0
  27. data/lib/PlainSite/_scaffold/_src/data/essays/game-of-life.md +15 -0
  28. data/lib/PlainSite/_scaffold/_src/data/essays/phoenix-rebirth.html +15 -0
  29. data/lib/PlainSite/_scaffold/_src/data/programming/hello-world.md +48 -0
  30. data/lib/PlainSite/_scaffold/_src/extensions/TplExt.rb +23 -0
  31. data/lib/PlainSite/_scaffold/_src/routes.rb +49 -0
  32. data/lib/PlainSite/_scaffold/_src/templates/404.html +16 -0
  33. data/lib/PlainSite/_scaffold/_src/templates/about.html +11 -0
  34. data/lib/PlainSite/_scaffold/_src/templates/base.html +32 -0
  35. data/lib/PlainSite/_scaffold/_src/templates/header.html +8 -0
  36. data/lib/PlainSite/_scaffold/_src/templates/index.html +25 -0
  37. data/lib/PlainSite/_scaffold/_src/templates/list.html +41 -0
  38. data/lib/PlainSite/_scaffold/_src/templates/post.html +81 -0
  39. data/lib/PlainSite/_scaffold/_src/templates/rss.erb +29 -0
  40. data/test/CategoryTest.rb +63 -0
  41. data/test/FrontMatterFileTest.rb +40 -0
  42. data/test/LayErbTest.rb +20 -0
  43. data/test/ObjectProxyTest.rb +30 -0
  44. data/test/PostListTest.rb +55 -0
  45. data/test/PostTest.rb +48 -0
  46. data/test/SiteTest.rb +105 -0
  47. data/test/fixtures/2012-06-12-test.md +7 -0
  48. data/test/fixtures/category-demo/2012-06-12-post1.md +7 -0
  49. data/test/fixtures/category-demo/2013-05-01-post2.md +7 -0
  50. data/test/fixtures/category-demo/_meta.yml +1 -0
  51. data/test/fixtures/category-demo/index.md +6 -0
  52. data/test/fixtures/category-demo/sub-category1/sub-post1.md +1 -0
  53. data/test/fixtures/category-demo/sub-category2/sub-post2.md +1 -0
  54. data/test/fixtures/include.erb +1 -0
  55. data/test/fixtures/invalid-front-matter.html +7 -0
  56. data/test/fixtures/layout.erb +1 -0
  57. data/test/fixtures/no-front-matter.html +2 -0
  58. data/test/fixtures/tpl.erb +7 -0
  59. data/test/fixtures/valid-front-matter.html +14 -0
  60. data/test/runtest +6 -0
  61. metadata +202 -0
@@ -0,0 +1,10 @@
1
+ url: http://example.com
2
+ name: Demo Blog
3
+ author: Ego
4
+ code_highlight:
5
+ engine: pygments
6
+ pygments_css_list:
7
+ default: css/pygments.css
8
+ disqus_id:
9
+
10
+
@@ -0,0 +1,15 @@
1
+ ---
2
+ title: Game of life!
3
+ disable_erb: true
4
+ ---
5
+
6
+ #### Game of life!
7
+
8
+
9
+ Life is a game!
10
+
11
+
12
+
13
+ This is a demo!
14
+
15
+
@@ -0,0 +1,15 @@
1
+ ---
2
+ title: Phoenix Rebirth!
3
+ ---
4
+
5
+
6
+ <h3>Phoenix Rebirth!</h3>
7
+
8
+ <p><strong>PlainSite</strong> is a simple but powerful static site generator!</p>
9
+
10
+
11
+ <%iframe do%>
12
+ <h4>Hello,I'm in iframe now!</h4>
13
+ <%end%>
14
+
15
+
@@ -0,0 +1,48 @@
1
+ ---
2
+ title: Hello,world!
3
+ ---
4
+
5
+ ### Hello,world!
6
+
7
+ This is a test!
8
+
9
+ Ruby:<highlight ruby>puts "Hello,world!"</highlight>
10
+
11
+ #### Java
12
+ <highlight java linenos>
13
+ class HelloWorldApp {
14
+ public static void main(String[] args) {
15
+ System.out.println("Hello World!"); // Display the string.
16
+ }
17
+ }
18
+ </highlight>
19
+
20
+ #### Haskell
21
+ <highlight haskell linenos=0>
22
+ module Main where
23
+
24
+ main :: IO ()
25
+ main = putStrLn "Hello, World!"
26
+ </highlight>
27
+
28
+ #### C++
29
+ <highlight c++>
30
+ int main(void) {
31
+ char NG[22] = {'1',0};
32
+ int x = -1;
33
+ N G;
34
+ for (int fibs = 1; fibs <= 20; fibs++) {
35
+ for (;G <= N(NG); ++G) x++;
36
+ NG[fibs] = '0';
37
+ NG[fibs+1] = 0;
38
+ std::cout << x << " ";
39
+ }
40
+ std::cout << std::endl;
41
+ return 0;
42
+ }
43
+ </highlight>
44
+
45
+
46
+
47
+ Self url:[<%=title%>](<%=url%>)
48
+
@@ -0,0 +1,23 @@
1
+ #coding:utf-8
2
+
3
+ module PlainSite;end
4
+ module PlainSite::Tpl
5
+ module ExtMethods
6
+ def your_custom_template_method(&block)
7
+ """
8
+ <% your_custom_template_method do %>
9
+ Echo!
10
+ <% end %>
11
+ """
12
+ code=echo_block &block
13
+ @_erbout_buf << code
14
+ end
15
+
16
+ def your_mystery_tpl_method
17
+ """
18
+ <%=your_mystery_tpl_method%>
19
+ """
20
+ "Mystery!"
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,49 @@
1
+ #coding:utf-8
2
+
3
+
4
+
5
+ $site.route(
6
+ url_pattern: 'index.html',
7
+ data: {site: $site},
8
+ template: 'index.html',
9
+ build_anyway:true
10
+ )
11
+
12
+ $site.route(
13
+ url_pattern: '404.html',
14
+ data: {site: $site},
15
+ template: '404.html'
16
+ )
17
+
18
+ $site.route(
19
+ url_pattern: 'rss.xml',
20
+ data: { posts: $site.data / '**' },
21
+ template: 'rss.erb'
22
+ )
23
+
24
+
25
+ $site.route(
26
+ url_pattern: 'about.html',
27
+ data: {site:$site},
28
+ template: 'about.html'
29
+ )
30
+
31
+
32
+ $site.data.subs.each do |cat|
33
+ $site.route(
34
+ url_pattern: "{data_id}.html",
35
+ data: cat / '*' ,
36
+ template: 'post.html'
37
+ )
38
+
39
+ pages=cat.posts / 10 # Page size is 10
40
+ pages.each do |p|
41
+ p.category=cat
42
+ end
43
+
44
+ $site.route(
45
+ url_pattern: "#{cat.data_id}/{slug}.html",
46
+ data: pages,
47
+ template: 'list.html'
48
+ )
49
+ end
@@ -0,0 +1,16 @@
1
+ ---
2
+ layout: base.html
3
+ ---
4
+
5
+ <% content_for :page_title do %>
6
+ Page Not Found! — <%=site.name%>
7
+ <% end %>
8
+ <% content_for :page_content do %>
9
+ <%= include 'header.html' %>
10
+ <section style="text-align:center;padding:1rem 0;" class="error">
11
+ <h2>404 Page Not Found!</h2>
12
+ <p>This is not the web page you are looking for!</p>
13
+ <p>Something goes wrong!</p>
14
+ <p style="font-size:40px;white-space:nowrap;">≧◔◡◔≦</p>
15
+ </section>
16
+ <% end %>
@@ -0,0 +1,11 @@
1
+ ---
2
+ layout: base.html
3
+ ---
4
+
5
+ <% content_for :page_content do %>
6
+ <%= include 'header.html' %>
7
+ <h1>About</h1>
8
+ <p>
9
+ This is a demo blog.
10
+ </p>
11
+ <% end %>
@@ -0,0 +1,32 @@
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><%=
7
+ if yield :page_title
8
+ html_escape(yield :page_title)
9
+ else
10
+ html_escape site.name
11
+ end
12
+ %></title>
13
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
14
+ <link rel="stylesheet" type="text/css" href="<%=site.url_for "css/pygments.css" %>" />
15
+ <link rel="stylesheet" type="text/css" href="<%=site.url_for "css/style.css" %>" />
16
+ <link rel="alternate" type="application/rss+xml" title="<%=site.name%>" href="<%=site.url_for "rss.xml" %>"/>
17
+ <link rel="shortcut icon" href="<%=site.url_for "favicon.png" %>" type="image/png" />
18
+ </head>
19
+ <body class="dark">
20
+
21
+ <%=yield :page_content%>
22
+
23
+ <footer class="site-footer">
24
+ <a rel="license"
25
+ title="This blog is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License."
26
+ href="https://creativecommons.org/licenses/by-sa/3.0/deed.zh" target="_blank"><!--img alt="知识共享许可协议" src="https://i.creativecommons.org/l/by-sa/3.0/80x15.png" width="80" height="14" /--><img width="80" height="15" title="知识共享许可协议" alt="知识共享许可协议" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAAAPCAIAAAD8q9/YAAAABGdBTUEAANbY1E9YMgAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIySURBVHjaYmAYYYARiP///z9SfMvIyAJhrdm0Glliz669M6fO7OjoKC8vx9Tm6up66tSptu5WcQlxIFdeVsHVyfXjh4+D3LeQeGXClHj54uXyxctx+RYIdu/ebWZmNrl/CoT74eOHwoLCoRLJWDy8fMkKYWFhXL6FAGBw3Lxxc8PajUD2x08fPHw8vH28h6qHL128lJ6eDmScPXtWWVkZmO6Bafj9+/dAEsgGigDFjY2NXVxcrl29BjWFiQnIRUs/EICcnDDZ+LXQonBhwvDt5c+fPgP9A2SHhYUBGUBbgWRnZyfQn+/evQPG/L1794CyQME7t+/AUzUwkWOWEEAAcTScASSBbKy+ZYQBZC7V/Yzu4a9fvgBJQUFBYJQCPQbxOTABA9lKSkpA8bS0tNDQUFgRD3X6z58/GFkYscYY3HsQ18O5aPEJkUVLCPSIYW4eHiAJ9C3Qb0AfAmMVUiwDuUA/A8UrKipmzZqFljjZ2Tn+//mPJ4ax1hDw+MSqHk2WVh7W09fl5eWF+BMYsXv27AHaCvQ5kA2MbSEhIaAIJLueOXNGUVkRokuAXwBYUeGPYYJ1BknqKW14INfDfV39z58+v3//Ph5twBAxMTGJjosOCPYHcmWl5Zobmrdu2TrI62FgaGIppaPjot6+fQOMUjyay8rKVFSVIb7l5xPYsWXHIPctvmoJ2H5KzUytrKxsb2/HqsfJ2en69esFJQXw9Nw/oX+0LT1I29IjrbPEABBgAEdwNeO7yfOaAAAAAElFTkSuQmCC" /></a>
27
+ <small>
28
+ Powered by <a href="https://jex.im/PlainSite/" target="_blank">PlainSite</a>.
29
+ </small>
30
+ </footer>
31
+ </body>
32
+ </html>
@@ -0,0 +1,8 @@
1
+ <header class="site-header">
2
+ <h1 class="site-title"><a href="<%=site.url%>" property="cc:attributionName" xmlns:cc="http://creativecommons.org/ns#" rel="cc:attributionURL"><%=site.name%></a></h1>
3
+ <nav class="header">
4
+ <a href="<%=site.url_for "/" %>">Home</a>
5
+ <a href="<%=site.url_for "about.html" %>">About</a>
6
+ <a href="<%=site.url_for "rss.xml" %>">RSS</a>
7
+ </nav>
8
+ </header>
@@ -0,0 +1,25 @@
1
+ ---
2
+ layout: base.html
3
+ ---
4
+
5
+ <% content_for :page_content do %>
6
+ <%= include 'header.html' %>
7
+ <% site.data.subs.sort_by {|cat| cat.name}.each do |cat| %>
8
+ <% next if cat.posts.empty? %>
9
+ <section class="category-posts">
10
+ <h2>
11
+ <a href="<%=site.url_for cat %>/index.html" rel="category"><%=cat.display_name%></a>
12
+ </h2>
13
+ <ul class="posts-list">
14
+ <% cat.posts.take(10).each do |p| %>
15
+ <li>
16
+ <a href="<%=p.url%>"><%=html_escape p.title%></a>
17
+ <small><time><%=p.date%></time></small>
18
+ <br />
19
+ </li>
20
+ <% end %>
21
+ </ul>
22
+ </section>
23
+ <% end %>
24
+ <br />
25
+ <% end %>
@@ -0,0 +1,41 @@
1
+ ---
2
+ layout: base.html
3
+ ---
4
+
5
+
6
+ <% content_for :page_title do %>
7
+ Page <%=display_num %> | Posts of <%=category.display_name%>
8
+ <% end %>
9
+
10
+ <% content_for :page_content do %>
11
+ <%= include 'header.html' %>
12
+ <section class="category-page">
13
+ <h2>
14
+ <small>Total: <%=total_pages_count%></small>
15
+ <a href="<%=url%>" rel="self">Page <%=display_num %></a>
16
+ |
17
+ <a href="<%=site.url_for "#{category.data_id}/index.html" %>"><%=category.display_name%></a>
18
+ </h2>
19
+ <ul class="posts-list">
20
+ <% posts.each do |p| %>
21
+ <li>
22
+
23
+ <a href="<%=p.url%>"><%=p.title%></a>
24
+ <small><time><%=p.date%></time></small>
25
+ <br/>
26
+ </li>
27
+ <% end %>
28
+ </ul>
29
+ <% if prev_page || next_page %>
30
+ <hr />
31
+ <nav class="near-posts link-list">
32
+ <% if next_page %>
33
+ <a href="<%=next_page.url%>" rel="next"><i>⇦</i><em>Next</em></a>
34
+ <% end %>
35
+ <% if prev_page %>
36
+ <a href="<%=prev_page.url%>" rel="prev" class="prev"><i>⇨</i><em>Previous</em></a>
37
+ <% end %>
38
+ </nav>
39
+ <% end %>
40
+ </section>
41
+ <% end %>
@@ -0,0 +1,81 @@
1
+ ---
2
+ layout: base.html
3
+ ---
4
+
5
+ <% content_for :page_title do %>
6
+ <%=title %>
7
+ <% end %>
8
+
9
+ <% content_for :page_content do %>
10
+ <nav class="category-path">
11
+ <a href="<%=site.url_for "/" %>" rel="home">Home</a> »
12
+ <% category.to_a[1..-1].each do |cat| %>
13
+ <a href="<%=site.url_for cat %>/index.html" rel="category"><%=cat.display_name%></a> »
14
+ <% end %>
15
+ <em><%= title %></em>
16
+ </nav>
17
+ <% if respond_to? :github_url %>
18
+ <a class="github-fork" target="_blank" href="<%=github_url%>" rel="alternate"><img width="149" height="149" src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" /></a>
19
+ <% end %>
20
+
21
+ <%
22
+ ltag="lang='#{lang}'" if respond_to? :lang
23
+ %>
24
+ <article <%=ltag%> id="article">
25
+
26
+ <h1 class="article-title">
27
+ <a href="<%=url%>" rel="self"><%= title %></a>
28
+ <small><a href="<%=site.url%>" rel="author"><%=site.author%></a> — <time><%=date%></time></small>
29
+ </h1>
30
+
31
+
32
+
33
+ <%=self.content%>
34
+
35
+ <% if respond_to? :github_url %>
36
+ <h4>项目地址</h4>
37
+ <p>Github:<a target="_blank" href="<%=github_url%>" rel="alternate"><%=github_url%></a></p>
38
+ <% end %>
39
+
40
+
41
+ </article>
42
+ <hr />
43
+ <% if prev_post || next_post %>
44
+ <nav class="near-posts link-list">
45
+ <% if next_post %>
46
+ <a href="<%=next_post.url%>" rel="next"><i>⇦</i><em><%=html_escape next_post.title%></em></a>
47
+ <% end %>
48
+ <% if prev_post %>
49
+ <a href="<%=prev_post.url%>" rel="prev" class="prev"><i>⇨</i><em><%=html_escape prev_post.title%></em></a>
50
+ <% end %>
51
+ </nav>
52
+ <hr />
53
+ <% end %>
54
+
55
+ <!-- Build: <%= Time.now%> -->
56
+ <% if site.config['disqus_id'] %>
57
+ <div id="disqus_thread"></div>
58
+ <script type="text/javascript">
59
+ /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
60
+ var disqus_shortname = "<%=site.config['disqus_id']%>"; // required: replace example with your forum shortname
61
+
62
+ var disqus_config = function () {
63
+ this.page.url = "<%= File.join $site.url,url %>";
64
+ this.page.identifier = "<%= data_id %>";
65
+ this.page.category_id = "<%= category.data_id %>";
66
+ this.page.title = "<%= title%>";
67
+ };
68
+
69
+ /* * * DON'T EDIT BELOW THIS LINE * * */
70
+ (function() {
71
+ var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
72
+ dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
73
+ (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
74
+ })();
75
+ </script>
76
+ <noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
77
+ <p>Comments powered by <a href="http://disqus.com/" target="_blank">Disqus!</a></p>
78
+ <% else %>
79
+ <p>Config <code>disqus_id</code> in <code>_src/config.yml</code> to enable comments!</p>
80
+ <% end %>
81
+ <% end %>
@@ -0,0 +1,29 @@
1
+ <%=
2
+ require 'rss/maker'
3
+
4
+ content = RSS::Maker.make('2.0') do |m|
5
+ m.channel.updated = Time.now.to_s
6
+ m.channel.title = site.name
7
+ m.channel.link = site.url
8
+ m.channel.description = site.name
9
+ m.items.do_sort = false
10
+
11
+ posts.each do |post|
12
+ m.items.new_item do |item|
13
+ item.title = post.title
14
+ item.author = site.author
15
+ item.link = post.url
16
+ item.description= post.content
17
+ item.date = post.date.to_s
18
+ if post.respond_to? :updated_date
19
+ item.updated = post.updated_date.to_s
20
+ else
21
+ item.updated = Time.now.to_s
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ content.to_s
28
+
29
+ %>
@@ -0,0 +1,63 @@
1
+ #coding:utf-8
2
+
3
+ require 'test/unit'
4
+ require 'fileutils'
5
+ require 'PlainSite/Data/Post'
6
+ require 'PlainSite/Data/PostList'
7
+ require 'PlainSite/Data/Category'
8
+ require 'PlainSite/Site'
9
+ include PlainSite::Data
10
+ include PlainSite
11
+
12
+ class CategoryTest < Test::Unit::TestCase
13
+ FIXTURES_DIR=File.realpath (File.join File.dirname(__FILE__),'fixtures')
14
+ def setup
15
+ @site_root=File.join FIXTURES_DIR,'test-site'
16
+ FileUtils.mkdir_p @site_root
17
+ @site=Site.new @site_root
18
+ @site.init_scaffold true
19
+ end
20
+ def teardown
21
+ FileUtils.rm_rf @site_root
22
+ end
23
+
24
+ def test_category
25
+ FileUtils.cp_r File.join(FIXTURES_DIR,'category-demo'),@site.data_path
26
+
27
+ assert @site.data.root? == true ,'Site Root'
28
+ assert @site.data.data_id == '' ,'Site Root'
29
+
30
+ cat=@site.data / :'category-demo'
31
+
32
+ assert cat,'Read category demo'
33
+ assert cat.root? == false ,'Category should not be root'
34
+ assert @site.data.root? ,'site.data is root'
35
+ assert cat.display_name=='DemoDemo','Category display name'
36
+
37
+ assert cat.has_index, 'Category has its index'
38
+
39
+ post1=cat / :post1
40
+ post2=cat / :post2
41
+ assert post1.data_id=='category-demo/post1','Read post1'
42
+ assert post2.category.data_id==cat.data_id,'Read post2'
43
+
44
+ assert PostList===cat['*'],'Read post list'
45
+
46
+ subs=cat.subs
47
+ assert subs.length==2,'Sub category should be 2'
48
+
49
+ sub1=cat['sub-category1']
50
+ assert sub1.display_name=='Sub category1','Sub category display name'
51
+
52
+ sub1=cat / 'sub-category1'
53
+ assert sub1.display_name=='Sub category1','Sub category display name'
54
+
55
+
56
+ cats=sub1.to_a
57
+ assert cats[0].data_id==@site.data.data_id,'First should be root category'
58
+ assert cats[1].data_id=='category-demo','Second should be category-demo category'
59
+ assert cats[2].data_id=='category-demo/sub-category1','Third should be sub-category1 category'
60
+ assert cats[3].nil?,'Fourth should be nil'
61
+
62
+ end
63
+ end