cheepub 0.1.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.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.travis.yml +11 -0
- data/Gemfile +6 -0
- data/LICENSE +21 -0
- data/README.md +37 -0
- data/Rakefile +16 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/cheepub.gemspec +32 -0
- data/doc/README_ja.md +110 -0
- data/exe/cheepub +6 -0
- data/lib/cheepub.rb +13 -0
- data/lib/cheepub/cli.rb +23 -0
- data/lib/cheepub/content.rb +49 -0
- data/lib/cheepub/error.rb +4 -0
- data/lib/cheepub/ext_hash.rb +15 -0
- data/lib/cheepub/generator.rb +69 -0
- data/lib/cheepub/markdown.rb +35 -0
- data/lib/cheepub/markdown/cheemarkdown.rb +64 -0
- data/lib/cheepub/templates/bodymatter.html.erb +12 -0
- data/lib/cheepub/templates/style.css.erb +143 -0
- data/lib/cheepub/version.rb +3 -0
- metadata +192 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 48f7b932a8c34bbfcdc9ab5729bc1fd2f361230f915f4728126e3aee7985fb55
|
4
|
+
data.tar.gz: 56b9172d5f6920b0bfa8153cbdd9d7ee7a5d1b0639340da9b70259a4ea568124
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ed20b41c81fb991248dbe1ec532c738bbc264d13243837b81a9bdfb633e963667952681290c0c432fbf5b378fa326c8fa923bd2bbcde154ce56a93bdb75f453a
|
7
|
+
data.tar.gz: 01b5f2cf9d51e45a47fc8eeb40c8acfe0191d7ac03dfff0c3308e568f0c4d79338cff1da964cacac1a0cab28e3ca49d52ffeda1f534da1fd0f6623ca6a376c48
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2018 Masayoshi Takahashi
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# Cheepub
|
2
|
+
|
3
|
+
Cheepub is EPUB generator from Markdown.
|
4
|
+
|
5
|
+
Cheepub uses [Kramdown](https://github.com/gettalong/kramdown) and [Gepub](https://github.com/skoji/gepub).
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'cheepub'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install cheepub
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
```sh
|
26
|
+
$ cheepub source.md
|
27
|
+
```
|
28
|
+
|
29
|
+
## Development
|
30
|
+
|
31
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
32
|
+
|
33
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
34
|
+
|
35
|
+
## Contributing
|
36
|
+
|
37
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/takahashim/cheepub.
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rake/testtask"
|
3
|
+
require 'rake/clean'
|
4
|
+
|
5
|
+
Rake::TestTask.new(:test) do |t|
|
6
|
+
t.libs << "test"
|
7
|
+
t.libs << "lib"
|
8
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
9
|
+
end
|
10
|
+
|
11
|
+
task :default => [:test, :rufo]
|
12
|
+
|
13
|
+
desc "Run rufo"
|
14
|
+
task :rufo do
|
15
|
+
ruby "-S rufo **/*.rb"
|
16
|
+
end
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "cheepub"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/cheepub.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require "cheepub/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "cheepub"
|
7
|
+
spec.version = Cheepub::VERSION
|
8
|
+
spec.authors = ["takahashim"]
|
9
|
+
spec.email = ["maki@rubycolor.org"]
|
10
|
+
|
11
|
+
spec.summary = "Simple EPUB generator from Markdown"
|
12
|
+
spec.description = %q{Simple EPUB generator from Markdown. Inspired by denden converter}
|
13
|
+
spec.homepage = "https://github.com/takahashim/cheepub"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
16
|
+
f.match(%r{^(test|spec|features)/})
|
17
|
+
end
|
18
|
+
spec.bindir = "exe"
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_dependency "gepub"
|
23
|
+
spec.add_dependency "kramdown", "~> 1.16"
|
24
|
+
spec.add_dependency "clamp", "~> 1.2"
|
25
|
+
|
26
|
+
spec.add_development_dependency "rufo", "~> 0.3"
|
27
|
+
spec.add_development_dependency "bundler", "~> 1.16"
|
28
|
+
spec.add_development_dependency "rake", "~> 12.0"
|
29
|
+
spec.add_development_dependency "test-unit", "~> 3.2"
|
30
|
+
spec.add_development_dependency "test-unit-notify"
|
31
|
+
spec.add_development_dependency "terminal-notifier"
|
32
|
+
end
|
data/doc/README_ja.md
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
---
|
2
|
+
title: Ceepub説明書
|
3
|
+
author: @takahashim
|
4
|
+
---
|
5
|
+
|
6
|
+
# Cheepubとは
|
7
|
+
|
8
|
+
Cheepubは、Markdownで書かれた文書を一発でEPUB3に変換するためのツールです。
|
9
|
+
基本的にはコマンドラインツール(CLI)ですが、ライブラリとしても使える……といいですね……。
|
10
|
+
|
11
|
+
## インストール
|
12
|
+
|
13
|
+
CheepubはRubyのgemとして実装されているので、gemコマンドでインストールします。対応しているRubyのバージョンは2.5.xですが、2.3くらいでも動きそうな気がします。
|
14
|
+
|
15
|
+
```console
|
16
|
+
gem install cheepub
|
17
|
+
```
|
18
|
+
|
19
|
+
[kramdown](https://kramdown.gettalong.org/)や[gepub](https://github.com/skoji/gepub)などのライブラリを使用していますが、どっちもpure Rubyのはずなのでそれほど環境依存などはないはず。
|
20
|
+
refinementsを使ってみたのでRuby 1.9とかでは動きません。もう2018年ですし、もう少し新し目のRubyをインストールして欲しいところです(2018年5月現在、2.1系以前のRubyは公式メンテナンスが終了しています。2.2系もそろそろ終わることになりそうです)。
|
21
|
+
|
22
|
+
## 使い方
|
23
|
+
|
24
|
+
Cheepubはコマンドラインで使うことを想定しています。
|
25
|
+
|
26
|
+
1. Markdownで文書をもりもり書く、あるいはMarkdownで書かれた文書を持ってくる
|
27
|
+
2. 必要に応じてメタデータと章分割の記述を追加する
|
28
|
+
3. 以下のようにcheepubコマンドを叩くと、EPUBファイルが生成される
|
29
|
+
|
30
|
+
```console
|
31
|
+
$ cheepub sample.md
|
32
|
+
```
|
33
|
+
|
34
|
+
## CheepubのMarkdownについて
|
35
|
+
|
36
|
+
基本方針は3つです。
|
37
|
+
|
38
|
+
* 「(コマンドラインで使える)[でんでんマークダウン](https://conv.denshochan.com/markdown)みたいなやつ」が目標
|
39
|
+
* 「簡単にEPUBが作りたい」(ただしコマンドラインで)という人向けツールです
|
40
|
+
* あまり頑張らない
|
41
|
+
* 「でんでんマークダウン完全互換」とかは大変そうなので、簡単に実装できる範囲でやる
|
42
|
+
* kramdownをベースにするので、でんでんマークダウンになくてもkramdownにある記法等は動くことはあるかも
|
43
|
+
* CLIでの使いやすさを重視
|
44
|
+
* ブラウザでぽちぽち指定するのはめんどくさい(ユーザとしても実装者としても)
|
45
|
+
* なので、Jekyllのfront-matter的なものを導入しました。1ファイルで設定コミで完結しているのがポイントです
|
46
|
+
|
47
|
+
作者としてはろすさんリスペクトなので、でんでんマークダウンがそのまま使いたい! という人は素直にでんでんコンバーターを使うことを強くおすすめします。
|
48
|
+
でんでんマークダウンとの互換性を高めるPull Requestをいただいても「ここまで頑張るのはちょっと…」という場合にはrejectさせていただくかもしれません。ご了承下さい。
|
49
|
+
|
50
|
+
### 改ページ(ファイル分割)
|
51
|
+
|
52
|
+
[でんでんマークダウン由来](https://conv.denshochan.com/markdown#docbreak)です。「半角のイコール記号「=」が3つ以上で構成される行があると、その前後でHTMLファイルを分割します。」というやつです。前後の空行を忘れないようにしてください。
|
53
|
+
|
54
|
+
|
55
|
+
### 縦中横
|
56
|
+
|
57
|
+
これも[でんでんマークダウン由来](https://conv.denshochan.com/markdown#tcy)です。`平成^30^年`みたいに書くと、縦書きでも「30」が横に並びます。
|
58
|
+
ただし、縦中横が使える文字はいわゆるASCIIの文字(のうち`^`以外)に限定しています。この限定はなくてもよかったかもしれません。
|
59
|
+
|
60
|
+
### 脚注
|
61
|
+
|
62
|
+
これはでんでんマークダウンというよりは[kramdownの機能](https://kramdown.gettalong.org/syntax.html#footnotes)をそのまま使っています。
|
63
|
+
|
64
|
+
### ルビ
|
65
|
+
|
66
|
+
これは[でんでんマークダウンのルビ](https://conv.denshochan.com/markdown#tcy)の縮小版です。グループルビだけ対応しています。
|
67
|
+
|
68
|
+
### パラグラフへのclass属性の指定
|
69
|
+
|
70
|
+
これは[kramdownの拡張機能](https://kramdown.gettalong.org/syntax.html)で、`{: .foo}`のような行を追加すると`<p>...</p>`要素にclass属性を追加できます。
|
71
|
+
|
72
|
+
## Cheepubのfront-matterについて
|
73
|
+
|
74
|
+
[でんでんコンバーターの設定ファイル](https://conv.denshochan.com/config)は設定ファイルとMarkdownファイルを別々に渡す方式でしたが、せっかくなのでJykellのようなfront-matterを使えば1ファイルにまとめられるのでは……? ということで、`---`が先頭に来れば次の`---`までをYAML形式の設定ファイルとして切り出すようにしてみました。
|
75
|
+
|
76
|
+
設定する内容については、でんでんコンバーターを参考にしようかとも思ったのですが、なんか複雑そうだったので思い切りシンプルなものにしてしまっています。
|
77
|
+
|
78
|
+
### 設定項目
|
79
|
+
|
80
|
+
#### id
|
81
|
+
|
82
|
+
本のID、identifierを指定します。現状1個だけです。そのうち必要があれば複数個指定できるようにしますが、ベタに内容を指定する方式のみにすると思います(でんでんコンバーターのidentifier-typeみたいなものは設けない)。
|
83
|
+
|
84
|
+
省略時にはUUIDを自動生成します。
|
85
|
+
|
86
|
+
#### title
|
87
|
+
|
88
|
+
本のタイトルを指定します。現状は1個しか指定できません。
|
89
|
+
|
90
|
+
省略は不可です。
|
91
|
+
|
92
|
+
#### author
|
93
|
+
|
94
|
+
本の著者を指定します。EPUB3だとcreatorですね。
|
95
|
+
|
96
|
+
省略は不可です。
|
97
|
+
|
98
|
+
#### date
|
99
|
+
|
100
|
+
出版日を指定します。省略時には現在日時が登録されます。
|
101
|
+
|
102
|
+
#### lastModified
|
103
|
+
|
104
|
+
最終更新日時を指定します。省略時には現在日時が登録されます。
|
105
|
+
|
106
|
+
#### pageDirection
|
107
|
+
|
108
|
+
ページの送り方向を指定します。横書きなら`ltr`、縦書きなら`rtl`にします。
|
109
|
+
|
110
|
+
省略時は設定自体が省略されます。
|
data/exe/cheepub
ADDED
data/lib/cheepub.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require "clamp"
|
2
|
+
require "cheepub/version"
|
3
|
+
require "cheepub/error"
|
4
|
+
require "cheepub/ext_hash"
|
5
|
+
require "cheepub/markdown"
|
6
|
+
require "cheepub/markdown/cheemarkdown"
|
7
|
+
require "cheepub/cli"
|
8
|
+
require "cheepub/generator"
|
9
|
+
require "cheepub/content"
|
10
|
+
|
11
|
+
module Cheepub
|
12
|
+
# Your code goes here...
|
13
|
+
end
|
data/lib/cheepub/cli.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
module Cheepub
|
2
|
+
class CLI < Clamp::Command
|
3
|
+
option ["-v", "--version"], :flag, "Show version" do
|
4
|
+
puts Cheepub::VERSION
|
5
|
+
exit(0)
|
6
|
+
end
|
7
|
+
|
8
|
+
parameter "SRC", "source file"
|
9
|
+
|
10
|
+
def execute
|
11
|
+
gen = Cheepub::Generator.new(src)
|
12
|
+
begin
|
13
|
+
gen.execute
|
14
|
+
rescue Cheepub::Error => e
|
15
|
+
puts "Error: #{e.message}"
|
16
|
+
if $DEBUG
|
17
|
+
puts e.backtrace
|
18
|
+
end
|
19
|
+
exit(1)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Cheepub
|
2
|
+
class Content
|
3
|
+
using Cheepub::ExtHash
|
4
|
+
|
5
|
+
SEPARATOR_PATTERN = /\n\n(?:\={3,}|\-{6,})\s*\n\n/m
|
6
|
+
FRONTMATTER_PATTERN = /\A---$(.*?)^---\n/m
|
7
|
+
|
8
|
+
attr_reader :src
|
9
|
+
attr_reader :header
|
10
|
+
attr_reader :body
|
11
|
+
attr_reader :pages
|
12
|
+
|
13
|
+
def initialize(content)
|
14
|
+
@content = content
|
15
|
+
@header, @body = parse_frontmatter(@content)
|
16
|
+
@pages = separate_pages(@body)
|
17
|
+
end
|
18
|
+
|
19
|
+
def html_pages
|
20
|
+
@pages.map{ |page| Cheepub::Markdown.new(page).convert }
|
21
|
+
end
|
22
|
+
|
23
|
+
def separate_pages(body)
|
24
|
+
pages = nil
|
25
|
+
if body =~ SEPARATOR_PATTERN
|
26
|
+
pages = body.split(SEPARATOR_PATTERN)
|
27
|
+
else
|
28
|
+
pages = [body]
|
29
|
+
end
|
30
|
+
pages.each_with_index do |page, idx|
|
31
|
+
if idx < pages.size - 1
|
32
|
+
page.concat("\n")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
pages
|
36
|
+
end
|
37
|
+
|
38
|
+
def parse_frontmatter(src)
|
39
|
+
header = body = nil
|
40
|
+
if src =~ FRONTMATTER_PATTERN
|
41
|
+
header, body = YAML.safe_load($1).symbolize_keys!, $'
|
42
|
+
else
|
43
|
+
header, body = Hash.new(), src
|
44
|
+
end
|
45
|
+
return header, body
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
require 'yaml'
|
3
|
+
require 'gepub'
|
4
|
+
|
5
|
+
module Cheepub
|
6
|
+
class Generator
|
7
|
+
|
8
|
+
ROLES = %i{aut edt trl ill cov cre pht cwt nrt}
|
9
|
+
|
10
|
+
def initialize(src, params = Hash.new)
|
11
|
+
if src.kind_of? Cheepub::Content
|
12
|
+
@src = nil
|
13
|
+
@content = src
|
14
|
+
else
|
15
|
+
@src = src
|
16
|
+
@content = Cheepub::Content.new(File.read(@src))
|
17
|
+
end
|
18
|
+
@params = params
|
19
|
+
end
|
20
|
+
|
21
|
+
def execute
|
22
|
+
params = @params.merge(@content.header)
|
23
|
+
if !params[:author] || !params[:title]
|
24
|
+
raise Cheepub::Error, "author and title should be defined."
|
25
|
+
end
|
26
|
+
book = GEPUB::Book.new
|
27
|
+
book.identifier = params[:id] || "urn:uuid:#{SecureRandom.uuid}"
|
28
|
+
book.title = params[:title]
|
29
|
+
if params[:creator]
|
30
|
+
parse_creator(book, params[:creator])
|
31
|
+
end
|
32
|
+
book.add_creator(params[:author])
|
33
|
+
book.language = params[:language] || 'ja'
|
34
|
+
book.version = '3.0'
|
35
|
+
book.publisher = params[:publisher]
|
36
|
+
## book.date= params[:date] || Time.now
|
37
|
+
book.add_date(params[:date] || Time.now, nil)
|
38
|
+
book.lastmodified = params[:lastModified] || Time.now
|
39
|
+
if params[:pageDirection]
|
40
|
+
book.page_progression_direction = params[:pageDirection]
|
41
|
+
end
|
42
|
+
File.open(File.join(File.dirname(__FILE__), "templates/style.css.erb")) do |f|
|
43
|
+
item = book.add_item("style.css")
|
44
|
+
item.add_content(f)
|
45
|
+
end
|
46
|
+
book.ordered do
|
47
|
+
@content.html_pages.each_with_index do |page, idx|
|
48
|
+
item = book.add_item("bodymatter_0_#{idx}.xhtml")
|
49
|
+
item.add_content(StringIO.new(page))
|
50
|
+
end
|
51
|
+
end
|
52
|
+
epubname = params[:epubname] || "book.epub"
|
53
|
+
book.generate_epub(epubname)
|
54
|
+
end
|
55
|
+
|
56
|
+
def parse_creator(book, creator)
|
57
|
+
if creator.kind_of? String
|
58
|
+
book.add_creator(creator)
|
59
|
+
else
|
60
|
+
creator.each do |role, name|
|
61
|
+
if !ROLES.include?(role)
|
62
|
+
raise Cheepub::Error, "invalid role: '#{role}' for creator '#{name}'."
|
63
|
+
end
|
64
|
+
book.add_creator(name, nil, role)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'kramdown'
|
2
|
+
|
3
|
+
module Cheepub
|
4
|
+
class Markdown
|
5
|
+
RUBY_PATTERN = /{([^}]+)\|([^}]+)}/
|
6
|
+
TCY_PATTERN = /\^([\u0020-\u005d\u005f\u007e]+)\^/ ## \u005e is "^"
|
7
|
+
|
8
|
+
def self.parse(filename, **params)
|
9
|
+
Markdown.new(File.read(filename), params)
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(text, **params)
|
13
|
+
default_params = {template: File.join(File.dirname(__FILE__), "templates/bodymatter.html.erb"),
|
14
|
+
lang: "ja",
|
15
|
+
title: "EPUB sample",
|
16
|
+
cssfile: "style.css",
|
17
|
+
generator: "Cheepub #{Cheepub::VERSION} with kramdown #{Kramdown::VERSION}",
|
18
|
+
input: "CheeMarkdown",
|
19
|
+
}
|
20
|
+
@params = default_params.merge(params)
|
21
|
+
@text = text
|
22
|
+
end
|
23
|
+
|
24
|
+
def convert
|
25
|
+
Kramdown::Document.new(@text, @params).to_html
|
26
|
+
end
|
27
|
+
|
28
|
+
alias_method :to_html, :convert
|
29
|
+
|
30
|
+
def save_as(filename)
|
31
|
+
html = convert
|
32
|
+
File.write(filename, html)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'kramdown/parser/kramdown'
|
2
|
+
|
3
|
+
module Kramdown
|
4
|
+
module Parser
|
5
|
+
class CheeMarkdown < Kramdown::Parser::GFM
|
6
|
+
|
7
|
+
def initialize(source, options)
|
8
|
+
super
|
9
|
+
@span_parsers.unshift(:ruby)
|
10
|
+
@span_parsers.unshift(:tcy)
|
11
|
+
@block_parsers.delete(:table)
|
12
|
+
end
|
13
|
+
|
14
|
+
RUBY_START = /(?:\{) ## begin
|
15
|
+
([^:\|}][^\|}]*) ## base text
|
16
|
+
\| ## separator
|
17
|
+
([^\|}]+) ## ruby text
|
18
|
+
(?:\})/x ## end
|
19
|
+
|
20
|
+
TCY_START = /\^([\u0020-\u005d\u005f\u007e]+)\^/ ## \u005e is "^"
|
21
|
+
|
22
|
+
def parse_ruby
|
23
|
+
start_line_number = @src.current_line_number
|
24
|
+
@src.pos += @src.matched_size
|
25
|
+
ruby_base, ruby_text = @src[1], @src[2]
|
26
|
+
ruby_el = Element.new(:html_element, :ruby, nil, :category => :span, :localtion => start_line_number)
|
27
|
+
@tree.children << ruby_el
|
28
|
+
|
29
|
+
@stack.push([@tree, @text_type])
|
30
|
+
@tree = ruby_el
|
31
|
+
add_text(ruby_base)
|
32
|
+
|
33
|
+
ruby_text_el = Element.new(:html_element, :rt, nil, :category => :span, :localtion => start_line_number)
|
34
|
+
@tree.children << ruby_text_el
|
35
|
+
|
36
|
+
@stack.push([@tree, @text_type])
|
37
|
+
|
38
|
+
@tree = ruby_text_el
|
39
|
+
add_text(ruby_text)
|
40
|
+
|
41
|
+
@tree, @text_type = @stack.pop
|
42
|
+
@tree, @text_type = @stack.pop
|
43
|
+
end
|
44
|
+
|
45
|
+
def parse_tcy
|
46
|
+
start_line_number = @src.current_line_number
|
47
|
+
@src.pos += @src.matched_size
|
48
|
+
|
49
|
+
tcy_text = @src[1]
|
50
|
+
tcy_el = Element.new(:html_element, :span, {class: "tcy"}, :category => :span, :localtion => start_line_number)
|
51
|
+
@tree.children << tcy_el
|
52
|
+
|
53
|
+
@stack.push([@tree, @text_type])
|
54
|
+
@tree = tcy_el
|
55
|
+
add_text(tcy_text)
|
56
|
+
|
57
|
+
@tree, @text_type = @stack.pop
|
58
|
+
end
|
59
|
+
|
60
|
+
define_parser(:ruby, RUBY_START, '\{[^:]')
|
61
|
+
define_parser(:tcy, TCY_START, '\^')
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<!DOCTYPE html>
|
3
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" xml:lang="<%= @converter.options[:lang] %>" lang="<%= @converter.options[:lang] %>">
|
4
|
+
<head>
|
5
|
+
<meta charset="utf-8" />
|
6
|
+
<link rel="stylesheet" href="<%= @converter.options[:cssfile] %>" type="text/css" />
|
7
|
+
<title><%= @converter.options[:title] %></title>
|
8
|
+
<meta name="generator" content="<%= @converter.options[:generator] %>" />
|
9
|
+
</head>
|
10
|
+
<body class="bodymatter" epub:type="bodymatter">
|
11
|
+
<%= @body %> </body>
|
12
|
+
</html>
|
@@ -0,0 +1,143 @@
|
|
1
|
+
@charset "UTF-8";
|
2
|
+
@namespace "http://www.w3.org/1999/xhtml";
|
3
|
+
@namespace epub "http://www.idpf.org/2007/ops";
|
4
|
+
|
5
|
+
html {
|
6
|
+
-epub-writing-mode: vertical-rl;
|
7
|
+
-webkit-writing-mode: vertical-rl;
|
8
|
+
writing-mode: vertical-rl;
|
9
|
+
}
|
10
|
+
|
11
|
+
body {
|
12
|
+
font-family: serif, sans-serif;
|
13
|
+
word-wrap: break-word;
|
14
|
+
}
|
15
|
+
|
16
|
+
h1, h2, h3, h4, h5, h6 {
|
17
|
+
font-family: sans-serif;
|
18
|
+
font-weight: normal;
|
19
|
+
}
|
20
|
+
|
21
|
+
h1 {
|
22
|
+
font-size: 1.8em;
|
23
|
+
}
|
24
|
+
|
25
|
+
h2 {
|
26
|
+
font-size: 1.4em;
|
27
|
+
}
|
28
|
+
|
29
|
+
h3 {
|
30
|
+
font-size: 1.2em;
|
31
|
+
}
|
32
|
+
|
33
|
+
h4 {
|
34
|
+
font-size: 1em;
|
35
|
+
}
|
36
|
+
|
37
|
+
h5 {
|
38
|
+
font-size: 0.9em;
|
39
|
+
}
|
40
|
+
|
41
|
+
h6 {
|
42
|
+
font-size: 0.8em;
|
43
|
+
}
|
44
|
+
|
45
|
+
p {
|
46
|
+
line-height: 1.6;
|
47
|
+
}
|
48
|
+
|
49
|
+
p, li, dt, dd {
|
50
|
+
line-height: 1.6;
|
51
|
+
}
|
52
|
+
|
53
|
+
b, strong, dt, caption, figcaption, th {
|
54
|
+
font-family: sans-serif;
|
55
|
+
}
|
56
|
+
|
57
|
+
blockquote, ul, fieldset, form, ol, dl, menu {
|
58
|
+
margin-right: 1.5em;
|
59
|
+
margin-left: 1.5em;
|
60
|
+
padding: 0;
|
61
|
+
}
|
62
|
+
|
63
|
+
blockquote blockquote, blockquote ol, blockquote ul, blockquote dl,
|
64
|
+
ol blockquote, ol ol, ol ul, ol dl,
|
65
|
+
ul blockquote, ul ol, ul ul, ul dl,
|
66
|
+
dl blockquote, dl ol, dl ul, dl dl {
|
67
|
+
margin-right: 0em;
|
68
|
+
margin-left: 0em;
|
69
|
+
}
|
70
|
+
|
71
|
+
pre {
|
72
|
+
white-space: pre-wrap;
|
73
|
+
}
|
74
|
+
|
75
|
+
img {
|
76
|
+
width: auto;
|
77
|
+
height: auto;
|
78
|
+
max-width: 100%;
|
79
|
+
max-height: 100%;
|
80
|
+
}
|
81
|
+
|
82
|
+
table {
|
83
|
+
border-collapse: collapse;
|
84
|
+
border-spacing: 0;
|
85
|
+
}
|
86
|
+
|
87
|
+
rt {
|
88
|
+
font-family: serif, sans-serif;
|
89
|
+
}
|
90
|
+
|
91
|
+
.tcy {
|
92
|
+
-epub-text-combine: horizontal;
|
93
|
+
-webkit-text-combine: horizontal;
|
94
|
+
-ms-text-combine-horizontal: all;
|
95
|
+
text-combine-horizontal: all;
|
96
|
+
text-combine-upright: all;
|
97
|
+
}
|
98
|
+
|
99
|
+
.sideways {
|
100
|
+
-epub-text-orientation: sideways;
|
101
|
+
text-orientation: sideways;
|
102
|
+
}
|
103
|
+
|
104
|
+
.upright {
|
105
|
+
-epub-text-orientation: rotate-right;
|
106
|
+
-epub-text-orientation: upright;
|
107
|
+
-webkit-text-orientation: upright;
|
108
|
+
-epub-text-combine: horizontal;
|
109
|
+
-webkit-text-combine: horizontal;
|
110
|
+
text-combine-horizontal: all;
|
111
|
+
text-combine-upright: all;
|
112
|
+
}
|
113
|
+
|
114
|
+
blockquote {
|
115
|
+
margin-top: 0.5em;
|
116
|
+
margin-bottom: 0.5em;
|
117
|
+
}
|
118
|
+
|
119
|
+
p {
|
120
|
+
margin: 0;
|
121
|
+
}
|
122
|
+
|
123
|
+
em {
|
124
|
+
font-style: normal;
|
125
|
+
-epub-text-emphasis-style: filled sesame;
|
126
|
+
text-emphasis-style: filled sesame;
|
127
|
+
}
|
128
|
+
|
129
|
+
.text-left {
|
130
|
+
text-align: left;
|
131
|
+
}
|
132
|
+
.text-right {
|
133
|
+
text-align: right;
|
134
|
+
}
|
135
|
+
.text-center {
|
136
|
+
text-align: center;
|
137
|
+
}
|
138
|
+
.text-justify {
|
139
|
+
text-align: justify;
|
140
|
+
}
|
141
|
+
.text-pre-wrap {
|
142
|
+
white-space: pre-wrap;
|
143
|
+
}
|
metadata
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cheepub
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- takahashim
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-05-05 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: gepub
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: kramdown
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.16'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.16'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: clamp
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.2'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.2'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rufo
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.3'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.3'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: bundler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.16'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.16'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '12.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '12.0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: test-unit
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '3.2'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '3.2'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: test-unit-notify
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: terminal-notifier
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
description: Simple EPUB generator from Markdown. Inspired by denden converter
|
140
|
+
email:
|
141
|
+
- maki@rubycolor.org
|
142
|
+
executables:
|
143
|
+
- cheepub
|
144
|
+
extensions: []
|
145
|
+
extra_rdoc_files: []
|
146
|
+
files:
|
147
|
+
- ".gitignore"
|
148
|
+
- ".travis.yml"
|
149
|
+
- Gemfile
|
150
|
+
- LICENSE
|
151
|
+
- README.md
|
152
|
+
- Rakefile
|
153
|
+
- bin/console
|
154
|
+
- bin/setup
|
155
|
+
- cheepub.gemspec
|
156
|
+
- doc/README_ja.md
|
157
|
+
- exe/cheepub
|
158
|
+
- lib/cheepub.rb
|
159
|
+
- lib/cheepub/cli.rb
|
160
|
+
- lib/cheepub/content.rb
|
161
|
+
- lib/cheepub/error.rb
|
162
|
+
- lib/cheepub/ext_hash.rb
|
163
|
+
- lib/cheepub/generator.rb
|
164
|
+
- lib/cheepub/markdown.rb
|
165
|
+
- lib/cheepub/markdown/cheemarkdown.rb
|
166
|
+
- lib/cheepub/templates/bodymatter.html.erb
|
167
|
+
- lib/cheepub/templates/style.css.erb
|
168
|
+
- lib/cheepub/version.rb
|
169
|
+
homepage: https://github.com/takahashim/cheepub
|
170
|
+
licenses: []
|
171
|
+
metadata: {}
|
172
|
+
post_install_message:
|
173
|
+
rdoc_options: []
|
174
|
+
require_paths:
|
175
|
+
- lib
|
176
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
181
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
182
|
+
requirements:
|
183
|
+
- - ">="
|
184
|
+
- !ruby/object:Gem::Version
|
185
|
+
version: '0'
|
186
|
+
requirements: []
|
187
|
+
rubyforge_project:
|
188
|
+
rubygems_version: 2.7.3
|
189
|
+
signing_key:
|
190
|
+
specification_version: 4
|
191
|
+
summary: Simple EPUB generator from Markdown
|
192
|
+
test_files: []
|