bookmaker 0.6.0 → 0.7.0.pre3
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.
- checksums.yaml +4 -4
- data/.document +5 -0
- data/.gitignore +48 -3
- data/Gemfile +12 -2
- data/Gemfile.lock +82 -0
- data/LICENSE.txt +20 -0
- data/Rakefile +72 -2
- data/VERSION +1 -0
- data/bookmaker.gemspec +126 -26
- data/lib/bookmaker.rb +3 -1
- data/lib/bookmaker/adapters/markdown.rb +9 -0
- data/lib/bookmaker/cli.rb +17 -7
- data/lib/bookmaker/exporter.rb +7 -1
- data/lib/bookmaker/generator.rb +22 -18
- data/lib/bookmaker/parser/epub.rb +32 -9
- data/lib/bookmaker/parser/html.rb +20 -10
- data/lib/bookmaker/parser/mobi.rb +1 -1
- data/lib/bookmaker/parser/pdf.rb +2 -1
- data/lib/bookmaker/stats.rb +93 -24
- data/lib/bookmaker/version.rb +9 -2
- data/templates/{back.erb → epub/back.erb} +0 -0
- data/templates/{copyright.erb → epub/copyright.erb} +0 -0
- data/templates/{cover.erb → epub/cover.erb} +0 -0
- data/templates/epub/cover.html +12 -0
- data/templates/{epub.erb → epub/page.erb} +0 -0
- data/templates/{epub.css → epub/user.css} +0 -0
- data/templates/html/copyright.erb +46 -0
- data/templates/{layout.css → html/layout.css} +0 -0
- data/templates/{html.erb → html/layout.erb} +0 -0
- data/templates/{syntax.css → html/syntax.css} +0 -0
- data/templates/html/thanks.erb +21 -0
- data/templates/{user.css → html/user.css} +0 -0
- data/templates/pdf/layout.erb +415 -0
- data/test/helper.rb +34 -0
- data/test/test_bookmaker.rb +7 -0
- metadata +100 -22
- data/features/basic.feature +0 -8
- data/features/export.feature +0 -8
- data/features/support/setup.rb +0 -1
|
@@ -21,6 +21,15 @@ module Kitabu
|
|
|
21
21
|
@engine ||= Object.const_get(MARKDOWN_LIBRARIES.find {|lib| Object.const_defined?(lib)})
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
+
def self.to_latex(content)
|
|
25
|
+
case engine.name
|
|
26
|
+
when "Redcarpet"
|
|
27
|
+
# render = Redcarpet::Render::HTML.new(:hard_wrap => true, :xhtml => true)
|
|
28
|
+
# Redcarpet::Markdown.new(render).render(content)
|
|
29
|
+
else
|
|
30
|
+
engine.new(content).to_latex
|
|
31
|
+
end
|
|
32
|
+
end
|
|
24
33
|
# Convert Markdown to HTML.
|
|
25
34
|
def self.to_html(content)
|
|
26
35
|
case engine.name
|
data/lib/bookmaker/cli.rb
CHANGED
|
@@ -55,15 +55,25 @@ module Bookmaker
|
|
|
55
55
|
stats = Bookmaker::Stats.new(root_dir)
|
|
56
56
|
|
|
57
57
|
say [
|
|
58
|
-
"Chapters: #{stats.chapters}",
|
|
59
|
-
"
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
58
|
+
# "Chapters: #{stats.chapters}",
|
|
59
|
+
"Goal: #{sprintf("%7d", stats.target)}",
|
|
60
|
+
"Words: #{sprintf("%7d", stats.words)}",
|
|
61
|
+
" -------",
|
|
62
|
+
"Left: #{sprintf("%7d", stats.remaining)}",
|
|
63
|
+
"\nProgress: #{sprintf("%5d", stats.today)}"
|
|
64
64
|
].join("\n")
|
|
65
65
|
end
|
|
66
|
-
|
|
66
|
+
|
|
67
|
+
desc "move old_id new_id", "Move scene to new sequence."
|
|
68
|
+
def move(oid,nid)
|
|
69
|
+
s = Structure.new(root_dir)
|
|
70
|
+
s.move(oid,nid)
|
|
71
|
+
end
|
|
72
|
+
desc "trash [OPTIONS]", "Move scene to trash."
|
|
73
|
+
def trash(scene_id)
|
|
74
|
+
s = Structure.new(root_dir)
|
|
75
|
+
s.trash(scene_id)
|
|
76
|
+
end
|
|
67
77
|
private
|
|
68
78
|
def config
|
|
69
79
|
YAML.load_file(config_path).with_indifferent_access
|
data/lib/bookmaker/exporter.rb
CHANGED
|
@@ -21,6 +21,12 @@ module Bookmaker
|
|
|
21
21
|
helper = root_dir.join("config/helper.rb")
|
|
22
22
|
load(helper) if helper.exist?
|
|
23
23
|
|
|
24
|
+
raise "Missing Templates directory (_templates)" unless File.exist?("_templates")
|
|
25
|
+
raise "Missing Images directory (_images)" unless File.exist?("_images")
|
|
26
|
+
raise "Missing Output directory (_output)" unless File.exist?("_output")
|
|
27
|
+
|
|
28
|
+
puts Dependency.xelatex?
|
|
29
|
+
|
|
24
30
|
export_pdf = [nil, "pdf"].include?(options[:only])
|
|
25
31
|
export_html = [nil, "html", "mobi", "epub"].include?(options[:only])
|
|
26
32
|
export_epub = [nil, "mobi", "epub"].include?(options[:only])
|
|
@@ -50,7 +56,7 @@ module Bookmaker
|
|
|
50
56
|
end
|
|
51
57
|
|
|
52
58
|
Notifier.notify(
|
|
53
|
-
:image => Bookmaker::ROOT.join("
|
|
59
|
+
:image => Bookmaker::ROOT.join("_templates/ebook.png"),
|
|
54
60
|
:title => "Bookmaker",
|
|
55
61
|
:message => "Your \"#{config[:title]}\" e-book has been exported!"
|
|
56
62
|
)
|
data/lib/bookmaker/generator.rb
CHANGED
|
@@ -12,30 +12,34 @@ module Bookmaker
|
|
|
12
12
|
template "config.erb", "_bookmaker.yml"
|
|
13
13
|
end
|
|
14
14
|
def copy_templates
|
|
15
|
-
copy_file "
|
|
16
|
-
copy_file "dp-logo.png",
|
|
15
|
+
copy_file "pdf/layout.erb", "_templates/pdf/layout.erb"
|
|
16
|
+
copy_file "dp-logo.png", "_images/dp-logo.png"
|
|
17
|
+
|
|
18
|
+
copy_file "html/layout.erb", "_templates/html/layout.erb"
|
|
19
|
+
copy_file "html/thanks.erb", "_templates/html/thanks.erb"
|
|
20
|
+
copy_file "html/copyright.erb", "_templates/html/copyright.erb"
|
|
21
|
+
copy_file "html/user.css", "_templates/html/user.css"
|
|
22
|
+
copy_file "html/layout.css", "_templates/html/layout.css"
|
|
23
|
+
copy_file "html/syntax.css", "_templates/html/syntax.css"
|
|
17
24
|
|
|
18
|
-
copy_file "
|
|
19
|
-
copy_file "
|
|
20
|
-
copy_file "
|
|
21
|
-
copy_file "
|
|
25
|
+
copy_file "epub/back.erb", "_templates/epub/back.html"
|
|
26
|
+
copy_file "epub/copyright.erb", "_templates/epub/copyright.erb"
|
|
27
|
+
copy_file "epub/cover.erb", "_templates/epub/cover.erb"
|
|
28
|
+
copy_file "epub/cover.html", "_templates/epub/cover.html"
|
|
29
|
+
copy_file "epub/page.erb", "_templates/epub/page.erb"
|
|
30
|
+
copy_file "epub/user.css", "_templates/epub/user.css"
|
|
22
31
|
|
|
23
|
-
copy_file "
|
|
24
|
-
copy_file "
|
|
25
|
-
copy_file "
|
|
26
|
-
copy_file "
|
|
27
|
-
copy_file "epub.css", "templates/epub/user.css"
|
|
28
|
-
copy_file "cover.jpg", "images/cover.jpg"
|
|
29
|
-
copy_file "rakefile.rb", "Rakefile"
|
|
30
|
-
copy_file "extras.tex", "extras/characters.tex"
|
|
31
|
-
copy_file "extras.tex", "extras/dedicationls.tex"
|
|
32
|
+
copy_file "cover.jpg", "_images/cover.jpg"
|
|
33
|
+
copy_file "rakefile.rb", "Rakefile"
|
|
34
|
+
copy_file "extras.tex", "_extras/characters.tex"
|
|
35
|
+
copy_file "extras.tex", "_extras/dedications.tex"
|
|
32
36
|
end
|
|
33
37
|
def copy_sample_text
|
|
34
|
-
copy_file "sample.tex"
|
|
38
|
+
copy_file "sample.tex", "text/01_First-Chapter/01-Welcome.tex"
|
|
35
39
|
end
|
|
36
40
|
def create_directories
|
|
37
|
-
empty_directory "
|
|
38
|
-
empty_directory "
|
|
41
|
+
empty_directory "_output"
|
|
42
|
+
empty_directory "_images"
|
|
39
43
|
end
|
|
40
44
|
private
|
|
41
45
|
# Retrieve user's name using finger.
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require 'fileutils'
|
|
1
2
|
module Bookmaker
|
|
2
3
|
module Parser
|
|
3
4
|
class Epub < Base
|
|
@@ -28,11 +29,12 @@ module Bookmaker
|
|
|
28
29
|
epub.cover cover_image
|
|
29
30
|
end
|
|
30
31
|
write_coverpage!
|
|
32
|
+
write_thankspage!
|
|
31
33
|
write_copyright!
|
|
32
34
|
write_sections!
|
|
33
35
|
write_backpage!
|
|
34
36
|
write_toc!
|
|
35
|
-
epub.files cover_page
|
|
37
|
+
epub.files cover_page + thanks_page + sections.map(&:filepath) + back_page + copyright_page + assets
|
|
36
38
|
epub.nav navigation
|
|
37
39
|
|
|
38
40
|
epub.save(epub_path)
|
|
@@ -51,28 +53,46 @@ module Bookmaker
|
|
|
51
53
|
def copyright_page
|
|
52
54
|
Dir[copyright_path]
|
|
53
55
|
end
|
|
56
|
+
def thanks_page
|
|
57
|
+
Dir[thanks_path]
|
|
58
|
+
end
|
|
54
59
|
def write_backpage!
|
|
55
|
-
contents = render_template(root_dir.join("
|
|
60
|
+
contents = render_template(root_dir.join("_templates/epub/back.html"), config)
|
|
56
61
|
File.open(back_path,"w") do |file|
|
|
57
62
|
file << contents
|
|
58
63
|
end
|
|
59
64
|
end
|
|
60
65
|
def write_coverpage!
|
|
61
|
-
contents = render_template(root_dir.join("
|
|
66
|
+
contents = render_template(root_dir.join("_templates/epub/cover.html"), config)
|
|
67
|
+
puts "Writing cover page. #{cover_path}"
|
|
68
|
+
#
|
|
69
|
+
# raise File.dirname(cover_path).inspect
|
|
70
|
+
FileUtils.mkdir_p(File.dirname(cover_path))
|
|
62
71
|
File.open(cover_path,"w") do |file|
|
|
63
72
|
file << contents
|
|
64
73
|
end
|
|
65
74
|
end
|
|
66
75
|
def write_copyright!
|
|
67
|
-
contents = render_template(root_dir.join("
|
|
76
|
+
contents = render_template(root_dir.join("_templates/html/copyright.erb"), config)
|
|
68
77
|
# File.open('help.html','w').write(contents)
|
|
78
|
+
FileUtils.mkdir_p(File.dirname(copyright_path))
|
|
69
79
|
File.open(copyright_path,"w") do |file|
|
|
70
80
|
file << contents
|
|
71
81
|
# puts file
|
|
72
82
|
end
|
|
73
83
|
end
|
|
84
|
+
def write_thankspage!
|
|
85
|
+
contents = render_template(root_dir.join("_templates/html/thanks.erb"), config)
|
|
86
|
+
# File.open('help.html','w').write(contents)
|
|
87
|
+
FileUtils.mkdir_p(File.dirname(thanks_path))
|
|
88
|
+
File.open(thanks_path,"w") do |file|
|
|
89
|
+
file << contents
|
|
90
|
+
# puts file
|
|
91
|
+
end
|
|
92
|
+
end
|
|
74
93
|
def write_toc!
|
|
75
94
|
toc = TOC::Epub.new(navigation)
|
|
95
|
+
FileUtils.mkdir_p(File.dirname(toc_path))
|
|
76
96
|
File.open(toc_path, "w") do |file|
|
|
77
97
|
file << toc.to_html
|
|
78
98
|
end
|
|
@@ -121,7 +141,7 @@ module Bookmaker
|
|
|
121
141
|
end
|
|
122
142
|
def assets
|
|
123
143
|
@assets ||= begin
|
|
124
|
-
assets = Dir[root_dir.join("
|
|
144
|
+
assets = Dir[root_dir.join("_templates/epub/*.css")]
|
|
125
145
|
assets += Dir[root_dir.join("images/**/*.{jpg,png,gif}")]
|
|
126
146
|
assets
|
|
127
147
|
end
|
|
@@ -138,20 +158,23 @@ module Bookmaker
|
|
|
138
158
|
end
|
|
139
159
|
end
|
|
140
160
|
def template_path
|
|
141
|
-
root_dir.join("
|
|
161
|
+
root_dir.join("_templates/epub/page.erb")
|
|
142
162
|
end
|
|
143
163
|
def html_path
|
|
144
|
-
root_dir.join("
|
|
164
|
+
root_dir.join("_output/#{name}.html")
|
|
145
165
|
end
|
|
146
166
|
def epub_path
|
|
147
|
-
root_dir.join("
|
|
167
|
+
root_dir.join("_output/#{name}.epub")
|
|
148
168
|
end
|
|
149
169
|
def tmp_dir
|
|
150
|
-
root_dir.join("
|
|
170
|
+
root_dir.join("_output/tmp")
|
|
151
171
|
end
|
|
152
172
|
def cover_path
|
|
153
173
|
tmp_dir.join("cover.html")
|
|
154
174
|
end
|
|
175
|
+
def thanks_path
|
|
176
|
+
tmp_dir.join("thanks.html")
|
|
177
|
+
end
|
|
155
178
|
def back_path
|
|
156
179
|
tmp_dir.join("back.html")
|
|
157
180
|
end
|
|
@@ -5,7 +5,8 @@ module Bookmaker
|
|
|
5
5
|
def content
|
|
6
6
|
raw = []
|
|
7
7
|
entries.keys.each do |chapter|
|
|
8
|
-
text = "<h2>#{chapter.split(/_/)[1].gsub('-',' ').titleize}</h2>"
|
|
8
|
+
# text = "<h2>#{chapter.split(/_/)[1].gsub('-',' ').titleize}</h2>"
|
|
9
|
+
text = "<h2>Chapter</h2>"
|
|
9
10
|
sections = []
|
|
10
11
|
entries[chapter].each do |section|
|
|
11
12
|
sections << "<p>#{read_content(section)[0].split(/\n{2,}/).map do |s|
|
|
@@ -26,8 +27,8 @@ module Bookmaker
|
|
|
26
27
|
:contents => toc.content,
|
|
27
28
|
:toc => toc.to_html,
|
|
28
29
|
})
|
|
29
|
-
output = render_template(root_dir.join("
|
|
30
|
-
f = File.open(root_dir.join("
|
|
30
|
+
output = render_template(root_dir.join("_templates/html/layout.erb"), locals)
|
|
31
|
+
f = File.open(root_dir.join("_output/#{name}.html"), 'w')
|
|
31
32
|
f.write(output)
|
|
32
33
|
f.close
|
|
33
34
|
true
|
|
@@ -44,20 +45,30 @@ module Bookmaker
|
|
|
44
45
|
text.gsub!(/``(.*?'?)''/) { "“#{$1}”"}
|
|
45
46
|
text.gsub!(/``(.*?'?)"/) { "“#{$1}”"}
|
|
46
47
|
text.gsub!(/``/, "“")
|
|
47
|
-
text.gsub!(/\b'\b/) { "
|
|
48
|
+
text.gsub!(/\b'\b/) { "’" }
|
|
48
49
|
text.gsub!(/`(.*?)'/) { "‘#{$1}’"}
|
|
49
50
|
# \{([^\}]+?)\} Within the curly braces.
|
|
50
51
|
text.gsub!(/\\pf?break\{\}/,"<hr />")
|
|
52
|
+
text.gsub!(/\\pf?break/,"<hr />")
|
|
53
|
+
text.gsub!(/\\%/,'%')
|
|
54
|
+
text.gsub!(/\\`e/,'é')
|
|
55
|
+
text.gsub!(/\\textgreater\{?\}?/, ">")
|
|
56
|
+
text.gsub!(/\\Bophendze/,'Bophendze')
|
|
51
57
|
text.gsub!(/\\ldots\{\}/,"…")
|
|
52
58
|
text.gsub!(/\\Dash\{\}/, "—")
|
|
59
|
+
text.gsub!(/\\Dash/, "—")
|
|
53
60
|
text.gsub!(/\\begin\{quote\}(.*?)\\end\{quote\}/m) { "<blockquote>#{$1.strip}</blockquote>"}
|
|
54
61
|
text.gsub!(/<\/blockquote>\s+?<blockquote>/m, "\n")
|
|
55
62
|
text.gsub!(/\\begin\{([^\}]+?)\}(.*?)\\end\{[^\}]+?\}/m) { "<div class='#{$1.strip}'>#{$2.strip}</div>"}
|
|
56
63
|
text.gsub!(/\\section\{([^\}]+?)\}/m) { "<h3>#{$1.strip}</h3>"}
|
|
57
|
-
['Character','Equipment'].each do |s|
|
|
58
|
-
|
|
59
|
-
text.gsub!(/\\#{s}
|
|
64
|
+
['Character','Equipment','Organization','Index'].each do |s|
|
|
65
|
+
# puts "Working on #{s}"
|
|
66
|
+
# text.gsub!(/\\#{s}{Drazen, Joven}{(Drazen)}/) { "<span class='#{s.downcase}'>#{$1.strip}</span>"}
|
|
67
|
+
text.gsub!(/\\#{s}\{[^\}]+?\}\{([^\}]+?)\}/) { "<span class='#{s.downcase}'>#{$1.strip}</span>"}
|
|
68
|
+
text.gsub!(/\\#{s}\{([^\}]+?)\}/) { ""}
|
|
69
|
+
# text.gsub!(/\\#{s}\{([^\}]+?)\}/) { "<span class='#{s.downcase}'>#{$1.strip}</span>"}
|
|
60
70
|
end
|
|
71
|
+
text.gsub!(/\\footnote\{([^\}]+?)\}/m) { ""}
|
|
61
72
|
text.gsub!(/\\emph\{([^\}]+?)\}/m) { "<em>#{$1.strip}</em>"}
|
|
62
73
|
text.gsub!(/\\thought\{([^\}]+?)\}/m) { "<em>#{$1.strip}</em>"}
|
|
63
74
|
text.gsub!(/\\(.*?)\{([^\}]+?)\}/) { "<span class='#{$1.downcase}'>#{$2.strip}</span>"}
|
|
@@ -65,7 +76,6 @@ module Bookmaker
|
|
|
65
76
|
text.gsub!(/<\/span>\{[^\}]+?}/, "</span>")
|
|
66
77
|
text.gsub!(/<p><h([1-6])>(.*?)<\/h[1-6]><\/p>/) { "<h#{$1}>#{$2.strip}</h#{$1}>"}
|
|
67
78
|
text.gsub!(/(\S+)~(\S+)/) { "#{$1} #{$2}"}
|
|
68
|
-
# text.gsub!(/> +/, ">")
|
|
69
79
|
output << text
|
|
70
80
|
end
|
|
71
81
|
output.gsub!(/\n\n+/, "\n\n")
|
|
@@ -97,7 +107,7 @@ module Bookmaker
|
|
|
97
107
|
# def parse
|
|
98
108
|
# reset_footnote_index!
|
|
99
109
|
#
|
|
100
|
-
# # File.open(root_dir.join("
|
|
110
|
+
# # File.open(root_dir.join("_output/#{name}.html"), "w") do |file|
|
|
101
111
|
# # file << parse_layout(content)
|
|
102
112
|
# # end
|
|
103
113
|
# true
|
|
@@ -211,7 +221,7 @@ module Bookmaker
|
|
|
211
221
|
# :toc => toc.to_html,
|
|
212
222
|
# :changelog => render_changelog
|
|
213
223
|
# })
|
|
214
|
-
# render_template(root_dir.join("
|
|
224
|
+
# render_template(root_dir.join("_templates/html/layout.erb"), locals)
|
|
215
225
|
# end
|
|
216
226
|
#
|
|
217
227
|
# # Render changelog file.
|
data/lib/bookmaker/parser/pdf.rb
CHANGED
|
@@ -7,6 +7,7 @@ module Bookmaker
|
|
|
7
7
|
raw = []
|
|
8
8
|
entries.keys.each do |chapter|
|
|
9
9
|
title = (chapter.empty?) ? "Untitled" : chapter.split('_')[1]
|
|
10
|
+
title = 'Untitled' if title.nil?
|
|
10
11
|
raw << "\\Chapter{#{title.gsub('-',' ')}}\n\n"
|
|
11
12
|
entries[chapter].each do |section|
|
|
12
13
|
s = read_content(section)[0]
|
|
@@ -46,7 +47,7 @@ module Bookmaker
|
|
|
46
47
|
text.gsub!('* * *', "\n\n\\pbreak{}\n\n")
|
|
47
48
|
end
|
|
48
49
|
def tex_file
|
|
49
|
-
root_dir.join("
|
|
50
|
+
root_dir.join("_output/#{name}.tex")
|
|
50
51
|
end
|
|
51
52
|
end
|
|
52
53
|
end
|
data/lib/bookmaker/stats.rb
CHANGED
|
@@ -1,45 +1,114 @@
|
|
|
1
|
+
class Fixnum
|
|
2
|
+
def day
|
|
3
|
+
self * (60 * 60 * 24) # seconds * hours * minutes
|
|
4
|
+
end
|
|
5
|
+
def ago
|
|
6
|
+
Time.now - self
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
require 'json'
|
|
1
10
|
module Bookmaker
|
|
2
11
|
class Stats
|
|
3
12
|
attr_reader :root_dir
|
|
4
13
|
|
|
5
14
|
def initialize(root_dir)
|
|
6
15
|
@root_dir = root_dir
|
|
16
|
+
@files = Dir["#{root_dir}/text/**/[0-9]*.tex"]
|
|
17
|
+
@words = 0
|
|
18
|
+
@progress = (File.exist?(log)) ? JSON.parse(File.open(log,'r').read).clone : {}
|
|
7
19
|
end
|
|
8
20
|
|
|
9
|
-
def
|
|
10
|
-
|
|
21
|
+
def log
|
|
22
|
+
"#{root_dir}/.wordcount"
|
|
11
23
|
end
|
|
12
24
|
|
|
13
|
-
def
|
|
14
|
-
@
|
|
25
|
+
def target
|
|
26
|
+
Bookmaker.config(@root_dir)['wordcount']
|
|
15
27
|
end
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
@words ||= text.split(" ").size
|
|
28
|
+
def now
|
|
29
|
+
Date.today.to_s
|
|
19
30
|
end
|
|
31
|
+
def words
|
|
32
|
+
if @words == 0
|
|
33
|
+
most_recent = @files.max_by {|f| File.mtime(f)}
|
|
34
|
+
if !@progress[now].nil? and File.mtime(log) > File.mtime(most_recent)
|
|
35
|
+
@progress[now]
|
|
36
|
+
else
|
|
37
|
+
detex = "/usr/texbin/detex"
|
|
20
38
|
|
|
21
|
-
|
|
22
|
-
|
|
39
|
+
file = Tempfile.new('foo.tex')
|
|
40
|
+
file.write(text)
|
|
41
|
+
file.close
|
|
42
|
+
@progress[now] = `detex #{file.path}| wc -w`.to_i
|
|
43
|
+
file.unlink
|
|
44
|
+
# Do previous day's progress...if nil.
|
|
45
|
+
@progress[Date.yesterday.to_s] = @progress[now] if @progress.keys.count == 1
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
if (lasttime != Date.yesterday.to_s)
|
|
49
|
+
# Update the record.
|
|
50
|
+
n = lasttime
|
|
51
|
+
w = @progress[lasttime]
|
|
52
|
+
n.upto(Date.yesterday.to_s) do |k|
|
|
53
|
+
# puts "Upto #{k}: @progress[#{k}] = #{w}"
|
|
54
|
+
@progress[k] = w
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
File.open(log,'w').write( JSON.generate(@progress) )
|
|
58
|
+
@words = @progress[now]
|
|
23
59
|
end
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
@
|
|
60
|
+
def lasttime
|
|
61
|
+
p = nil
|
|
62
|
+
@progress.keys.sort.each do |k|
|
|
63
|
+
break if k == now
|
|
64
|
+
p = k
|
|
65
|
+
end
|
|
66
|
+
p
|
|
27
67
|
end
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
@footnotes ||= html.css("p.footnote").size
|
|
68
|
+
def yesterday
|
|
69
|
+
@progress[lasttime]
|
|
31
70
|
end
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
@links ||= html.css("[href^='http']").size
|
|
71
|
+
def today
|
|
72
|
+
@words - @progress[lasttime]
|
|
35
73
|
end
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
@
|
|
74
|
+
def text
|
|
75
|
+
@text = nil
|
|
76
|
+
@text = @files.map{|f| File.open(f,'r').read}.join("\n\n\n") if @text.nil?
|
|
39
77
|
end
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
@content ||= Parser::HTML.new(root_dir).content
|
|
78
|
+
def remaining
|
|
79
|
+
target - words
|
|
43
80
|
end
|
|
81
|
+
|
|
82
|
+
# def html
|
|
83
|
+
# @html ||= Nokogiri::HTML(content)
|
|
84
|
+
# end
|
|
85
|
+
|
|
86
|
+
# def words
|
|
87
|
+
# @words ||= text.split(" ").size
|
|
88
|
+
# end
|
|
89
|
+
|
|
90
|
+
# def chapters
|
|
91
|
+
# @chapters ||= html.css(".chapter").size
|
|
92
|
+
# end
|
|
93
|
+
|
|
94
|
+
# def images
|
|
95
|
+
# @images ||= html.css("img").size
|
|
96
|
+
# end
|
|
97
|
+
|
|
98
|
+
# def footnotes
|
|
99
|
+
# @footnotes ||= html.css("p.footnote").size
|
|
100
|
+
# end
|
|
101
|
+
|
|
102
|
+
# def links
|
|
103
|
+
# @links ||= html.css("[href^='http']").size
|
|
104
|
+
# end
|
|
105
|
+
|
|
106
|
+
# def code_blocks
|
|
107
|
+
# @code_blocks ||= html.css("pre").size
|
|
108
|
+
# end
|
|
109
|
+
|
|
110
|
+
# def content
|
|
111
|
+
# @content ||= Parser::HTML.new(root_dir).content
|
|
112
|
+
# end
|
|
44
113
|
end
|
|
45
114
|
end
|