docwu 0.0.1 → 0.0.3

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.
data/README.md CHANGED
@@ -1,24 +1,36 @@
1
1
  # doc wu
2
2
 
3
- This project rocks and uses MIT-LICENSE.
3
+ This project rocks and uses MIT-LICENSE. Docwu mains Documents Work Up!
4
4
 
5
5
  ## A markdown doc generations
6
6
 
7
7
  ## 结构
8
8
 
9
9
  ```
10
- workspace
10
+ - workspace
11
11
 
12
- - assets:
13
- + javascripts:
14
- + stylesheets:
15
- + images:
16
- - sources:
17
- - layouts:
18
- - default.mustache
19
- - pages:
20
- - index.mustache
21
- - posts:
22
- -
12
+ assets/
13
+ files/
14
+ images/
15
+ javascripts/
16
+ application.js
17
+ document_folder.js
18
+ document_post.js
19
+ stylesheets/
20
+ application.css
21
+ document_folder.css
22
+ document_post.css
23
+ ▸ doc/
24
+ ▾ layouts/
25
+ ▸ partials/
26
+ folder.mustache
27
+ post.mustache
28
+ ▾ pages/
29
+ index.markdown
30
+ .gitignore
31
+ config.yml
32
+ Gemfile
33
+ Gemfile.lock
34
+ worker*
23
35
 
24
36
  ```
data/bin/docwu ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'docwu'
4
+
5
+ Docwu.start('.')
data/lib/docwu/config.rb CHANGED
@@ -12,34 +12,47 @@ module Docwu
12
12
  end
13
13
  end
14
14
 
15
- #
16
- # src_paths
17
- # asset_paths
18
- # layout_paths
19
- # output_path
20
- #
21
15
  class Config
22
- attr_reader :src_paths, :asset_paths, :layout_paths, :output_path, :data
16
+ # attr_reader :src_paths, :asset_paths, :layout_paths, :output_path, :data
23
17
 
24
- def data= a
25
- @data ||= a
18
+ attr_reader :routes, :params, :worker, :workspace, :docwu_env, :logger
19
+
20
+ def logger= a
21
+ @logger ||= (a || ::Logger.new(STDOUT))
22
+ end
23
+
24
+ def routes= a
25
+ @routes ||= a
26
+ end
27
+
28
+ def params= a={}
29
+ @params ||= a
26
30
  end
27
31
 
28
- def src_paths= a
29
- @src_paths ||= a
32
+ def worker= a
33
+ @worker ||= a
30
34
  end
31
35
 
32
- def asset_paths= a
33
- @asset_paths ||= a
36
+ def workspace= a
37
+ @workspace ||= a
34
38
  end
35
39
 
36
- def layout_paths= a
37
- @layout_paths ||= a
40
+ def docwu_env= a
41
+ @docwu_env ||= 'development'
38
42
  end
39
43
 
40
- def output_path= a
41
- @output_path ||= a
44
+ def topics_path
45
+ @topics_path ||= ("#{self.workspace}/topics")
42
46
  end
47
+
48
+ def layouts_path
49
+ @layouts_path ||= ("#{self.workspace}/layouts")
50
+ end
51
+
52
+ def deploy_path
53
+ @deploy_path ||= ("#{self.workspace}/_deploy")
54
+ end
55
+
43
56
  end
44
57
  end
45
58
 
data/lib/docwu/folder.rb CHANGED
@@ -1,42 +1,111 @@
1
+ # -*- encoding : utf-8 -*-
1
2
  module Docwu
2
3
  class Folder
3
4
  # 一个文件夹下面可能会有很多文件或文件夹的
4
- attr_reader :posts, :folders, :parent, :path, :worker, :dir
5
+ attr_reader :posts, :folders, :parent, :worker, :name,
6
+ :dest, :path, :src, :url, :index_post, :index_dest,
7
+ :parents, :content_data
5
8
 
6
9
  def initialize attrs={}
7
- @path = attrs[:path]
8
10
  @worker = attrs[:worker]
9
11
  @parent = attrs[:parent]
10
- @house = attrs[:house]
11
12
 
12
- @dir = attrs[:dir]
13
+ @parents = if @parent.nil?
14
+ []
15
+ else
16
+ @parent.parents.dup << @parent
17
+ end
18
+
19
+ @src = attrs[:src]
20
+ @path = attrs[:path]
21
+ @url = "/#{@path}/index.html"
22
+
23
+ @name = ::Docwu::Utils.filename(@path)
24
+
25
+ @dest = "#{self.worker.deploy_path}/#{self.path}"
26
+ @index_dest = "#{self.dest}/index.html"
27
+ # -------------------------------------
13
28
 
14
29
  @posts = []
15
30
  @folders = []
16
31
 
17
- ::Dir.glob("#{self.path}/*").each do |_path|
18
- _dir = _path.sub(self.path, '')
32
+ ::Dir.glob("#{self.src}/*").each do |_src|
33
+ _name = "#{_src.sub("#{self.src}/", '')}"
34
+
35
+ if File.exists?(_src)
36
+ if File.file?(_src) # 如果一个文件
37
+ _post = ::Docwu::Post.new(:src => _src, :parent => self, :worker => self.worker, :path => "#{self.path}/#{_name}")
19
38
 
20
- if File.exists?(_path)
21
- if File.file?(_path) # 如果一个文件
22
- @posts << ::Docwu::Post.new(:path => _path, :parent => self, :worker => self.worker, :dir => _dir)
23
- elsif File.directory?(_path) # 如果是一个文件夹
24
- @folders << self.class.new(:path => _path, :parent => self, :worker => self.worker, :dir => _dir)
39
+ if _post.index?
40
+ @index_post = _post
41
+ else
42
+ @posts << _post
43
+ end
44
+ elsif File.directory?(_src) # 如果是一个文件夹
45
+ @folders << self.class.new(:src => _src, :parent => self, :worker => self.worker, :path => "#{self.path}/#{_name}")
25
46
  end
26
47
  end
27
48
  end
49
+
50
+ self.posts.sort! { |a, b| b.ranking <=> a.ranking }
51
+ self.posts.sort! { |a, b| b.datetime <=> a.datetime }
52
+
53
+ # TODO: 是否从index文件中读取data呢?
54
+ end
55
+
56
+ def parent_datas
57
+ self.parents.map(&:to_data)
58
+ end
59
+
60
+ # 转为数据
61
+ def to_data
62
+ {
63
+ 'name' => self.name,
64
+ 'url' => self.url,
65
+ 'title' => self.name,
66
+ 'folders' => self.folders.map(&:to_data),
67
+ 'posts' => self.posts.map(&:to_data)
68
+ }
69
+ end
70
+
71
+ def index_page_data
72
+ if self.has_index?
73
+ self.index_post.page_data
74
+ else
75
+ {}
76
+ end
28
77
  end
29
78
 
30
- def generate space=nil
79
+ def generate
80
+ _prepare_data
81
+
82
+ # TODO: index : 需要生成首页!
83
+ _template = if self.has_index?
84
+ self.worker.layouts[self.index_post.layout]
85
+ end
86
+
87
+ _template ||= self.worker.layouts['folder']
88
+
89
+ ::Docwu::Render.generate(
90
+ :content_data => self.content_data,
91
+ :dest => self.index_dest,
92
+ :template => _template
93
+ )
94
+
31
95
  self.folders.each do |folder|
32
- folder.generate space
96
+ folder.generate
33
97
  end
34
98
 
35
99
  self.posts.each do |post|
36
- post.generate space
100
+ post.generate
37
101
  end
38
102
  end
39
103
 
104
+ # 有首页文件了
105
+ def has_index?
106
+ !!(self.index_post)
107
+ end
108
+
40
109
  def folder?
41
110
  true
42
111
  end
@@ -47,5 +116,20 @@ module Docwu
47
116
 
48
117
  private
49
118
 
119
+ def _prepare_data
120
+ @content_data = ::Docwu::Utils.hash_deep_merge(self.worker.data, {
121
+ 'reader' => {
122
+ 'folder' => self.to_data,
123
+ 'folders' => self.parent_datas
124
+ }
125
+ })
126
+
127
+ # puts ""
128
+ # puts ""
129
+ # puts ""
130
+ # puts ""
131
+ # pp @content_data
132
+ end
133
+
50
134
  end
51
135
  end
data/lib/docwu/post.rb CHANGED
@@ -1,61 +1,132 @@
1
+ # -*- encoding : utf-8 -*-
1
2
  module Docwu
2
3
  class Post
3
4
  # 一个文件夹下面可能会有很多文件或文件夹的
4
- attr_reader :parent, :path, :worker, :house, :dir, :content_data
5
+ attr_reader :parent,
6
+ :worker, # worker对象
7
+ :content_data,
8
+ :dest, # 目标地址
9
+ :path, # 访问地址
10
+ :src, # 原文件地址
11
+ :url, # URL 地址
12
+ :content_type,
13
+ :name,
14
+ :file_name, # 文件名
15
+ :datetime,
16
+ :ranking
17
+
18
+ def parents
19
+ if self.parent.nil?
20
+ []
21
+ else
22
+ self.parent.parents.dup << self.parent
23
+ end
24
+ end
25
+
26
+ def parent_datas
27
+ self.parents.map(&:to_data)
28
+ end
5
29
 
6
30
  def initialize attrs={}
7
- @path = attrs[:path]
8
- @house = attrs[:house]
9
31
  @parent = attrs[:parent]
32
+
10
33
  @worker = attrs[:worker]
11
34
 
12
- @dir = attrs[:dir]
35
+ @src = attrs[:src]
13
36
 
14
37
  _parse_content = self.parse_content
15
38
 
16
- @content_data = {}
39
+ # 将合并来自worker的数据
40
+ @content_data = ::Docwu::Utils.hash_deep_merge(self.worker.data, 'page' => _parse_content[:data]) # 来自页面的数据
41
+
42
+ @content_type = @content_data['content_type'] || 'html'
43
+
44
+ _extend_name = case self.content_type
45
+ when 'html'
46
+ 'html'
47
+ else
48
+ 'html'
49
+ end
50
+
51
+ # URL ---------------------------------
52
+ _filename_extless = ::Docwu::Utils.filename_extless(attrs[:path])
53
+
54
+ @path = "#{_filename_extless}.#{_extend_name}"
55
+ @url = "/#{@path}"
56
+ @dest = "#{self.worker.deploy_path}/#{self.path}"
57
+
58
+ @file_name = ::Docwu::Utils.filename(_filename_extless)
17
59
 
18
- self.content_data.merge!(_parse_content[:data])
60
+ @name = self.file_name
61
+ @datetime = self.page_data['datetime'] # 创建时间
62
+ @ranking = self.page_data['ranking'].to_i # 创建时间
63
+
64
+ # puts "post to: -----------------> desc: #{self.dest}"
65
+ # puts " src: #{self.src}"
66
+ # puts " path: #{self.path}"
67
+ # puts " url: #{self.url}"
68
+ # -------------------------------------
69
+ end
70
+
71
+ def template
72
+ self.worker.layouts[self.layout] || self.worker.layouts['post'] || self.worker.layouts['application']
73
+ end
74
+
75
+ # 是否是首页?
76
+ def index?
77
+ self.file_name == 'index'
19
78
  end
20
79
 
21
80
  def layout
22
- self.worker.layouts[self.content_data['layout']] || self.worker.layouts['default.mustache']
81
+ self.page_data['layout']
82
+ end
83
+
84
+ def outline
85
+ @outline ||= self.page_data['outline'].to_s
86
+ end
87
+
88
+ def to_data
89
+ introduction_size = 32
90
+
91
+ introduction = "#{self.outline[0, introduction_size]}#{' ...' if self.outline.size > introduction_size}"
92
+
93
+ {
94
+ 'name' => self.name,
95
+ 'url' => self.url,
96
+ 'title' => self.title,
97
+ 'outline' => self.outline,
98
+ 'introduction' => introduction
99
+ }
100
+ end
101
+
102
+ # 页面数据
103
+ def page_data
104
+ self.content_data['page'] ||= {}
105
+ end
106
+
107
+ def title
108
+ self.page_data['title'] || self.url
23
109
  end
24
110
 
25
111
  # 渲染
26
- def generate space=nil
112
+ def generate
113
+ _prepare_data
114
+
27
115
  _parse_content = self.parse_content
28
116
 
29
117
  _content_text = _parse_content[:text]
30
118
 
31
- _template = ::Docwu::Utils.read_file(self.layout)
32
-
33
119
  _path = self.path
34
- _dest = self.dest(space)
35
-
36
- puts " -> generate post: form #{_path} to #{_dest}"
37
- puts " layout: #{self.layout}"
120
+ _dest = self.dest
38
121
 
39
122
  ::Docwu::Render.generate(
40
123
  :content_text => _content_text,
41
124
  :content_data => self.content_data,
42
125
  :dest => _dest,
43
- :template => _template
126
+ :template => self.template
44
127
  )
45
128
  end
46
129
 
47
- def dest space
48
- _dest = "#{self.worker.output_path}"
49
-
50
- if space
51
- _dest << "/#{space}"
52
- end
53
-
54
- _dest << self.dir
55
-
56
- _dest
57
- end
58
-
59
130
  def folder?
60
131
  false
61
132
  end
@@ -63,23 +134,34 @@ module Docwu
63
134
  def post?
64
135
  true
65
136
  end
66
-
137
+
67
138
  # 解析正文
68
139
  def parse_content
69
- _content = ::File.read(self.path)
140
+ _content = ::File.read(self.src)
141
+
142
+ ::Docwu::Utils.parse_marked_content(_content)
143
+ end
144
+
145
+ def has_folder?
146
+ self.parent.is_a?(::Docwu::Folder)
147
+ end
148
+
149
+ private
70
150
 
71
- _content_text = ''
72
- _content_data = {}
151
+ def _prepare_data
152
+ self.content_data['reader'] ||= {}
73
153
 
74
- _parse_content = _content.to_s.split(/---+\n/)
154
+ _data = {
155
+ 'folders' => self.parent_datas,
156
+ 'post' => self.to_data
157
+ }
75
158
 
76
- if _parse_content.size > 2 && _parse_content.first.to_s == ''
77
- _content_text << _parse_content[2]
78
- # 从上下文中读取配置
79
- _content_data.merge!(::YAML.load(_parse_content[1]))
159
+ if self.has_folder?
160
+ (_data['folder'] ||= {}).merge!(self.parent.to_data)
80
161
  end
81
162
 
82
- {:data => _content_data, :text => _content_text}
163
+ # 合并, datas
164
+ self.content_data['reader'].merge!(_data)
83
165
  end
84
166
  end
85
167
  end
data/lib/docwu/render.rb CHANGED
@@ -1,3 +1,8 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'redcarpet'
3
+ require 'coderay'
4
+ require "nokogiri"
5
+
1
6
  module Docwu
2
7
  class Render
3
8
  class << self
@@ -6,30 +11,62 @@ module Docwu
6
11
  end
7
12
  end
8
13
 
14
+ #
15
+ # usage:
16
+ # ::Docwu::Render.generate(
17
+ # :content_data => ''
18
+ # )
19
+ # options:
20
+ # - content_data
21
+ # - content_text
22
+ # - dest
23
+ # - template
24
+ #
9
25
  def generate(options={})
10
26
  content_data = options[:content_data] || {}
11
27
  content_text = options[:content_text] || ''
12
28
  content_result = ''
13
29
  dest = options[:dest]
30
+ template = options[:template]
14
31
 
15
32
  # 读取标记类型
16
33
  marktype = (content_data['marktype'] || 'markdown').to_s
17
- content_type = (content_data['content_type'] || 'html').to_s
34
+
35
+ # 目录
36
+ _catalogs = []
18
37
 
19
38
  case marktype
20
39
  when 'markdown'
21
40
  _mark_options = [:hard_wrap, :autolink, :no_intraemphasis, :fenced_code, :gh_blockcode]
22
41
 
23
- content_result << ::RedcarpetCompat.new(content_text, *_mark_options).to_html
42
+ _html = ::RedcarpetCompat.new(content_text, *_mark_options).to_html
43
+
44
+ # 获取一个html代码的目录结果
45
+ _catalogs_result = ::Docwu::Utils.html_catalogable(_html)
46
+
47
+ _catalogs = _catalogs_result['catalogs']
48
+
49
+ content_result << ::Docwu::Utils.syntax_highlighter(_catalogs_result['html'])
24
50
  else
25
51
  # FIXME: no
26
52
  end
27
53
 
28
- content_data['content'] = content_result
54
+ content_data['page'] ||= {}
55
+
56
+ # 正文
57
+ content_data['page']['content'] = content_result
58
+ content_data['page']['content_present?'] = content_result.size > 0
59
+
60
+ # 目录
61
+ content_data['page']['catalogs'] = _catalogs
62
+
63
+ ::Docwu::Utils.formated_hashed!(content_data)
64
+
65
+ # pp content_data
66
+ # puts "#{template}"
29
67
 
30
- puts " --------------------> write to: #{dest}, #{content_result}"
31
68
  # 页面的内容
32
- # ::Docwu::Utils.write_file dest, ::MustacheRender::Mustache.render(template, data.merge('page' => context_data))
69
+ ::Docwu::Utils.write_file dest, ::MustacheRender::Mustache.render(template, content_data)
33
70
  end
34
71
 
35
72
  end
@@ -0,0 +1,6 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module Docwu
3
+ class Route
4
+ end
5
+ end
6
+
data/lib/docwu/server.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # -*- encoding : utf-8 -*-
1
2
  # http://tobyho.com/2009/09/16/http-server-in-5-lines-with/
2
3
  # https://github.com/rack/rack/blob/master/lib/rack/handler/thin.rb
3
4
  # https://github.com/macournoyer/thin/blob/master/lib/thin/server.rb
@@ -10,21 +11,24 @@ module Docwu
10
11
  #
11
12
  # Rack::Handler::Thin.run(staticMe, :port => 8080
12
13
 
14
+ require 'thin'
13
15
  require 'rack'
14
16
 
15
- def self.process(options={})
16
- options['destination'] ||= ::Docwu.config.output_path
17
+ def self.process(options={}, &block)
18
+ options['destination'] ||= ::Docwu.config.deploy_path
17
19
  destination = options['destination']
18
20
  FileUtils.mkdir_p(destination)
19
21
 
20
- options['port'] ||= 5656
21
- options['host'] ||= '0.0.0.0'
22
-
23
22
  staticMe = Rack::Builder.new do
24
23
  run Rack::Directory.new(destination)
25
24
  end
26
25
 
27
- Rack::Handler::Thin.run(staticMe, :Port => options['port'], :Host => options['host'])
26
+ pp options
27
+
28
+ ::Thin::Server.start(options.delete(:Host), options.delete(:Port), staticMe, options, &block)
29
+
30
+ # Rack::Handler::Thin.run(staticMe, options)
31
+
28
32
  # Rack::Handler::WEBrick.run(staticMe, :Port => options['port'], :Host => options['host'])
29
33
  # Rack::Handler::Mongrel.run(staticMe, :Port => options['port'], :Host => options['host'])
30
34
  end
@@ -0,0 +1,93 @@
1
+ module Docwu
2
+ class Topic
3
+ attr_reader :worker, :dest, :path, :src, :url, :content_data, :file_name, :name, :title
4
+
5
+ def initialize attrs={}
6
+ @worker = attrs[:worker]
7
+
8
+ @path = attrs[:path]
9
+ @src = attrs[:src]
10
+
11
+ _parse_content = self.parse_content
12
+
13
+ # 将合并来自worker的数据
14
+ @content_data = ::Docwu::Utils.hash_deep_merge(self.worker.data, 'page' => _parse_content[:data]) # 来自页面的数据
15
+
16
+ # URL ---------------------------------
17
+ _filename_extless = ::Docwu::Utils.filename_extless(self.path)
18
+
19
+ @url = "/#{@path}"
20
+ @dest = "#{self.worker.deploy_path}/#{self.path}"
21
+
22
+ @file_name = ::Docwu::Utils.filename(_filename_extless)
23
+
24
+ @name = self.content_data['page']['name'] || self.file_name
25
+
26
+ # -------------------------------------
27
+ end
28
+
29
+ # 页面数据
30
+ def page_data
31
+ self.content_data['page'] ||= {}
32
+ end
33
+
34
+ def title
35
+ self.page_data['title'] || self.url
36
+ end
37
+
38
+ def url
39
+ self.path
40
+ end
41
+
42
+ def to_data
43
+ {
44
+ 'name' => self.name,
45
+ 'url' => self.url,
46
+ 'title' => self.title
47
+ }
48
+ end
49
+
50
+ def generate
51
+ _prepare_data
52
+
53
+ _parse_content = self.parse_content
54
+
55
+ _content_text = _parse_content[:text]
56
+
57
+ ::Docwu::Render.generate(
58
+ :content_text => _content_text,
59
+ :content_data => self.content_data,
60
+ :dest => self.dest,
61
+ :template => self.template
62
+ )
63
+ end
64
+
65
+ def layout
66
+ self.page_data['layout']
67
+ end
68
+
69
+ def template
70
+ self.worker.layouts[self.layout] || self.worker.layouts['topic'] || self.worker.layouts['application']
71
+ end
72
+
73
+ # 解析正文
74
+ def parse_content
75
+ _content = ::File.read(self.src)
76
+
77
+ ::Docwu::Utils.parse_marked_content(_content)
78
+ end
79
+
80
+ private
81
+
82
+ def _prepare_data
83
+ self.content_data['reader'] ||= {}
84
+
85
+ _data = {
86
+ 'topic' => self.to_data
87
+ }
88
+
89
+ # 合并, datas
90
+ self.content_data['reader'].merge!(_data)
91
+ end
92
+ end
93
+ end
data/lib/docwu/utils.rb CHANGED
@@ -1,12 +1,64 @@
1
+ # -*- encoding : utf-8 -*-
1
2
  module Docwu
2
3
  class Utils
3
4
  class << self
5
+ def hash_deep_merge(hash, other_hash)
6
+ hash.merge(other_hash) do |key, oldval, newval|
7
+ oldval = oldval.to_hash if oldval.respond_to?(:to_hash)
8
+ newval = newval.to_hash if newval.respond_to?(:to_hash)
9
+ oldval.class.to_s == 'Hash' && newval.class.to_s == 'Hash' ? self.hash_deep_merge(oldval, newval) : newval
10
+ end
11
+ end
12
+
13
+ def hash_deep_merge!(hash, other_hash)
14
+ hash.replace(self.hash_deep_merge(hash, other_hash))
15
+ end
16
+
17
+ def formated_hashed! hash={}
18
+ hash.replace(self.formated_hashed(hash))
19
+ end
20
+
21
+ # 将hash中所有非hash的类型,转为hash, 以便前端调用
22
+ def formated_hashed hash={}
23
+ _res = {}
24
+
25
+ hash.each do |key, value|
26
+ if value.is_a?(Array)
27
+ _res[key] = value.map do |_val|
28
+ if _val.is_a?(Hash)
29
+ self.formated_hashed(_val)
30
+ else
31
+ {'value' => _val}
32
+ end
33
+ end
34
+
35
+ _res["#{key}_any?"] = value.any?
36
+ _res["#{key}_count"] = value.size
37
+
38
+ elsif value.is_a?(Hash)
39
+ _res[key] = self.formated_hashed(value)
40
+ else
41
+ _res[key] = value
42
+ end
43
+ end
44
+
45
+ _res
46
+ end
47
+
48
+ # 获取文件名
49
+ def filename path=''
50
+ path.split('/').last
51
+ end
52
+
53
+ def filename_extless _path=''
54
+ _path.chomp(File.extname(_path))
55
+ end
4
56
 
5
57
  def read_file path
6
58
  ::File.read(path)
7
59
  end
8
60
 
9
- def write_file path, content=''
61
+ def write_file dst, content=''
10
62
  ::FileUtils.mkdir_p(::File.dirname(dst))
11
63
 
12
64
  file = ::File.new(dst, 'w')
@@ -20,7 +72,117 @@ module Docwu
20
72
  ::FileUtils.cp_r(src, dst)
21
73
  end
22
74
 
75
+ def syntax_highlighter(html)
76
+ doc = ::Nokogiri::HTML(html)
77
+
78
+ doc.search("//pre").each do |pre|
79
+ lang = pre.attr('lang')
80
+
81
+ if lang
82
+ _lang_class = pre.attr('class').to_s.split(' ').select {|_itm| _itm.include?('lang-') }.first
83
+
84
+ if _lang_class
85
+ lang = _lang_class.gsub('lang-', '')
86
+ end
87
+ end
88
+
89
+ # debugger
90
+ if pre_code=pre.css('code')
91
+ lang = pre_code.attr('class').to_s
92
+ end
93
+
94
+ unless lang
95
+ lang = :text
96
+ end
97
+
98
+ text = pre.text.rstrip
99
+
100
+ begin
101
+ pre.replace ::CodeRay.scan(text, lang).div.to_s
102
+ rescue Exception => error
103
+ # TODO: error log
104
+ # puts "#{__FILE__} syntax_highlighter error: \ntext => #{text} \nlang => #{lang}\n origin error:#{error}"
105
+ end
106
+ end
107
+
108
+ doc.css('body').inner_html.to_s
109
+ end
110
+
111
+ # 解析 mark
112
+ def parse_marked_content src_content=''
113
+ _content_text = ''
114
+ _content_data = {}
115
+
116
+ # 读取页面的配置
117
+ content_lines = src_content.split(/\n/) # 根据换行分割
118
+
119
+ _data_lines = []
120
+ _text_lines = []
121
+
122
+ _data_num_a = -1
123
+ _data_num_b = -1
124
+
125
+ content_lines.each_with_index do |line, index|
126
+ if line =~ /--+/
127
+ if _data_num_a == -1
128
+ _data_num_a = index
129
+ elsif _data_num_b == -1
130
+ _data_num_b = index
131
+ else
132
+ break
133
+ end
134
+ end
135
+ end
136
+
137
+ if _data_num_a > -1 && _data_num_b > -1
138
+ # 说明有配置信息
139
+ _yaml = ::YAML.load(content_lines[_data_num_a + 1, _data_num_b -1].join("\n"))
140
+
141
+ if _yaml.is_a?(Hash)
142
+ _content_data.merge!(_yaml)
143
+ end
144
+
145
+ _content_text = content_lines[_data_num_b + 1, content_lines.size].join("\n")
146
+ else # 无页面配置信息
147
+ _content_text = src_content
148
+ end
149
+
150
+ {:data => _content_data, :text => _content_text}
151
+
152
+ end
153
+
154
+ # 获取一个html代码的目录结果
155
+ def html_catalogable html=''
156
+ doc = ::Nokogiri::HTML(html)
157
+
158
+ paths = doc.xpath('//h1|//h2|//h3|//h4|//h5|//h6')
159
+
160
+ index = 1
161
+
162
+ catalogs = paths.map do |path|
163
+ _name = path.name
164
+ _text = path.text
165
+
166
+ _anchor = "markup-#{_name}-#{index}"
167
+
168
+ index += 1
169
+
170
+ path.replace("<#{_name}><a name='#{_anchor}'></a>#{_text}</#{_name}>")
171
+
172
+ {
173
+ 'text' => _text,
174
+ 'name' => _name,
175
+ 'anchor' => _anchor
176
+ }
177
+ end
178
+
179
+ {
180
+ 'catalogs' => catalogs,
181
+ 'html' => doc.css('body').inner_html.to_s
182
+ }
183
+ end
23
184
  end
185
+
24
186
  end
25
187
  end
26
188
 
data/lib/docwu/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  module Docwu
3
- VERSION = "0.0.1"
3
+ VERSION = "0.0.3"
4
4
  end
data/lib/docwu/worker.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  # -*- encoding : utf-8 -*-
2
+ require 'date'
2
3
  module Docwu
3
4
  class Worker
4
5
 
@@ -26,95 +27,95 @@ module Docwu
26
27
  # - layouts:
27
28
  # - application.mustache
28
29
  #
29
- # data:
30
- # src_paths
31
- # asset_paths
32
- # layout_paths
33
- # output_path
34
- #
35
- attr_reader :src_paths, # 源文件地址们
36
- :output_path, # 要输出的路径
37
- :folders, # 项目文件夹们
38
- :asset_paths, # assets路径
39
- :layouts, # layouts路径
40
- :data # 数据
41
30
 
42
- def initialize attrs={}
43
- @data = attrs[:data] || Docwu.config.data || {}
44
- @src_paths = attrs[:src_paths] || Docwu.config.src_paths
31
+ attr_reader :layouts, :data, :deploy_path, :folders, :topics
45
32
 
46
- # 关于目录
47
- @folders = {}
48
- @layouts = {}
33
+ def initialize
34
+ @deploy_path = ::Docwu.config.deploy_path # 部署路径
49
35
 
50
- # 静态文件目录 --------------------------------------------------------
51
- @asset_paths = []
36
+ @data = {
37
+ 'worker' => {
38
+ 'copyright' => {
39
+ 'year' => ::Date.today.year,
40
+ 'content' => 'document world util',
41
+ 'name' => 'Doc WU'
42
+ }
43
+ }
44
+ }
52
45
 
53
- (attrs[:asset_paths] || Docwu.config.asset_paths || []).each do |_path|
54
- if File.exists?(_path) && File.directory?(_path)
55
- @asset_paths < _path
56
- end
57
- end
46
+ ::Docwu::Utils.hash_deep_merge!(@data['worker'], ::Docwu.config.worker)
58
47
 
59
- layout_paths = attrs[:layout_paths] || Docwu.config.layout_paths || []
48
+ self.data['page'] ||= {}
60
49
 
61
- # 计算出当前所有的asset_paths
62
- @src_paths.each do |_space, _path|
63
- _asset_path = "#{_path}/assets"
50
+ self.data['reader'] ||= {}
64
51
 
65
- if File.exists?(_asset_path) && File.directory?(_asset_path)
66
- @asset_paths << _asset_path
67
- end
52
+ # 关于目录
53
+ @folders = []
54
+ @layouts = {}
55
+ @topics = []
68
56
 
69
- _layout_path = "#{_path}/layouts"
57
+ # 布局模板
58
+ ::Docwu.config.routes['layouts'].each do |name, path|
59
+ _path = "#{::Docwu.config.layouts_path}/#{path}"
70
60
 
71
- if File.exists?(_layout_path) && File.directory?(_layout_path)
72
- layout_paths << _layout_path
61
+ if File.exists?(_path) && File.file?(_path)
62
+ @layouts[name] = File.read(_path)
73
63
  end
64
+ end
74
65
 
75
- _folder_path = "#{_path}/doc"
76
-
77
- puts " _folder_path---> #{_folder_path}"
66
+ # 原文件, 目标路径
67
+ ::Docwu.config.routes['topics'].each do |src, path|
68
+ _src_path = "#{::Docwu.config.topics_path}/#{src}"
78
69
 
79
- if File.exists?(_folder_path) && File.directory?(_folder_path)
80
- @folders[_space] = ::Docwu::Folder.new(:path => _folder_path, :worker => self, :dir => (_folder_path.sub(_path, '')))
70
+ if File.exists?(_src_path) && File.file?(_src_path)
71
+ @topics << ::Docwu::Topic.new(:src => _src_path, :path => path, :worker => self)
81
72
  end
82
73
  end
83
74
 
84
- layout_paths.each do |_path|
85
- Dir.glob("#{_path}/**/*").each do |_dir|
86
- if File.exists?(_dir) && File.file?(_dir)
87
- @layouts[_dir.sub("#{_path}/", '')] = _dir
88
- end
75
+ # 计算出当前所有的 folders 源, 目标
76
+ ::Docwu.config.routes['folders'].each do |_src, _path|
77
+ _folder_src = "#{plain_path("/#{_src}")}"
78
+
79
+ if File.exists?(_folder_src) && File.directory?(_folder_src)
80
+ @folders << ::Docwu::Folder.new(:src => _folder_src, :worker => self, :path => _path)
89
81
  end
90
82
  end
91
83
 
92
- @output_path = attrs[:output_path] || Docwu.config.output_path
84
+ # TODO: add 更多的全局数据
85
+
86
+ self.data['reader'].merge!(
87
+ 'global' => {
88
+ 'folders' => self.folders_data
89
+ }
90
+ )
93
91
 
94
- # puts self.output_path
95
- # puts self.folders
96
- # puts self.layouts
97
- # puts self.asset_paths
98
92
  end
99
93
 
100
94
  # 输出:
101
95
  # TODO: 先生成临时目录, 然后 -> deploy
102
96
  def generate
103
97
  # 删除要输出的路径
104
- FileUtils.rm_rf(self.output_path)
98
+ FileUtils.rm_rf(self.deploy_path)
105
99
 
106
100
  # 复制 assets 文件进去
107
- self.asset_paths.each do |_path|
108
- FileUtils.cp_r("#{_path}", "#{self.output_path}/")
101
+ FileUtils.cp_r("#{plain_path('/assets')}", "#{self.deploy_path}/")
102
+
103
+ self.folders.each do |folder|
104
+ folder.generate
109
105
  end
110
106
 
111
- self.folders.each do |space, folder|
112
- folder.generate space
107
+ self.topics.each do |topic|
108
+ topic.generate
113
109
  end
110
+ end
114
111
 
112
+ def plain_path(path)
113
+ "#{::Docwu.config.workspace}#{path}"
115
114
  end
116
115
 
117
- private
116
+ def folders_data
117
+ self.folders.map(&:to_data)
118
+ end
118
119
 
119
120
  end
120
121
  end
data/lib/docwu.rb CHANGED
@@ -1,23 +1,112 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  require "#{File.dirname(__FILE__)}/docwu/config"
3
+ require "#{File.dirname(__FILE__)}/docwu/route" # 定制页面路由器
4
+ require "#{File.dirname(__FILE__)}/docwu/topic"
3
5
  require "#{File.dirname(__FILE__)}/docwu/utils"
4
6
  require "#{File.dirname(__FILE__)}/docwu/worker"
5
7
  require "#{File.dirname(__FILE__)}/docwu/render"
6
8
  require "#{File.dirname(__FILE__)}/docwu/folder"
7
9
  require "#{File.dirname(__FILE__)}/docwu/post"
8
- require "#{File.dirname(__FILE__)}/docwu/category"
9
10
  require "#{File.dirname(__FILE__)}/docwu/server"
10
11
 
11
- require 'redcarpet'
12
- require 'coderay'
12
+ require 'pp'
13
13
  require 'yaml'
14
14
  require 'fileutils'
15
15
  require 'mustache_render'
16
+ require 'logger'
16
17
 
17
18
  module Docwu
18
19
 
19
- def self.generate
20
- Docwu::Worker.new.generate
20
+ # 程序开始
21
+ def self.start(workspace)
22
+ _start_time = Time.now
23
+
24
+ args = ARGV
25
+
26
+ _command = args.shift
27
+
28
+ _useful_cmds = ['g', 'generate', 's', 'server', '-h', '--help']
29
+
30
+ unless _useful_cmds.include?(_command)
31
+ raise "command #{_command} is not available, not in (#{_useful_cmds.join('|')})"
32
+ end
33
+
34
+ _default_params = {
35
+ '-p' => [5656],
36
+ '-a' => ['0.0.0.0'],
37
+ '-c' => ["#{workspace}/config.yml"],
38
+ 'DOCWU_ENV' => ['development'],
39
+ '-d' => [(args.delete('-d') == '-d')]
40
+ }
41
+
42
+ if ['--help', '-h'].include?(_command)
43
+ puts "docwu:"
44
+
45
+ _default_params.each do |_cmd, _cfg|
46
+ puts " #{_cmd}, #{_cfg[1]} (default: #{_cfg[0]})"
47
+ end
48
+
49
+ exit
50
+ end
51
+
52
+ # 获取参数
53
+ params = Hash[args.each_slice(2).to_a]
54
+
55
+ _default_params.each do |_k, _v|
56
+ params[_k] = params[_k] || _v.first
57
+ end
58
+
59
+ params['-p'] = params['-p'].to_i
60
+
61
+ # 需要生成
62
+ _need_generate = ['g', 'generate', 's', 'server'].include?(_command)
63
+
64
+ # 需要开启server
65
+ _need_server = ['s', 'server'].include?(_command)
66
+
67
+ _config_file = params['-c']
68
+
69
+ _config = {}
70
+
71
+ if File.exists?(_config_file) && File.file?(_config_file)
72
+ _yml = YAML.load(File.read(_config_file))
73
+
74
+ if _yml.is_a?(Hash)
75
+ _config.merge!(_yml['docwu'] || {})
76
+ end
77
+ else
78
+ raise "#{_config_file} not exists!"
79
+ end
80
+
81
+ _logger = ::Logger.new(STDOUT)
82
+ _logger.level = ::Logger::INFO
83
+
84
+ # docwu 的配置
85
+ ::Docwu.configure do |config|
86
+ config.logger = _logger
87
+ config.params = params.freeze
88
+ config.routes = (_config['routes'] || {}).freeze
89
+ config.worker = (_config['worker'] || {}).freeze
90
+ config.workspace = "#{workspace}".freeze
91
+ end
92
+
93
+ ::MustacheRender.configure do |config|
94
+ config.file_template_root_path = ::Docwu.config.layouts_path
95
+ config.logger = ::Docwu.config.logger
96
+ end
97
+
98
+ if _need_generate
99
+ ::Docwu::Worker.new.generate
100
+
101
+ _logger.info("generate: success, #{Time.now - _start_time}")
102
+ end
103
+
104
+ if _need_server
105
+ ::Docwu::Server.process(
106
+ :Port => ::Docwu.config.params['-p'],
107
+ :Host => ::Docwu.config.params['-a']
108
+ )
109
+ end
21
110
  end
22
111
 
23
112
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: docwu
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-08-28 00:00:00.000000000 Z
12
+ date: 2013-08-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: redcarpet
@@ -75,27 +75,46 @@ dependencies:
75
75
  - - ">="
76
76
  - !ruby/object:Gem::Version
77
77
  version: '0'
78
- description: Description of Docfive.
78
+ - !ruby/object:Gem::Dependency
79
+ name: nokogiri
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ description: Description of Doc Work UP.
79
95
  email:
80
96
  - andywang7259@gmail.com
81
- executables: []
97
+ executables:
98
+ - docwu
82
99
  extensions: []
83
100
  extra_rdoc_files: []
84
101
  files:
85
102
  - lib/docwu/server.rb
103
+ - lib/docwu/route.rb
86
104
  - lib/docwu/render.rb
87
105
  - lib/docwu/config.rb
88
106
  - lib/docwu/utils.rb
89
107
  - lib/docwu/version.rb
108
+ - lib/docwu/topic.rb
90
109
  - lib/docwu/worker.rb
91
110
  - lib/docwu/post.rb
92
- - lib/docwu/category.rb
93
111
  - lib/docwu/folder.rb
94
112
  - lib/docwu.rb
95
113
  - lib/tasks/docwu_tasks.rake
96
114
  - MIT-LICENSE
97
115
  - Rakefile
98
116
  - README.md
117
+ - bin/docwu
99
118
  homepage: http://github.com/xiuxian123/docwu
100
119
  licenses: []
101
120
  post_install_message:
@@ -110,7 +129,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
110
129
  version: '0'
111
130
  segments:
112
131
  - 0
113
- hash: -1575743025569223070
132
+ hash: -3240824084123490041
114
133
  required_rubygems_version: !ruby/object:Gem::Requirement
115
134
  none: false
116
135
  requirements:
@@ -119,11 +138,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
119
138
  version: '0'
120
139
  segments:
121
140
  - 0
122
- hash: -1575743025569223070
141
+ hash: -3240824084123490041
123
142
  requirements: []
124
143
  rubyforge_project:
125
144
  rubygems_version: 1.8.25
126
145
  signing_key:
127
146
  specification_version: 3
128
- summary: Summary of Docfive.
147
+ summary: Summary of Doc Work UP.
129
148
  test_files: []
File without changes