burr 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/.ruby-version +1 -0
- data/Gemfile +3 -0
- data/LICENSE.md +30 -0
- data/README.md +180 -0
- data/Rakefile +118 -0
- data/bin/burr +9 -0
- data/burr.gemspec +36 -0
- data/generators/Gemfile.txt +3 -0
- data/generators/config.yml +55 -0
- data/generators/contents/chapter1.md +7 -0
- data/generators/contents/chapter2.md +7 -0
- data/generators/stylesheets/pdf.css +569 -0
- data/generators/stylesheets/site.css +1 -0
- data/lib/burr.rb +56 -0
- data/lib/burr/book.rb +289 -0
- data/lib/burr/cli.rb +64 -0
- data/lib/burr/converter.rb +19 -0
- data/lib/burr/core_ext/blank.rb +107 -0
- data/lib/burr/dependency.rb +28 -0
- data/lib/burr/eeepub_ext/maker.rb +131 -0
- data/lib/burr/exporter.rb +137 -0
- data/lib/burr/exporters/epub.rb +163 -0
- data/lib/burr/exporters/pdf.rb +95 -0
- data/lib/burr/exporters/site.rb +101 -0
- data/lib/burr/generator.rb +41 -0
- data/lib/burr/kramdown_ext/converter.rb +145 -0
- data/lib/burr/kramdown_ext/options.rb +38 -0
- data/lib/burr/kramdown_ext/parser.rb +65 -0
- data/lib/burr/liquid_ext/block.rb +58 -0
- data/lib/burr/liquid_ext/extends.rb +114 -0
- data/lib/burr/plugin.rb +70 -0
- data/lib/burr/plugins/aside.rb +44 -0
- data/lib/burr/plugins/codeblock.rb +42 -0
- data/lib/burr/plugins/figure.rb +62 -0
- data/lib/burr/plugins/link.rb +47 -0
- data/lib/burr/plugins/parser_plugin.rb +18 -0
- data/lib/burr/plugins/table.rb +42 -0
- data/lib/burr/plugins/toc.rb +105 -0
- data/lib/burr/ruby_version_check.rb +4 -0
- data/lib/burr/server.rb +27 -0
- data/lib/burr/ui.rb +46 -0
- data/lib/burr/version.rb +8 -0
- data/resources/locales/labels/en.yml +45 -0
- data/resources/locales/labels/zh_CN.yml +46 -0
- data/resources/locales/titles/en.yml +21 -0
- data/resources/locales/titles/zh_CN.yml +21 -0
- data/resources/templates/epub/_layout.liquid +17 -0
- data/resources/templates/epub/acknowledgement.liquid +10 -0
- data/resources/templates/epub/afterword.liquid +10 -0
- data/resources/templates/epub/appendix.liquid +10 -0
- data/resources/templates/epub/author.liquid +10 -0
- data/resources/templates/epub/chapter.liquid +10 -0
- data/resources/templates/epub/conclusion.liquid +10 -0
- data/resources/templates/epub/cover.liquid +9 -0
- data/resources/templates/epub/dedication.liquid +10 -0
- data/resources/templates/epub/edition.liquid +1 -0
- data/resources/templates/epub/epilogue.liquid +1 -0
- data/resources/templates/epub/foreword.liquid +10 -0
- data/resources/templates/epub/glossary.liquid +1 -0
- data/resources/templates/epub/introduction.liquid +1 -0
- data/resources/templates/epub/license.liquid +1 -0
- data/resources/templates/epub/lof.liquid +24 -0
- data/resources/templates/epub/lot.liquid +24 -0
- data/resources/templates/epub/part.liquid +4 -0
- data/resources/templates/epub/preface.liquid +10 -0
- data/resources/templates/epub/prologue.liquid +1 -0
- data/resources/templates/epub/table.liquid +7 -0
- data/resources/templates/epub/title.liquid +3 -0
- data/resources/templates/epub/toc.liquid +10 -0
- data/resources/templates/pdf/_item.liquid +6 -0
- data/resources/templates/pdf/acknowledgement.liquid +1 -0
- data/resources/templates/pdf/afterword.liquid +1 -0
- data/resources/templates/pdf/appendix.liquid +4 -0
- data/resources/templates/pdf/author.liquid +1 -0
- data/resources/templates/pdf/blank.liquid +3 -0
- data/resources/templates/pdf/book.liquid +42 -0
- data/resources/templates/pdf/chapter.liquid +4 -0
- data/resources/templates/pdf/code.liquid +3 -0
- data/resources/templates/pdf/conclusion.liquid +1 -0
- data/resources/templates/pdf/cover.liquid +6 -0
- data/resources/templates/pdf/dedication.liquid +3 -0
- data/resources/templates/pdf/edition.liquid +1 -0
- data/resources/templates/pdf/epilogue.liquid +1 -0
- data/resources/templates/pdf/foreword.liquid +1 -0
- data/resources/templates/pdf/glossary.liquid +1 -0
- data/resources/templates/pdf/introduction.liquid +1 -0
- data/resources/templates/pdf/license.liquid +1 -0
- data/resources/templates/pdf/lof.liquid +24 -0
- data/resources/templates/pdf/lot.liquid +24 -0
- data/resources/templates/pdf/part.liquid +4 -0
- data/resources/templates/pdf/preface.liquid +1 -0
- data/resources/templates/pdf/prologue.liquid +1 -0
- data/resources/templates/pdf/table.liquid +7 -0
- data/resources/templates/pdf/title.liquid +3 -0
- data/resources/templates/pdf/toc.liquid +4 -0
- data/resources/templates/site/_layout.liquid +27 -0
- data/resources/templates/site/author.liquid +13 -0
- data/resources/templates/site/chapter.liquid +13 -0
- data/resources/templates/site/foreword.liquid +13 -0
- data/resources/templates/site/preface.liquid +13 -0
- metadata +232 -0
@@ -0,0 +1,42 @@
|
|
1
|
+
module Burr
|
2
|
+
class TablePlugin < Plugin
|
3
|
+
|
4
|
+
# Do something after parsed the item content.
|
5
|
+
def after_parse
|
6
|
+
add_label
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
# Adds label and id to table block.
|
12
|
+
#
|
13
|
+
def add_label
|
14
|
+
item = self.book.current_item
|
15
|
+
return unless self.book.config['formats']["#{self.book.format}"]['label']['elements'].include?('table')
|
16
|
+
|
17
|
+
counter = 1
|
18
|
+
number = if item['number']
|
19
|
+
item['number']
|
20
|
+
else
|
21
|
+
item['element']
|
22
|
+
end
|
23
|
+
|
24
|
+
dom = ::Nokogiri::HTML::DocumentFragment.parse(item['content'])
|
25
|
+
dom.css('.table.has-caption').each do |table|
|
26
|
+
# add id
|
27
|
+
table.set_attribute('id', "table-#{number}-#{counter}")
|
28
|
+
|
29
|
+
# add label
|
30
|
+
caption = table.css('.caption').first
|
31
|
+
label = self.book.render_label('table', { 'item' => { 'number' => number, 'counter' => counter } })
|
32
|
+
caption_html = "<span>#{label}</span>#{caption.inner_html}"
|
33
|
+
caption.children = ::Nokogiri::HTML.fragment(caption_html, 'utf-8')
|
34
|
+
|
35
|
+
counter += 1
|
36
|
+
end
|
37
|
+
|
38
|
+
item['content'] = dom.to_xhtml
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module Burr
|
2
|
+
class TocPlugin < Plugin
|
3
|
+
|
4
|
+
def after_parse
|
5
|
+
parse_toc
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def parse_toc
|
11
|
+
item = self.book.current_item
|
12
|
+
|
13
|
+
if item['toc'].size > 0
|
14
|
+
# strip title from the parsed content
|
15
|
+
#
|
16
|
+
first_heading = item['toc'].first
|
17
|
+
# only <h1> headings can be the title of the content
|
18
|
+
if first_heading['level'] == 1
|
19
|
+
# the <h1> heading must be the first line to consider it a title
|
20
|
+
item['content'].sub!(/^<h1.*<\/h1>\n+(.*)/, '\1')
|
21
|
+
item['title'] = "#{first_heading['title']}"
|
22
|
+
end
|
23
|
+
|
24
|
+
item['id'] = "#{item['element']}"
|
25
|
+
item['id'] << "-#{item['number']}" unless item['number'].blank?
|
26
|
+
|
27
|
+
# add labels
|
28
|
+
#
|
29
|
+
current_format_labels = self.book.config['formats']["#{self.book.format}"]['label']['elements']
|
30
|
+
current_format_labels = [] if current_format_labels.nil?
|
31
|
+
counters = [
|
32
|
+
item['number'],
|
33
|
+
0,
|
34
|
+
0,
|
35
|
+
0,
|
36
|
+
0,
|
37
|
+
0
|
38
|
+
]
|
39
|
+
|
40
|
+
parsed_toc = []
|
41
|
+
|
42
|
+
item['toc'].each do |t|
|
43
|
+
level = t['level']
|
44
|
+
title = t['title']
|
45
|
+
|
46
|
+
counters[level-1] += 1 if level > 1
|
47
|
+
# Reset the counters for the higher heading levels
|
48
|
+
(level..5).each { |x| counters[x] = 0 }
|
49
|
+
sliced_counters = counters[0..(level-1)]
|
50
|
+
|
51
|
+
parameters = {
|
52
|
+
'level' => level,
|
53
|
+
'number' => item['number'],
|
54
|
+
'element' => item['element'],
|
55
|
+
'counters' => sliced_counters
|
56
|
+
}
|
57
|
+
|
58
|
+
# format config allows labels for this element type (`labels' option)
|
59
|
+
if current_format_labels.include?(item['element']) && level <= self.book.config['formats']["#{self.book.format}"]['label']['deep']
|
60
|
+
label = self.book.render_label(item['element'], { 'item' => parameters })
|
61
|
+
else
|
62
|
+
label = ''
|
63
|
+
end
|
64
|
+
|
65
|
+
id = self.book.render_id({ 'item' => parameters })
|
66
|
+
|
67
|
+
parsed_toc << {
|
68
|
+
'id' => id,
|
69
|
+
'level' => level,
|
70
|
+
'title' => title,
|
71
|
+
'label' => label
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
item['toc'] = parsed_toc
|
76
|
+
|
77
|
+
item['label'] = item['toc'][0]['label']
|
78
|
+
|
79
|
+
# add labels to content
|
80
|
+
#
|
81
|
+
item['toc'].each do |tt|
|
82
|
+
# the parsed title can be different from the toc entry title
|
83
|
+
# that's the case for the titles with markup code inside (* ` ** etc.)
|
84
|
+
# thus, the replacement must be done based on a fuzzy title that
|
85
|
+
# doesn't include the title text
|
86
|
+
fuzzy_title = Regexp.new("<h#{tt['level']}>#{tt['title']}</h#{tt['level']}>")
|
87
|
+
labeled_title = sprintf("<h%s id='%s'><span>%s</span>%s</h%s>\n",
|
88
|
+
tt['level'],
|
89
|
+
tt['id'],
|
90
|
+
tt['label'],
|
91
|
+
'' != tt['label'] ? " #{tt['title']}" : tt['title'],
|
92
|
+
tt['level']
|
93
|
+
)
|
94
|
+
item['content'].sub!(fuzzy_title, labeled_title)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# ensure that the item has a title (using the default title if necessary)
|
99
|
+
item['title'] = self.book.titles[item['element']] if item['title'].blank?
|
100
|
+
|
101
|
+
nil
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
data/lib/burr/server.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'webrick'
|
2
|
+
|
3
|
+
module Burr
|
4
|
+
module Server
|
5
|
+
|
6
|
+
include WEBrick
|
7
|
+
|
8
|
+
def self.start!
|
9
|
+
destination = File.join(Dir.pwd, '/outputs/site')
|
10
|
+
|
11
|
+
# recreate NondisclosureName under utf-8 circumstance
|
12
|
+
fh_option = WEBrick::Config::FileHandler
|
13
|
+
fh_option[:NondisclosureName] = ['.ht*','~*']
|
14
|
+
|
15
|
+
s = HTTPServer.new(
|
16
|
+
:Port => 8000,
|
17
|
+
:BindAddress => '0.0.0.0',
|
18
|
+
)
|
19
|
+
|
20
|
+
s.mount('/', HTTPServlet::FileHandler, destination, fh_option)
|
21
|
+
t = Thread.new { s.start }
|
22
|
+
trap("INT") { s.shutdown }
|
23
|
+
t.join()
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
data/lib/burr/ui.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# Much of these code stole from bundler.
|
2
|
+
|
3
|
+
module Burr
|
4
|
+
class UI
|
5
|
+
|
6
|
+
attr_accessor :shell
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
Thor::Base.shell = Thor::Shell::Basic if !STDOUT.tty?
|
10
|
+
@shell = Thor::Base.shell.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def info(msg, newline = nil)
|
14
|
+
tell_me(msg, nil, newline)
|
15
|
+
end
|
16
|
+
|
17
|
+
def confirm(msg, newline = nil)
|
18
|
+
tell_me(msg, :green, newline)
|
19
|
+
end
|
20
|
+
|
21
|
+
def warn(msg, newline = nil)
|
22
|
+
tell_me(msg, :yellow, newline)
|
23
|
+
end
|
24
|
+
|
25
|
+
def error(msg, newline = nil)
|
26
|
+
tell_me(msg, :red, newline)
|
27
|
+
end
|
28
|
+
|
29
|
+
def debug(msg, newline = nil)
|
30
|
+
tell_me(msg, nil, newline) if debug?
|
31
|
+
end
|
32
|
+
|
33
|
+
def trace(e, newline = nil)
|
34
|
+
msg = ["#{e.class}: #{e.message}", *e.backtrace].join("\n")
|
35
|
+
tell_me(msg, nil, newline)
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
# valimism
|
41
|
+
def tell_me(msg, color = nil, newline = nil)
|
42
|
+
newline.nil? ? @shell.say(msg, color) : @shell.say(msg, color, newline)
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
data/lib/burr/version.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
id:
|
2
|
+
- '{{ item.element }}-{{ item.number }}'
|
3
|
+
- 'section-{{ item.counters | join:"-" }}' # section-1-1
|
4
|
+
|
5
|
+
appendix:
|
6
|
+
- 'Appendix {{ item.number }}'
|
7
|
+
- '{{ item.counters | join:"." }}' # A.1
|
8
|
+
|
9
|
+
chapter:
|
10
|
+
- 'Chapter {{ item.number }}'
|
11
|
+
- '{{ item.counters | join:"." }}' # 1.1
|
12
|
+
|
13
|
+
part: 'Part {{ item.number }}'
|
14
|
+
figure: 'Figure {{ element.number }}.{{ item.number }}'
|
15
|
+
table: 'Table {{ element.number }}.{{ item.number }}'
|
16
|
+
codeblock: 'Sample {{ item.number }}.{{ item.counter }}'
|
17
|
+
|
18
|
+
acknowledgement: ''
|
19
|
+
afterword: ''
|
20
|
+
author: ''
|
21
|
+
conclusion: ''
|
22
|
+
cover: ''
|
23
|
+
dedication: ''
|
24
|
+
edition: ''
|
25
|
+
epilogue: ''
|
26
|
+
foreword: ''
|
27
|
+
glossary: ''
|
28
|
+
introduction: ''
|
29
|
+
preface: ''
|
30
|
+
prologue: ''
|
31
|
+
title: ''
|
32
|
+
toc: ''
|
33
|
+
|
34
|
+
# Navigation elements
|
35
|
+
index: 'Index'
|
36
|
+
next: 'Next'
|
37
|
+
previous: 'Previous'
|
38
|
+
|
39
|
+
# Special
|
40
|
+
date_format: 'm/d/Y'
|
41
|
+
datetime_format: 'm/d/Y H:i'
|
42
|
+
|
43
|
+
# Other
|
44
|
+
by: 'by'
|
45
|
+
page: 'page'
|
@@ -0,0 +1,46 @@
|
|
1
|
+
id:
|
2
|
+
- '{{ item.element }}-{{ item.number }}'
|
3
|
+
- 'section-{{ item.counters | join:"-" }}' # section-1-1
|
4
|
+
|
5
|
+
appendix:
|
6
|
+
- '附录 {{ item.number }}'
|
7
|
+
- '{{ item.counters | join:"." }}' # A.1
|
8
|
+
|
9
|
+
chapter:
|
10
|
+
- '第 {{ item.number }} 章'
|
11
|
+
- '{{ item.counters | join:"." }}' # 1.1
|
12
|
+
|
13
|
+
part: '第 {{ item.number }} 部分:'
|
14
|
+
figure: '图 {{ item.number }}.{{ item.counter }}:'
|
15
|
+
table: '表格 {{ item.number }}.{{ item.counter }}:'
|
16
|
+
codeblock: '代码 {{ item.number }}.{{ item.counter }}:'
|
17
|
+
aside: '旁注 {{ item.number }}.{{ item.counter }}:'
|
18
|
+
|
19
|
+
acknowledgement: ''
|
20
|
+
afterword: ''
|
21
|
+
author: ''
|
22
|
+
conclusion: ''
|
23
|
+
cover: ''
|
24
|
+
dedication: ''
|
25
|
+
edition: ''
|
26
|
+
epilogue: ''
|
27
|
+
foreword: ''
|
28
|
+
glossary: ''
|
29
|
+
introduction: ''
|
30
|
+
preface: ''
|
31
|
+
prologue: ''
|
32
|
+
title: ''
|
33
|
+
toc: ''
|
34
|
+
|
35
|
+
# Navigation elements
|
36
|
+
index: '索引'
|
37
|
+
next: '下一页'
|
38
|
+
previous: '上一页'
|
39
|
+
|
40
|
+
# Special
|
41
|
+
date_format: 'm/d/Y'
|
42
|
+
datetime_format: 'm/d/Y H:i'
|
43
|
+
|
44
|
+
# Other
|
45
|
+
by: 'by'
|
46
|
+
page: 'page'
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# English translations of default titles
|
2
|
+
|
3
|
+
acknowledgement: 'Acknowledgements'
|
4
|
+
afterword: 'Afterword'
|
5
|
+
author: 'About the author'
|
6
|
+
blank: 'This Page Intentionally Left Blank'
|
7
|
+
conclusion: 'Conclusion'
|
8
|
+
cover: 'Cover'
|
9
|
+
dedication: 'Dedication'
|
10
|
+
edition: 'About this edition'
|
11
|
+
epilogue: 'Epilogue'
|
12
|
+
foreword: 'Foreword'
|
13
|
+
glossary: 'Glossary'
|
14
|
+
introduction: 'Introduction'
|
15
|
+
license: 'License'
|
16
|
+
lof: 'List of Figures'
|
17
|
+
lot: 'List of Tables'
|
18
|
+
preface: 'Preface'
|
19
|
+
prologue: 'Prologue'
|
20
|
+
title: 'Title'
|
21
|
+
toc: 'Table of contents'
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Simplified Chinese translations of default titles
|
2
|
+
|
3
|
+
acknowledgement: '致谢'
|
4
|
+
afterword: '后记'
|
5
|
+
author: '作者简介'
|
6
|
+
blank: '此页留白'
|
7
|
+
conclusion: '总论'
|
8
|
+
cover: '封面'
|
9
|
+
dedication: 'Dedication'
|
10
|
+
edition: 'About this edition'
|
11
|
+
epilogue: 'Epilogue'
|
12
|
+
foreword: '续'
|
13
|
+
glossary: '词汇表'
|
14
|
+
introduction: 'Introduction'
|
15
|
+
license: 'License'
|
16
|
+
lof: 'List of Figures'
|
17
|
+
lot: 'List of Tables'
|
18
|
+
preface: '前言'
|
19
|
+
prologue: 'Prologue'
|
20
|
+
title: 'Title'
|
21
|
+
toc: '目录'
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" ?>
|
2
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
3
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" xml:lang="en">
|
4
|
+
<head>
|
5
|
+
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
|
6
|
+
<meta name="author" content="{% if config.translator %}{{ config.translator }}{% else %}{{ config.author }}{% endif %}" />
|
7
|
+
<meta name="date" content="{{ config.publication_date }}"/>
|
8
|
+
<title>{% block title %}{% endblock %}</title>
|
9
|
+
<link type="text/css" rel="stylesheet" href="style.css" />
|
10
|
+
</head>
|
11
|
+
|
12
|
+
<body>
|
13
|
+
<div class="container">
|
14
|
+
{% block body %}{% endblock %}
|
15
|
+
</div>
|
16
|
+
</body>
|
17
|
+
</html>
|