Module: Mdown2PDF

Extended by:
Mdown2PDF
Included in:
Mdown2PDF
Defined in:
lib/mdown2pdf.rb,
lib/mdown2pdf/render.rb,
lib/mdown2pdf/version.rb,
lib/mdown2pdf/pseudo_code_lexer.rb

Defined Under Namespace

Classes: PseudoCodeLexer, Render

Constant Summary collapse

VERSION =
"0.1.0"

Instance Method Summary collapse

Instance Method Details

#asset(name) ⇒ Object

Returns an absolute path for a given asset.



109
110
111
# File 'lib/mdown2pdf.rb', line 109

def asset(name)
  File.expand_path(File.join(__dir__, '..', 'assets', name))
end

#html_for(markdown) ⇒ Object

Converts a given Markdown string to HTML.



96
97
98
99
100
101
102
103
104
105
106
# File 'lib/mdown2pdf.rb', line 96

def html_for(markdown)
  parser = Redcarpet::Markdown.new(Render, {
    fenced_code_blocks: true,
    tables:             true,
    superscript:        true,
    strikethrough:      true,
    autolink:           true
  })

  parser.render(markdown)
end

#markdown_for(file) ⇒ Object

Converts a given Markdown file to an HTML document. The underlying implementation uses Redcarpet but you should check out the Render class for further information.



91
92
93
# File 'lib/mdown2pdf.rb', line 91

def markdown_for(file)
  html_for(File.read(file))
end

#output(file:, name:, cover: nil, toc: false) ⇒ Object

Actually outputs a given HTML file as a PDF for a given name through the ‘wkhtmltopdf` command line tool.

- The given `:file` key represents the HTML file to translate
  to PDF.
- `:name` will be used to infer the PDF file's name.
- `:cover` can be used if a document should be used as a cover.
- `:toc` specifies whether a table of contents should be generated
   or not for the document.


66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/mdown2pdf.rb', line 66

def output(file: , name: , cover: nil, toc: false)
  stylesheet = ["--user-style-sheet", asset('style.css')]
  arguments  = ["wkhtmltopdf"]

  if cover
    arguments.push("cover", cover)
    arguments.push(*stylesheet)
  end

  arguments.push("toc", "--xsl-style-sheet", asset("toc.xsl")) if toc

  arguments.push(
    file,
    "--include-in-outline",
    "--enable-internal-links",
    *stylesheet,
    name.sub(/.(md|mdwon)/, '.pdf')
  )

  `#{arguments.join(" ")}`
end

#temporary_html_files_for(file) ⇒ Object

Creates two temporary files:

* One to represent the eventual cover of the PDF file.
* One with the document translated to HTML.

These two temporary files will be used by Wkhtmltopdf to generate the final PDF file.

This method requires a block that will yield a path for each file. For example:

temporary_files_for("a_file.md") do |output, cover|
  # Here `output` and `cover` are paths.
end

To distinguish the cover from the rest of the document, the user must put an h-rule inside their document and the first one will be used as a separator.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/mdown2pdf.rb', line 26

def temporary_html_files_for(file)
  seed        = (rand * 100).round
  output_file = "/tmp/output-#{seed}.html"
  cover_file  = "/tmp/cover-#{seed}.html"

  document = markdown_for(file)
  first_hr = document.index('<hr>')

  if first_hr
    cover    = document[0...first_hr]
    document = document[first_hr+4..-1]
  end

  File.open(output_file, "w") do |f|
    f.write(File.read(asset('output.html')) % { content: document })
  end

  if cover
    File.open(cover_file, "w") do |f|
      f.write(File.read(asset('output.html')) % { content: cover })
    end

    yield(output_file, cover_file)
  else
    yield(output_file, nil)
  end
ensure
  File.delete(output_file)
  File.delete(cover_file) if File.exist?(cover_file)
end