maliq 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -26,7 +26,7 @@ Follow the steps below:
26
26
 
27
27
  2. Write meta data required for EPUB in the head of the file with Yaml Front Matter(YFM) form(see below).
28
28
 
29
- 3. You can obtain separated xhtml files each of which represents a chapter from a markdown file if needed. This achive by placing a special marker into target line of your content. The Default marker is `<<<--- <filename> --->>>`. (ex. `<<<--- chapter02 --->>>`)
29
+ 3. You can obtain separated xhtml files each of which represents a chapter from a markdown file if needed. This achive by placing a special marker into target line of your content. The Default marker is `<<<--- <filename> --->>>` (ex. `<<<--- chapter02 --->>>`). When filenames are omitted, system generate sequential names automatically for them.
30
30
 
31
31
  4. Place css and image files into the directory or its sub directory if any.
32
32
 
data/bin/maliq CHANGED
@@ -4,31 +4,6 @@ require "trollop"
4
4
 
5
5
  class OptionParser
6
6
  def self.parse!
7
- opts = build_opts
8
-
9
- filenames = ARGV.select { |f| f.match /\.(md|markdown)$/ }
10
- if filenames.empty?
11
- abort "Must pass one or more markdown filenames to build xhtml output."
12
- end
13
- csses = Dir['*.css', '*/*.css']
14
-
15
- lastname = nil
16
- filenames.each_with_index do |fname, fno|
17
- seq_name = Maliq::FileUtils.create_filename(lastname) if lastname && opts[:seq]
18
- chapters = Maliq::FileUtils.split(fname)
19
- chapters.each do |title, text|
20
- title = seq_name.tap { |s| seq_name = seq_name.next } if !fno.zero? && opts[:seq]
21
- dest = title.basename_with(:xhtml)
22
- conv = Maliq::Converter.new(text, css:csses)
23
- conv.set_meta(liquid:opts[:liquid]) if opts[:liquid]
24
- conv.save(dest)
25
- puts "'#{dest}' created."
26
- lastname = title
27
- end
28
- end
29
- end
30
-
31
- def self.build_opts
32
7
  Trollop::options do
33
8
  version "Maliq #{Maliq::VERSION} (c) 2012 kyoendo"
34
9
  banner ~<<-EOS
@@ -62,8 +37,15 @@ class OptionParser
62
37
 
63
38
  opt :liquid, "Liquid plugin path", :type => :string
64
39
  opt :seq, "Build consecutive filenames", :default => false
40
+ opt :nav, "Create nav.xhtml(TOC)", :default => true
41
+ opt :toc, "Set title for TOC", :default => ''
65
42
  end
66
43
  end
67
44
  end
68
45
 
69
- OptionParser.parse!
46
+ opts = OptionParser.parse!
47
+ css = Dir['*.css', '*/*.css']
48
+ opts.update(css: css)
49
+ opts.update(toc:nil) if opts[:toc].empty?
50
+
51
+ Maliq::Create.new(ARGV, opts).run!
@@ -3,24 +3,6 @@
3
3
  require "maliq"
4
4
  require "trollop"
5
5
  require "gepub"
6
- require "stringio"
7
-
8
- # a patch for Nokogiri::XML::Node#namespaces
9
- # Hash[ alist ] => Hash[ *alist.flatten ]
10
- class Nokogiri::XML::Node
11
- def namespaces
12
- Hash[*namespace_scopes.map { |nd|
13
- key = ['xmlns', nd.prefix].compact.join(':')
14
- if RUBY_VERSION >= '1.9' && document.encoding
15
- begin
16
- key.force_encoding document.encoding
17
- rescue ArgumentError
18
- end
19
- end
20
- [key, nd.href]
21
- }.flatten]
22
- end
23
- end
24
6
 
25
7
  class OptionParser
26
8
  class << self
@@ -90,12 +72,11 @@ class OptionParser
90
72
  cover_xhtml = create_cover_page(cover)
91
73
  end
92
74
 
93
- xhtmls.map! { |f| xhtml_with_heading f }
75
+ navfile, xhtmls = pick_nav_file(xhtmls)
94
76
 
95
- # Create Table of Contents page.
96
- if opts[:toc] && no_nav_page?(xhtmls)
97
- nav_xhtml = create_nav_page(xhtmls, css:csses)
98
- end
77
+ heading_files = get_heading_files(navfile)
78
+
79
+ xhtmls.map! { |f| xhtml_with_heading f }
99
80
 
100
81
  GEPUB::Builder.new do
101
82
  metadata.each { |k, v| send k, *Array(v) }
@@ -110,14 +91,11 @@ class OptionParser
110
91
  heading 'Cover'
111
92
  end
112
93
 
113
- if nav_xhtml
114
- file 'nav.xhtml' => nav_xhtml
115
- heading 'Table of Contents'
116
- end
94
+ nav navfile if navfile
117
95
 
118
96
  xhtmls.each do |fname, head|
119
97
  file fname
120
- heading head
98
+ heading head if !navfile || heading_files.include?(fname)
121
99
  end
122
100
  }
123
101
  }
@@ -129,22 +107,14 @@ class OptionParser
129
107
  StringIO.new(out)
130
108
  end
131
109
 
132
- def no_nav_page?(xhtmls)
133
- xhtmls.none? { |fname, _| File.basename(fname, '.*').match /(nav|toc)$/ }
110
+ def pick_nav_file(xhtmls)
111
+ navs, xhtmls = xhtmls.partition { |fname| fname.match /^(nav|toc)\.x*html$/ }
112
+ nav = navs.empty? ? nil : navs.first
113
+ return nav, xhtmls
134
114
  end
135
115
 
136
- def create_nav_page(xhtmls, opts={})
137
- out = Maliq::Converter.new(~<<-EOS, opts).run(:epub, 'xhtmls' => xhtmls)
138
- ## Table of Contents
139
-
140
- <ol id='toc'>
141
- {% for ch in xhtmls %}
142
- <li><a href='{{ ch[0] }}'>{{ ch[1] }}</a></li>
143
- {% endfor %}
144
- </ol>
145
-
146
- EOS
147
- StringIO.new(out)
116
+ def get_heading_files(navfile)
117
+ File.read(navfile).scan(/\w+\.xhtml(?=.*?<\/li>)/) if navfile
148
118
  end
149
119
 
150
120
  def xhtml_with_heading(xhtml)
@@ -1,5 +1,5 @@
1
1
  require "maliq/version"
2
2
 
3
3
  module Maliq
4
- %w(system_extensions file_utils converter).each { |lib| require_relative 'maliq/' + lib }
4
+ %w(system_extensions file_utils converter create).each { |lib| require_relative 'maliq/' + lib }
5
5
  end
@@ -0,0 +1,79 @@
1
+ # encoding: UTF-8
2
+ # Maliq::Create receive markdown filename(s)
3
+ # and create xhtml file(s).
4
+ class Maliq::Create
5
+ def initialize(files, opts={})
6
+ @opts = opts
7
+ @nav = opts.delete(:toc) || opts.delete(:nav)
8
+ @mdfiles = get_markdown_files(files)
9
+ end
10
+
11
+ def get_markdown_files(files)
12
+ files.select { |f| f.match /\.(md|markdown)$/ }
13
+ .tap { |res|
14
+ if res.empty?
15
+ abort "Must pass one or more markdown filenames to build xhtml output."
16
+ end
17
+ }
18
+ end
19
+ private :get_markdown_files
20
+
21
+ def run!
22
+ lastname = nil
23
+ dirname = nil
24
+ nav_list = []
25
+ @mdfiles.each_with_index do |filename, fno|
26
+ dirname = File.dirname(filename)
27
+ if @opts[:seq] && lastname
28
+ seq_fname = Maliq::FileUtils.create_filename(lastname)
29
+ end
30
+
31
+ # Split a file at split markers to several chapters,
32
+ # each of which become a file.
33
+ chapters = Maliq::FileUtils.split(filename)
34
+
35
+ chapters.each do |fname, content|
36
+ #this change filenames with sequential names.
37
+ if @opts[:seq] && !fno.zero?
38
+ fname = seq_fname.tap { |s| seq_fname = seq_fname.next }
39
+ end
40
+
41
+ dest = File.join(dirname, fname.basename_with(:xhtml))
42
+ convert_and_save(content, dest)
43
+ nav_list << [fname, content]
44
+ lastname = fname
45
+ end
46
+ end
47
+ create_nav_page(nav_list, File.join(dirname, 'nav.xhtml')) if @nav
48
+ end
49
+
50
+ private
51
+ def convert_and_save(md_content, dest)
52
+ conv = Maliq::Converter.new(md_content, css:@opts[:css])
53
+ conv.set_meta(liquid:@opts[:liquid]) if @opts[:liquid]
54
+ conv.save(dest)
55
+ end
56
+
57
+ def create_nav_page(nav_list, dest)
58
+ nav_list.map! do |fname, content|
59
+ header = File.basename(fname, '.*').capitalize
60
+ content.match(/^\#{1,3}(.*)$/) { header = $1 } # find the first header
61
+ [fname.basename_with(:xhtml), header]
62
+ end
63
+
64
+ toc = @nav.is_a?(String) ? @nav : "##目次"
65
+
66
+ body = Maliq::Converter.new(~<<-EOS, @opts).run(:epub, 'list' => nav_list)
67
+ <nav epub:type="toc" id="toc">
68
+ #{toc}
69
+ <ol class='toc'>
70
+ {% for ch in list %}
71
+ <li><a href='{{ ch[0] }}'>{{ ch[1] }}</a></li>
72
+ {% endfor %}
73
+ </ol>
74
+ </nav>
75
+ EOS
76
+ body = body.gsub(/<p>(<nav.*?>)<\/p>/, '\1').gsub(/<p>(<\/nav>)<\/p>/, '\1')
77
+ File.write(dest, body)
78
+ end
79
+ end
@@ -1,3 +1,3 @@
1
1
  module Maliq
2
- VERSION = "0.0.7"
2
+ VERSION = "0.0.8"
3
3
  end
@@ -0,0 +1,112 @@
1
+ # encoding: UTF-8
2
+ require_relative 'spec_helper'
3
+
4
+ describe Maliq::Create do
5
+ before(:each) do
6
+ @header, @footer = ->lang='ja',title=nil{ ~<<-HEAD }, ~<<-FOOT
7
+ <?xml version="1.0" encoding="UTF-8"?>
8
+ <!DOCTYPE html>
9
+ <html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" xml:lang="#{lang}">
10
+ <head>
11
+ <title>#{title}</title>
12
+ <link href='style.css' rel='stylesheet' type='text/css'/>
13
+ </head>
14
+ <body>
15
+ HEAD
16
+ </body>
17
+ </html>
18
+ FOOT
19
+ end
20
+
21
+ describe "#run" do
22
+ context "when pass one markdown file with a css" do
23
+ it 'returns one xhtml file with same filename' do
24
+ Dir.mktmpdir do |dir|
25
+ mdfile = "#{dir}/chap1.md"
26
+ cssfile = "#{dir}/style.css"
27
+ File.write(mdfile, ~<<-EOS)
28
+ ---
29
+ title: 'Sample'
30
+ ---
31
+ #title1
32
+ #title2
33
+ EOS
34
+ system 'touch', cssfile
35
+ Maliq::Create.new([mdfile], css:File.basename(cssfile)).run!
36
+ xhtml = "#{dir}/chap1.xhtml"
37
+ File.exist?(xhtml).should be_true
38
+ File.read(xhtml).should eql [@header.call('ja','Sample'), ~<<-EOS, @footer].join
39
+ <h1>title1</h1>
40
+
41
+ <h1>title2</h1>
42
+ EOS
43
+ end
44
+ end
45
+ end
46
+
47
+ context "when pass one markdown file in which split marker placed" do
48
+ it "returns two xhtml files" do
49
+ Dir.mktmpdir do |dir|
50
+ mdfile = "#{dir}/chap1.md"
51
+ cssfile = "#{dir}/style.css"
52
+ File.write(mdfile, ~<<-EOS)
53
+ ---
54
+ title: 'Sample'
55
+ ---
56
+ #title1
57
+ <<<------>>>
58
+ #title2
59
+ EOS
60
+ system 'touch', cssfile
61
+ Maliq::Create.new([mdfile], css:File.basename(cssfile)).run!
62
+ xhtml1, xhtml2 = "#{dir}/chap1.xhtml", "#{dir}/chap2.xhtml"
63
+ File.exist?(xhtml1).should be_true
64
+ File.exist?(xhtml2).should be_true
65
+ File.read(xhtml1).should eql [@header.call('ja','Sample'), ~<<-EOS, @footer].join
66
+ <h1>title1</h1>
67
+ EOS
68
+ File.read(xhtml2).should eql [@header.call('ja','Sample'), ~<<-EOS, @footer].join
69
+ <h1>title2</h1>
70
+ EOS
71
+ end
72
+ end
73
+ end
74
+
75
+ context "when nav option is true" do
76
+ it "also create nav.xhtml" do
77
+ Dir.mktmpdir do |dir|
78
+ mdfile = "#{dir}/chap1.md"
79
+ cssfile = "#{dir}/style.css"
80
+ File.write(mdfile, ~<<-EOS)
81
+ ---
82
+ title: 'Sample'
83
+ ---
84
+ #title1
85
+ <<<------>>>
86
+ #title2
87
+ EOS
88
+ system 'touch', cssfile
89
+ Maliq::Create.new([mdfile], css:File.basename(cssfile), nav:true).run!
90
+ nav = "#{dir}/nav.xhtml"
91
+ File.exist?(nav).should be_true
92
+ File.read(nav).should eql [@header.call, ~<<-EOS, @footer].join
93
+ <nav epub:type="toc" id="toc">
94
+
95
+ <h2>目次</h2>
96
+
97
+ <ol class='toc'>
98
+
99
+ <li><a href='chap1.xhtml'>title1</a></li>
100
+
101
+ <li><a href='chap2.xhtml'>title2</a></li>
102
+
103
+ </ol>
104
+
105
+
106
+ </nav>
107
+ EOS
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: maliq
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
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: 2012-12-18 00:00:00.000000000 Z
12
+ date: 2012-12-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: trollop
@@ -109,11 +109,13 @@ files:
109
109
  - bin/maliq_gepub
110
110
  - lib/maliq.rb
111
111
  - lib/maliq/converter.rb
112
+ - lib/maliq/create.rb
112
113
  - lib/maliq/file_utils.rb
113
114
  - lib/maliq/system_extensions.rb
114
115
  - lib/maliq/version.rb
115
116
  - maliq.gemspec
116
117
  - spec/converter_spec.rb
118
+ - spec/create_spec.rb
117
119
  - spec/file_utils_spec.rb
118
120
  - spec/plugins/calc.rb
119
121
  - spec/spec_helper.rb
@@ -145,6 +147,7 @@ summary: Maliq is a markdown, liquid converter for EPUB's xhtml. It comes with t
145
147
  is a wrapper of gepub gem which is a EPUB generator.
146
148
  test_files:
147
149
  - spec/converter_spec.rb
150
+ - spec/create_spec.rb
148
151
  - spec/file_utils_spec.rb
149
152
  - spec/plugins/calc.rb
150
153
  - spec/spec_helper.rb