kitabu 2.1.0 → 3.0.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.
Files changed (92) hide show
  1. checksums.yaml +5 -5
  2. data/.github/CODEOWNERS +4 -0
  3. data/.github/FUNDING.yml +4 -0
  4. data/.github/ISSUE_TEMPLATE/bug_report.md +41 -0
  5. data/.github/ISSUE_TEMPLATE/config.yml +5 -0
  6. data/.github/ISSUE_TEMPLATE/feature_request.md +23 -0
  7. data/.github/PULL_REQUEST_TEMPLATE.md +38 -0
  8. data/.github/dependabot.yml +15 -0
  9. data/.github/workflows/ruby-tests.yml +61 -0
  10. data/.rubocop.yml +17 -0
  11. data/CHANGELOG.md +13 -2
  12. data/CODE_OF_CONDUCT.md +74 -0
  13. data/CONTRIBUTING.md +79 -0
  14. data/Gemfile +2 -0
  15. data/LICENSE.md +20 -0
  16. data/README.md +103 -88
  17. data/Rakefile +7 -0
  18. data/bin/kitabu +4 -0
  19. data/kitabu.gemspec +21 -15
  20. data/lib/kitabu/cli.rb +54 -39
  21. data/lib/kitabu/dependency.rb +11 -5
  22. data/lib/kitabu/errors.rb +2 -0
  23. data/lib/kitabu/exporter/base.rb +11 -11
  24. data/lib/kitabu/exporter/css.rb +6 -15
  25. data/lib/kitabu/exporter/epub.rb +23 -17
  26. data/lib/kitabu/exporter/html.rb +27 -21
  27. data/lib/kitabu/exporter/mobi.rb +7 -1
  28. data/lib/kitabu/exporter/pdf.rb +9 -3
  29. data/lib/kitabu/exporter.rb +15 -16
  30. data/lib/kitabu/extensions/rouge.rb +6 -1
  31. data/lib/kitabu/extensions/string.rb +5 -3
  32. data/lib/kitabu/footnotes/base.rb +2 -0
  33. data/lib/kitabu/footnotes/html.rb +18 -13
  34. data/lib/kitabu/footnotes/pdf.rb +17 -11
  35. data/lib/kitabu/generator.rb +13 -8
  36. data/lib/kitabu/helpers.rb +12 -9
  37. data/lib/kitabu/markdown.rb +12 -10
  38. data/lib/kitabu/source_list.rb +15 -12
  39. data/lib/kitabu/stats.rb +3 -1
  40. data/lib/kitabu/syntax/highlight.rb +4 -11
  41. data/lib/kitabu/toc/epub.rb +5 -2
  42. data/lib/kitabu/toc/html/stream.rb +3 -1
  43. data/lib/kitabu/toc/html.rb +12 -8
  44. data/lib/kitabu/version.rb +4 -2
  45. data/lib/kitabu.rb +8 -10
  46. data/spec/kitabu/cli/export_spec.rb +6 -4
  47. data/spec/kitabu/cli/new_spec.rb +6 -4
  48. data/spec/kitabu/cli/permalinks_spec.rb +4 -2
  49. data/spec/kitabu/cli/stats_spec.rb +19 -15
  50. data/spec/kitabu/cli/version_spec.rb +3 -1
  51. data/spec/kitabu/exporter/css_spec.rb +3 -1
  52. data/spec/kitabu/exporter/epub_spec.rb +2 -0
  53. data/spec/kitabu/exporter/html_spec.rb +11 -9
  54. data/spec/kitabu/exporter/mobi_spec.rb +5 -5
  55. data/spec/kitabu/exporter/pdf_spec.rb +8 -4
  56. data/spec/kitabu/extensions/string_spec.rb +14 -9
  57. data/spec/kitabu/footnotes/html_spec.rb +35 -33
  58. data/spec/kitabu/generator_spec.rb +3 -1
  59. data/spec/kitabu/markdown_spec.rb +8 -6
  60. data/spec/kitabu/source_list_spec.rb +8 -2
  61. data/spec/kitabu/stats_spec.rb +10 -6
  62. data/spec/kitabu/toc/html_spec.rb +37 -21
  63. data/spec/spec_helper.rb +23 -8
  64. data/spec/support/exit_with_code.rb +7 -5
  65. data/spec/support/have_tag.rb +44 -32
  66. data/spec/support/helper.rb +5 -3
  67. data/spec/support/mybook/code/code.rb +2 -0
  68. data/spec/support/mybook/config/helper.rb +2 -0
  69. data/spec/support/shared.rb +8 -6
  70. data/templates/Gemfile +5 -3
  71. data/templates/Guardfile +3 -1
  72. data/templates/helper.rb +8 -6
  73. data/templates/templates/styles/epub.css +1 -0
  74. data/templates/templates/styles/files/normalize.css +351 -0
  75. data/templates/templates/styles/{html.scss → html.css} +28 -26
  76. data/templates/templates/styles/{pdf.scss → pdf.css} +49 -47
  77. data/templates/templates/styles/print.css +2 -0
  78. data/templates/text/01_Getting_Started.md +27 -9
  79. data/templates/text/02_Creating_Chapters.md +9 -3
  80. data/templates/text/{03_Syntax_Highlighting.erb → 03_Syntax_Highlighting.md.erb} +12 -7
  81. data/templates/text/04_Dynamic_Content.md.erb +48 -0
  82. data/templates/text/05_Exporting_Files.md +17 -8
  83. metadata +40 -48
  84. data/.gitmodules +0 -3
  85. data/.travis.yml +0 -18
  86. data/lib/kitabu/exporter/txt.rb +0 -18
  87. data/spec/kitabu/exporter/txt_spec.rb +0 -14
  88. data/templates/ebook.png +0 -0
  89. data/templates/templates/styles/epub.scss +0 -1
  90. data/templates/templates/styles/files/_normalize.scss +0 -427
  91. data/templates/templates/styles/print.scss +0 -2
  92. data/templates/text/04_Dynamic_Content.erb +0 -64
@@ -1,15 +1,18 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Kitabu
2
4
  class Exporter
3
5
  class Epub < Base
4
6
  def sections
5
- @sections ||= html.css("div.chapter").each_with_index.map do |chapter, index|
6
- OpenStruct.new({
7
- index: index,
8
- filename: "section_#{index}.html",
9
- filepath: tmp_dir.join("section_#{index}.html").to_s,
10
- html: Nokogiri::HTML(chapter.inner_html)
11
- })
12
- end
7
+ @sections ||=
8
+ html.css("div.chapter").each_with_index.map do |chapter, index|
9
+ OpenStruct.new(
10
+ index: index,
11
+ filename: "section_#{index}.html",
12
+ filepath: tmp_dir.join("section_#{index}.html").to_s,
13
+ html: Nokogiri::HTML(chapter.inner_html)
14
+ )
15
+ end
13
16
  end
14
17
 
15
18
  def epub
@@ -34,7 +37,7 @@ module Kitabu
34
37
  epub.save(epub_path)
35
38
 
36
39
  true
37
- rescue Exception => error
40
+ rescue StandardError => error
38
41
  handle_error(error)
39
42
  false
40
43
  end
@@ -54,7 +57,8 @@ module Kitabu
54
57
  epub.publisher config[:publisher]
55
58
  epub.date config[:published_at]
56
59
  epub.uid config[:uid]
57
- epub.identifier config[:identifier][:id], scheme: config[:identifier][:type]
60
+ epub.identifier config[:identifier][:id],
61
+ scheme: config[:identifier][:type]
58
62
  epub.cover_page cover_image if cover_image && File.exist?(cover_image)
59
63
  end
60
64
 
@@ -70,13 +74,11 @@ module Kitabu
70
74
  # First we need to get all ids, which are used as
71
75
  # the anchor target.
72
76
  #
73
- links = sections.inject({}) do |buffer, section|
77
+ links = sections.each_with_object({}) do |section, buffer|
74
78
  section.html.css("[id]").each do |element|
75
- anchor = "##{element["id"]}"
79
+ anchor = "##{element['id']}"
76
80
  buffer[anchor] = "#{section.filename}#{anchor}"
77
81
  end
78
-
79
- buffer
80
82
  end
81
83
 
82
84
  # Then we can normalize all links and
@@ -102,14 +104,16 @@ module Kitabu
102
104
  # Save file to disk.
103
105
  #
104
106
  File.open(section.filepath, "w") do |file|
105
- body = section.html.css("body").to_xhtml.gsub(%r[<body>(.*?)</body>]m, "\\1")
107
+ body = section.html.css("body").to_xhtml.gsub(
108
+ %r{<body>(.*?)</body>}m, "\\1"
109
+ )
106
110
  file << render_chapter(body)
107
111
  end
108
112
  end
109
113
  end
110
114
 
111
115
  def render_chapter(content)
112
- locals = config.merge(:content => content)
116
+ locals = config.merge(content: content)
113
117
  render_template(template_path, locals)
114
118
  end
115
119
 
@@ -122,7 +126,9 @@ module Kitabu
122
126
  end
123
127
 
124
128
  def cover_image
125
- path = Dir[root_dir.join("templates/epub/cover.{jpg,png,gif}").to_s].first
129
+ path =
130
+ Dir[root_dir.join("templates/epub/cover.{jpg,png,gif}").to_s].first
131
+
126
132
  return path if path && File.exist?(path)
127
133
  end
128
134
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Kitabu
2
4
  class Exporter
3
5
  class HTML < Base
@@ -21,7 +23,7 @@ module Kitabu
21
23
  end
22
24
 
23
25
  true
24
- rescue Exception => error
26
+ rescue StandardError => error
25
27
  handle_error(error)
26
28
  false
27
29
  end
@@ -33,28 +35,29 @@ module Kitabu
33
35
  # Return all chapters wrapped in a <tt>div.chapter</tt> tag.
34
36
  #
35
37
  def content
36
- String.new.tap do |content|
38
+ buffer = [].tap do |content|
37
39
  source_list.each_chapter do |files|
38
40
  content << %[<div class="chapter">#{render_chapter(files)}</div>]
39
41
  end
40
42
  end
43
+
44
+ buffer.join
41
45
  end
42
46
 
43
- private
44
47
  # Render +file+ considering its extension.
45
48
  #
46
- def render_file(file)
47
- if format(file) == :erb
48
- content = render_template(file, config)
49
- else
50
- content = File.read(file)
51
- end
49
+ private def render_file(file_path)
50
+ content = if file_format(file_path) == :erb
51
+ render_template(file_path, config)
52
+ else
53
+ File.read(file_path)
54
+ end
52
55
 
53
56
  Kitabu::Markdown.render(content)
54
57
  end
55
58
 
56
- def format(file)
57
- if File.extname(file) == '.erb'
59
+ private def file_format(file_path)
60
+ if File.extname(file_path) == ".erb"
58
61
  :erb
59
62
  else
60
63
  :markdown
@@ -63,15 +66,16 @@ module Kitabu
63
66
 
64
67
  # Parse layout file, making available all configuration entries.
65
68
  #
66
- def parse_layout(html)
69
+ private def parse_layout(html)
67
70
  toc = TOC::HTML.generate(html)
68
- content = Footnotes::HTML.process(toc.content).html.css('body').first.inner_html
71
+ content =
72
+ Footnotes::HTML.process(toc.content).html.css("body").first.inner_html
69
73
 
70
- locals = config.merge({
74
+ locals = config.merge(
71
75
  content: content,
72
76
  toc: toc.to_html,
73
77
  changelog: render_changelog
74
- })
78
+ )
75
79
 
76
80
  render_template(root_dir.join("templates/html/layout.erb"), locals)
77
81
  end
@@ -79,36 +83,38 @@ module Kitabu
79
83
  # Render changelog file.
80
84
  # This file can be used to inform any book change.
81
85
  #
82
- def render_changelog
86
+ private def render_changelog
83
87
  changelog = Dir[root_dir.join("text/CHANGELOG.*")].first
84
88
  render_file(changelog) if changelog
85
89
  end
86
90
 
87
91
  # Render all +files+ from a given chapter.
88
92
  #
89
- def render_chapter(files)
90
- String.new.tap do |chapter|
93
+ private def render_chapter(files)
94
+ buffer = [].tap do |chapter|
91
95
  files.each do |file|
92
96
  chapter << render_file(file) << "\n\n"
93
97
  end
94
98
  end
99
+
100
+ buffer.join
95
101
  end
96
102
 
97
103
  # Copy images
98
104
  #
99
- def copy_images!
105
+ private def copy_images!
100
106
  copy_directory("images", "output/images")
101
107
  end
102
108
 
103
109
  # Copy font files
104
110
  #
105
- def copy_fonts!
111
+ private def copy_fonts!
106
112
  copy_directory("fonts", "output/fonts")
107
113
  end
108
114
 
109
115
  # Export all root stylesheets.
110
116
  #
111
- def export_stylesheets!
117
+ private def export_stylesheets!
112
118
  Exporter::CSS.new(root_dir).export
113
119
  end
114
120
  end
@@ -1,11 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Kitabu
2
4
  class Exporter
3
5
  class Mobi < Base
4
6
  def export
5
- spawn_command ["kindlegen", epub_file.to_s]
7
+ spawn_command ["ebook-convert", epub_file.to_s, mobi_file.to_s]
6
8
  true
7
9
  end
8
10
 
11
+ def mobi_file
12
+ root_dir.join("output/#{name}.mobi")
13
+ end
14
+
9
15
  def epub_file
10
16
  root_dir.join("output/#{name}.epub")
11
17
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Kitabu
2
4
  class Exporter
3
5
  class PDF < Base
@@ -9,13 +11,17 @@ module Kitabu
9
11
 
10
12
  def apply_footnotes!
11
13
  html = Footnotes::PDF.process(html_file.read).html
12
- create_html_file(html_for_print, html, 'print')
13
- create_html_file(html_for_pdf, html, 'pdf')
14
+ create_html_file(html_for_print, html, "print")
15
+ create_html_file(html_for_pdf, html, "pdf")
14
16
  end
15
17
 
16
18
  def create_html_file(target, html, class_name)
17
19
  html.css("html").first.set_attribute "class", class_name
18
- html.css("link[name=stylesheet]").first.set_attribute "href", "styles/#{class_name}.css"
20
+ html
21
+ .css("link[name=stylesheet]")
22
+ .first
23
+ .set_attribute "href", "styles/#{class_name}.css"
24
+
19
25
  File.open(target, "w") {|f| f << html.to_html }
20
26
  end
21
27
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Kitabu
2
4
  class Exporter
3
5
  def self.run(root_dir, options)
@@ -5,8 +7,7 @@ module Kitabu
5
7
  exporter.export!
6
8
  end
7
9
 
8
- attr_accessor :root_dir
9
- attr_accessor :options
10
+ attr_accessor :root_dir, :options
10
11
 
11
12
  def initialize(root_dir, options)
12
13
  @root_dir = root_dir
@@ -26,37 +27,35 @@ module Kitabu
26
27
  export_pdf = [nil, "pdf"].include?(options[:only])
27
28
  export_epub = [nil, "mobi", "epub"].include?(options[:only])
28
29
  export_mobi = [nil, "mobi"].include?(options[:only])
29
- export_txt = [nil, "txt"].include?(options[:only])
30
30
 
31
31
  exported = []
32
32
  exported << HTML.export(root_dir)
33
33
  exported << PDF.export(root_dir) if export_pdf && Dependency.prince?
34
34
  exported << Epub.export(root_dir) if export_epub
35
- exported << Mobi.export(root_dir) if export_mobi && Dependency.kindlegen?
36
- exported << Txt.export(root_dir) if export_txt && Dependency.html2text?
35
+ exported << Mobi.export(root_dir) if export_mobi && Dependency.calibre?
37
36
 
38
37
  if exported.all?
39
38
  color = :green
40
- message = options[:auto] ? "exported!" : "** e-book has been exported"
39
+ message = options[:auto] ? "exported!" : "=> e-book has been exported"
41
40
 
42
41
  if options[:open] && export_pdf
43
42
  filepath = root_dir.join("output/#{File.basename(root_dir)}.pdf")
44
43
 
45
- if RUBY_PLATFORM =~ /darwin/
44
+ case RUBY_PLATFORM
45
+ when /darwin/
46
46
  IO.popen("open -a Preview.app '#{filepath}'").close
47
- elsif RUBY_PLATFORM =~ /linux/
48
- Process.detach(Process.spawn("xdg-open '#{filepath}'", :out => "/dev/null"))
47
+ when /linux/
48
+ Process.detach(Process.spawn("xdg-open '#{filepath}'",
49
+ out: "/dev/null"))
49
50
  end
50
51
  end
51
-
52
- Notifier.notify(
53
- :image => Kitabu::ROOT.join("templates/ebook.png").to_s,
54
- :title => "Kitabu",
55
- :message => "Your \"#{config[:title]}\" e-book has been exported!"
56
- )
57
52
  else
58
53
  color = :red
59
- message = options[:auto] ? "could not be exported!" : "** e-book couldn't be exported"
54
+ message = if options[:auto]
55
+ "could not be exported!"
56
+ else
57
+ "=> e-book couldn't be exported"
58
+ end
60
59
  end
61
60
 
62
61
  ui.say message, color
@@ -1,9 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rouge
2
4
  module Plugins
3
5
  module Redcarpet
4
6
  def rouge_formatter(lexer)
5
7
  options = lexer.respond_to?(:options) ? lexer.options : {}
6
- Formatters::HTMLLegacy.new({css_class: "highlight #{lexer.tag}"}.merge(options))
8
+
9
+ Formatters::HTMLLegacy.new(
10
+ {css_class: "highlight #{lexer.tag}"}.merge(options)
11
+ )
7
12
  end
8
13
  end
9
14
  end
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class String
2
4
  def to_permalink
3
- str = ActiveSupport::Multibyte::Chars.new(self.dup)
4
- str = str.normalize(:kd).gsub(/[^\x00-\x7F]/,'').to_s
5
- str.gsub!(/[^-\w\d]+/xim, "-")
5
+ str = dup.unicode_normalize(:nfkd)
6
+ str = str.gsub(/[^\x00-\x7F]/, "").to_s
7
+ str.gsub!(/[^-\w]+/xim, "-")
6
8
  str.gsub!(/-+/xm, "-")
7
9
  str.gsub!(/^-?(.*?)-?$/, '\1')
8
10
  str.downcase!
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Kitabu
2
4
  module Footnotes
3
5
  class Base
@@ -1,25 +1,28 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Kitabu
2
4
  module Footnotes
3
5
  class HTML < Base
4
6
  def process
5
- html.css('.chapter').each(&method(:process_chapter))
7
+ html.css(".chapter").each(&method(:process_chapter))
6
8
  end
7
9
 
8
10
  def process_chapter(chapter)
9
- footnotes = chapter.css('.footnotes').first
11
+ footnotes = chapter.css(".footnotes").first
10
12
  return unless footnotes
11
- list = footnotes.css('ol').first
12
- list.set_attribute 'start', footnote_index
13
13
 
14
- chapter.css('.footnotes li').each do |footnote|
14
+ list = footnotes.css("ol").first
15
+ list.set_attribute "start", footnote_index
16
+
17
+ chapter.css(".footnotes li").each do |footnote|
15
18
  process_footnote(chapter, footnote)
16
19
  increment_footnote_index!
17
20
  end
18
21
  end
19
22
 
20
23
  def process_footnote(chapter, footnote)
21
- current_index = footnote.get_attribute('id').gsub(/[^\d]/m, '')
22
- footnote.set_attribute 'id', "fn#{footnote_index}"
24
+ current_index = footnote.get_attribute("id").gsub(/[^\d]/m, "")
25
+ footnote.set_attribute "id", "fn#{footnote_index}"
23
26
 
24
27
  process_links_to_footnote(chapter, current_index)
25
28
  process_rev_links(chapter, current_index)
@@ -28,25 +31,27 @@ module Kitabu
28
31
 
29
32
  def process_links_to_footnote(chapter, current_index)
30
33
  chapter.css("a[href='#fn#{current_index}']").each do |link|
31
- link.set_attribute 'href', "#fn#{footnote_index}"
34
+ link.set_attribute "href", "#fn#{footnote_index}"
32
35
  end
33
36
  end
34
37
 
35
38
  def process_rev_links(chapter, current_index)
36
39
  chapter.css("a[href='#fnref#{current_index}']").each do |link|
37
- link.set_attribute 'href', "#fnref#{footnote_index}"
40
+ link.set_attribute "href", "#fnref#{footnote_index}"
38
41
  end
39
42
  end
40
43
 
41
44
  def process_ref_elements(chapter, current_index)
42
- chapter.css("sup[id=fnref#{current_index}]").each_with_index do |sup, index|
45
+ selector = "sup[id=fnref#{current_index}]"
46
+
47
+ chapter.css(selector).each_with_index do |sup, index|
43
48
  if index.zero?
44
- sup.set_attribute 'id', "fnref#{footnote_index}"
49
+ sup.set_attribute "id", "fnref#{footnote_index}"
45
50
  else
46
- sup.remove_attribute 'id'
51
+ sup.remove_attribute "id"
47
52
  end
48
53
 
49
- sup.css('a').first.content = footnote_index
54
+ sup.css("a").first.content = footnote_index
50
55
  end
51
56
  end
52
57
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Kitabu
2
4
  module Footnotes
3
5
  class PDF < Base
@@ -8,35 +10,39 @@ module Kitabu
8
10
 
9
11
  def remove_duplicated_attributes
10
12
  # https://github.com/sparklemotion/nokogiri/issues/339
11
- html.css('html').first.tap do |element|
13
+ html.css("html").first.tap do |element|
12
14
  next unless element
13
- element.delete('xmlns')
14
- element.delete('xml:lang')
15
+
16
+ element.delete("xmlns")
17
+ element.delete("xml:lang")
15
18
  end
16
19
  end
17
20
 
18
21
  def process_chapter(chapter)
19
- chapter.css('.footnotes li').each do |footnote|
22
+ chapter.css(".footnotes li").each do |footnote|
20
23
  process_footnote(chapter, footnote)
21
24
  increment_footnote_index!
22
25
  end
23
26
 
24
- chapter.css('.footnotes').each(&:remove)
27
+ chapter.css(".footnotes").each(&:remove)
25
28
  end
26
29
 
27
30
  def process_footnote(chapter, footnote)
28
31
  # Remove rev links
29
- footnote.css('[rev=footnote]').map(&:remove)
32
+ footnote.css("[rev=footnote]").map(&:remove)
30
33
 
31
34
  # Create an element for storing the footnote description
32
- description = Nokogiri::XML::Node.new('span', Nokogiri::HTML::DocumentFragment.parse(''))
33
- description.set_attribute 'class', 'footnote'
34
- description.inner_html = footnote.css('p').map(&:inner_html).join("\n")
35
+ description = Nokogiri::XML::Node.new(
36
+ "span",
37
+ Nokogiri::HTML::DocumentFragment.parse("")
38
+ )
39
+ description.set_attribute "class", "footnote"
40
+ description.inner_html = footnote.css("p").map(&:inner_html).join("\n")
35
41
 
36
42
  # Find ref based on footnote's id
37
- fn_id = footnote.get_attribute('id')
43
+ fn_id = footnote.get_attribute("id")
38
44
 
39
- refs = chapter.css("a[href='##{fn_id}']").each do |ref|
45
+ chapter.css("a[href='##{fn_id}']").each do |ref|
40
46
  sup = ref.parent
41
47
  sup.after(description)
42
48
  sup.remove
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Kitabu
2
4
  # The Kitabu::Generator class will create a new book structure.
3
5
  #
@@ -11,7 +13,7 @@ module Kitabu
11
13
  desc "Generate a new e-Book structure"
12
14
 
13
15
  def self.source_root
14
- File.dirname(__FILE__) + "/../../templates"
16
+ "#{File.dirname(__FILE__)}/../../templates"
15
17
  end
16
18
 
17
19
  def copy_templates
@@ -64,13 +66,16 @@ module Kitabu
64
66
  end
65
67
  end
66
68
 
67
- private
68
- # Retrieve user's name using finger.
69
- # Defaults to <tt>John Doe</tt>.
70
- #
71
- def full_name
72
- name = `finger $USER 2> /dev/null | grep Login | colrm 1 46 2> /dev/null`.chomp
73
- name.present? ? name.squish : "John Doe"
69
+ no_commands do
70
+ # Retrieve user's name using finger.
71
+ # Defaults to <tt>John Doe</tt>.
72
+ #
73
+ def full_name
74
+ name =
75
+ `finger $USER 2> /dev/null | grep Login | colrm 1 46 2> /dev/null`
76
+ .chomp
77
+ name.present? ? name.squish : "John Doe"
78
+ end
74
79
  end
75
80
  end
76
81
  end
@@ -1,14 +1,16 @@
1
+ # frozen_string_literal: false
2
+
1
3
  module Kitabu
2
4
  module Helpers
3
5
  def highlight_theme(name = theme)
4
6
  html = '<style type="text/css">'
5
- html << Rouge::Theme.find(name).render(scope: '.highlight')
6
- html << '</style>'
7
+ html << Rouge::Theme.find(name).render(scope: ".highlight")
8
+ html << "</style>"
7
9
  html
8
10
  end
9
11
 
10
- def image_tag(path, attributes = {})
11
- html = %[<img src="images/#{path}" />]
12
+ def image_tag(path, _attributes = {})
13
+ %[<img src="images/#{path}" />]
12
14
  end
13
15
 
14
16
  def escape_html(content)
@@ -17,19 +19,20 @@ module Kitabu
17
19
 
18
20
  def note(class_name = :info, &block)
19
21
  content = block_content(block)
20
- output << '<div class="note %s">' % escape_html(class_name)
22
+ output << ('<div class="note %s">' % escape_html(class_name)) # rubocop:disable Style/FormatString
21
23
  output << markdown(content)
22
- output << '</div>'
24
+ output << "</div>"
23
25
  end
24
26
 
25
27
  def block_content(block)
26
- output, @_output = @_output.dup, ''
28
+ output = @_output.dup
29
+ @_output = ""
27
30
  content = block.call
28
31
  @_output = output
29
32
  content
30
33
  end
31
34
 
32
- def markdown(content, deindent_content = true)
35
+ def markdown(content, deindent_content: true)
33
36
  content = deindent(content) if deindent_content
34
37
  Markdown.render(content)
35
38
  end
@@ -37,7 +40,7 @@ module Kitabu
37
40
  def deindent(content)
38
41
  content = content.to_s
39
42
  indent = (content.scan(/^[ \t]*(?=\S)/) || []).size
40
- content.gsub(/^[ \t]{#{indent}}/, '')
43
+ content.gsub(/^[ \t]{#{indent}}/, "")
41
44
  end
42
45
 
43
46
  def output
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Kitabu
2
4
  module Markdown
3
5
  class Renderer < Redcarpet::Render::HTML
@@ -13,16 +15,16 @@ module Kitabu
13
15
  renderer = Renderer.new(hard_wrap: true, safe_links_only: true)
14
16
 
15
17
  self.processor = Redcarpet::Markdown.new(renderer, {
16
- tables: true,
17
- footnotes: true,
18
- space_after_headers: true,
19
- superscript: true,
20
- highlight: true,
21
- strikethrough: true,
22
- autolink: true,
23
- fenced_code_blocks: true,
24
- no_intra_emphasis: true
25
- })
18
+ tables: true,
19
+ footnotes: true,
20
+ space_after_headers: true,
21
+ superscript: true,
22
+ highlight: true,
23
+ strikethrough: true,
24
+ autolink: true,
25
+ fenced_code_blocks: true,
26
+ no_intra_emphasis: true
27
+ })
26
28
 
27
29
  def self.render(text)
28
30
  processor.render(text)