jekyll-latex-pdf 0.4.2 → 0.5.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.
data/bin/setup CHANGED
@@ -1,7 +1,9 @@
1
1
  #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
2
+ # frozen_string_literal: true
3
+
4
+ # set -euo pipefail
5
+ # IFS=$'\n\t'
6
+ # set -vx
5
7
 
6
8
  bundle install
7
9
 
@@ -29,7 +29,9 @@ enclang = {
29
29
 
30
30
  \usepackage{amsmath}
31
31
  \usepackage{graphicx}
32
- \usepackage[colorinlistoftodos]{todonotes}
32
+ %\usepackage[colorinlistoftodos]{todonotes}
33
+ \usepackage{tikz}
34
+
33
35
 
34
36
  \usepackage{hyperref}
35
37
  \hypersetup{
@@ -64,6 +66,10 @@ urlcolor=black
64
66
  <% if data[:note] %>\note{<%= data[:note] %>}<% end %>
65
67
  <% if data[:authornote] %>\authornote{<%= data[:authornote] %>}<% end %>
66
68
  <% if data[:keywords] %>\keywords{<%= data[:keywords] %>}<% end %>
69
+ <% if data[:journal] %>\journal{<%= data[:journal] %>}<% end %>
70
+ <% if data[:volume] %>\volume{<%= data[:volume] %>}<% end %>
71
+ <% if data[:ccoppy] %>\ccoppy{<%= data[:ccoppy] %>}<% end %>
72
+ <% if data[:copnum] %>\copnum{<%= data[:copnum] %>}<% end %>
67
73
 
68
74
  \begin{document}
69
75
  <% if data[:title] %>
@@ -37,6 +37,7 @@ enclang = {
37
37
  \usepackage{listings}
38
38
  <% @converter.data[:packages].each {|pkg| %>\usepackage{<%= pkg %>}
39
39
  <% } %>
40
+ \usepackage{tikz}
40
41
  \usepackage{hyperref}
41
42
 
42
43
  <% if data[:lang] %>
@@ -29,6 +29,9 @@ Gem::Specification.new do |spec|
29
29
  spec.add_development_dependency "rake", "~> 10.0"
30
30
  spec.add_development_dependency "rubocop", "~> 0.67"
31
31
  spec.add_development_dependency "jekyll-scholar", "~> 5.14.1"
32
+ #spec.add_development_dependency "minitest", "~> 5.0.0"
33
+ #spec.add_development_dependency "rouge"
34
+ #spec.add_development_dependency "stringex", "~> 1.5.1"
32
35
 
33
36
  spec.add_runtime_dependency "jekyll", "~> 3.8.5"
34
37
  spec.add_runtime_dependency "kramdown", "~> 1.17"
@@ -1,15 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "jekyll/latex/pdf/options"
3
+ require "jekyll/latex/pdf/defaults"
4
+ require "jekyll/latex/pdf/kramdown_data"
4
5
  require "jekyll/latex/pdf/utilities"
5
6
  require "jekyll/latex/pdf/liquid"
6
7
 
7
- # having jekyll-scholar installed?
8
- if Jekyll.configuration({})["plugins"].include? "jekyll-scholar"
9
- require "jekyll/scholar"
8
+ if Jekyll::External.require_if_present "jekyll/scholar"
10
9
  require "jekyll/latex/pdf/scholar"
11
10
  end
12
11
 
12
+ if Jekyll::External.require_if_present "jekyll/figure"
13
+ require "jekyll/latex/pdf/figure"
14
+ end
15
+
16
+ require "jekyll/latex/pdf/tikz"
17
+
13
18
  require "jekyll/latex/pdf/latex"
14
19
  require "jekyll/latex/pdf/document"
15
20
  require "jekyll/latex/pdf/generator"
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ module Latex
5
+ # Default values for configuration.
6
+ module Pdf
7
+ class Defaults
8
+
9
+ # Defaults
10
+ @defaults = {
11
+
12
+ # Engine to render latex to pdf.
13
+ "pdf_engine" => "lualatex",
14
+
15
+ # Default binary to handle bibtex files. Using biblatex for default.
16
+ "bib_engine" => "biber",
17
+
18
+ # Default template to use
19
+ "template" => "jekyll-latex-pdf",
20
+
21
+ # Template path under site
22
+ "template_path" => "_latex",
23
+
24
+ # Use the date in the \note command instead of the \date. Usefull for apa6
25
+ "date_as_note" => false,
26
+
27
+ # Set the path where the rendered svg files should be stored.
28
+ "tikz_path" => "assets/tikz",
29
+ }
30
+ class << self
31
+
32
+ def prepare_defaults
33
+ @defaults["default_template_path"] = File.expand_path(File.join(File.dirname(__FILE__),
34
+ "..", "..", "..", "..",
35
+ "data", "kramdown"))
36
+ end
37
+
38
+ def defaults
39
+ prepare_defaults
40
+ @defaults
41
+ end
42
+
43
+ end
44
+
45
+ end
46
+ end
47
+ end
48
+ end
@@ -8,6 +8,7 @@ module Jekyll
8
8
  module Pdf
9
9
  # The document adds the file.
10
10
  class Document < Jekyll::Page
11
+
11
12
  attr_accessor :source
12
13
 
13
14
  def initialize(site, page)
@@ -16,7 +17,7 @@ module Jekyll
16
17
  @dir = File.dirname(page.url)
17
18
  @name = File.basename(page.url, File.extname(page.url)) + ".pdf"
18
19
  @texname = File.basename(page.url, File.extname(page.url)) + ".tex"
19
- @settings = site.config.key?("pdf") ? site.config["pdf"].clone : {}
20
+ # @settings = site.config["pdf"] ? site.config["pdf"].clone : {}
20
21
 
21
22
  process(@name)
22
23
 
@@ -27,34 +28,51 @@ module Jekyll
27
28
  # data["layout"] = layout
28
29
  data["html_url"] = page.url
29
30
  data["date_str"] = data["date"].strftime("%Y-%m-%d")
30
- @options = Options.new @settings
31
- @options.add_data data
31
+ @config = Defaults.defaults.merge(site.config["pdf"] || {})
32
+
33
+ @kramdowndata = KramdownData.new data
34
+ @kramdowndata.add(site.config["pdf"] || {})
32
35
 
33
36
  check_scholar
34
37
  end
35
38
 
36
39
  def check_scholar
37
- if Jekyll.configuration({})["plugins"].include? "jekyll-scholar"
38
- (class <<self; include Jekyll::Scholar::Utilities; end)
40
+ if @site.config["plugins"].include? "jekyll-scholar"
41
+ # (class <<self; include Jekyll::Scholar::Utilities; end)
39
42
  # getting bibtex files
40
- @config = Jekyll::Scholar.defaults.dup
41
- @options.add_data(:bibtex_files => bibtex_files.map { |bibfile| File.join(config["source"], bibfile) })
43
+ # @config = Jekyll::Scholar.defaults.dup
44
+ # config = @site.config["scholar"]
45
+ @kramdowndata.add(bibtex_files: bibtex_files.map do |bibfile|
46
+ File.join(@site.config["scholar"]["source"], bibfile)
47
+ end)
42
48
  end
43
49
  end
44
50
 
45
51
  def permalink
46
- data.key? "permalink" ? nil : (data["permalink"] + ext)
52
+ data.key?("permalink") ? (data["permalink"] + ext) : nil
47
53
  end
48
54
 
49
55
  def write(dest)
50
56
  path = File.join(dest, CGI.unescape(url))
51
57
 
52
- latex = Latex.new(source, @site, @options)
53
- if latex.compile == 0
58
+ latex = Latex.new(source, @site, @kramdowndata, @name)
59
+ if 0 == latex.compile
54
60
  FileUtils.cp(latex.pdf_file, path)
55
61
  Jekyll.logger.debug "cp " + latex.pdf_file.to_s + " " + path.to_s
56
62
  end
57
63
  end
64
+
65
+ def bibtex_files
66
+ if @site.config["scholar"]['bibliography'].include? '*'
67
+ @bibtex_files ||= Dir.glob(File.join(@site.config["scholar"]["source"],
68
+ @site.config["scholar"]["bibliography"])).
69
+ collect do |f|
70
+ Pathname(f).relative_path_from(Pathname(@site.config["scholar"]['source'])).to_s
71
+ end
72
+ end
73
+ @bibtex_files ||= [@site.config["scholar"]['bibliography']]
74
+ end
75
+
58
76
  end
59
77
  end
60
78
  end
@@ -0,0 +1,2 @@
1
+ # frozen_string_literal: true
2
+ require "jekyll/latex/pdf/figure/figure"
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ module Latex
5
+ # This module generates pdf files using latex (must be installed on the system) and
6
+ # should be highly configurable.
7
+ module Pdf
8
+ ## here we add support for jekyll-scholar, a great module for scientific writing.
9
+ module Figure
10
+ # Overrides the Figure tag from jekyll-figure
11
+ class FigureTag < Liquid::Block
12
+
13
+ include Utilities
14
+
15
+ def initialize(tag_name, markup, tokens)
16
+ @markup = markup
17
+ super
18
+ end
19
+
20
+ def render(context)
21
+ # Render any liquid variables
22
+ markup = Liquid::Template.parse(@markup).render(context)
23
+
24
+ # Extract tag attributes
25
+ attributes = {}
26
+ markup.scan(Liquid::TagAttributes) do |key, value|
27
+ attributes[key] = value
28
+ end
29
+
30
+ @caption = attributes["caption"] if attributes.include? "caption"
31
+ @label = attributes["label"] if attributes.include? "label"
32
+
33
+ # Caption: convert markdown and remove paragraphs
34
+ unless @caption.nil?
35
+ figure_caption = @caption.gsub!(/\A"|"\Z/, "")
36
+ # figure_caption = converter.convert(figure_caption).gsub(/<\/?p[^>]*>/, "").chomp
37
+ # figure_caption = " <figcaption>#{figure_caption}</figcaption>\n"
38
+ figure_caption = Kramdown::Document.new(figure_caption).to_latex.strip
39
+ figure_caption = "\\caption{#{figure_caption}}\n"
40
+ end
41
+
42
+ figure_main = super context
43
+
44
+ # render figure
45
+ figure_latex = nomarkdown_p "\\begin{figure}"
46
+ figure_latex += nomarkdown_p "\\centering"
47
+ figure_latex += figure_main.to_s
48
+ figure_latex += nomarkdown_p figure_caption.to_s
49
+ figure_latex += nomarkdown_p "\\label{#{@label}}" unless @label.nil?
50
+ figure_latex + nomarkdown_p("\\end{figure}")
51
+ end
52
+
53
+ end
54
+ end
55
+ TempLiquid.register_tag("figure", Figure::FigureTag)
56
+ end
57
+ end
58
+ end
@@ -2,16 +2,28 @@
2
2
 
3
3
  module Jekyll
4
4
  module Latex
5
+ # This module generates pdf files using latex (must be installed on the system) and
6
+ # should be highly configurable.
5
7
  module Pdf
8
+ # The generator acutally generates pdf files for posts with `pdf: true` in the yaml header.
6
9
  class Generator < Jekyll::Generator
10
+
7
11
  safe true
8
12
  priority :lowest
9
13
 
14
+ attr_reader :config
15
+
10
16
  def generate(site)
11
- site.posts.docs.each do |post|
12
- site.pages << Document.new(site, post) if post.data["pdf"]
17
+ @site, @config = site, Defaults.defaults.merge(site.config["pdf"] || {})
18
+
19
+ @site.config["pdf"].merge! @config
20
+ @site.config["exclude"].concat [".latex-cache" + File::SEPARATOR, ".tikz-cache" + File::SEPARATOR]
21
+
22
+ @site.posts.docs.each do |post|
23
+ @site.pages << Document.new(@site, post) if post.data["pdf"]
13
24
  end
14
25
  end
26
+
15
27
  end
16
28
  end
17
29
  end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ module Latex
5
+ module Pdf
6
+
7
+ # Hold data for kramdown renderer. We have some extra things added to the
8
+ # default post content.
9
+ class KramdownData
10
+
11
+ def initialize(*args)
12
+ add(*args)
13
+ end
14
+
15
+ def add(*args)
16
+ @data ||= {}
17
+ @data.merge! hash_args(*args)
18
+ end
19
+
20
+ attr_reader :data
21
+
22
+ private
23
+
24
+ def hash_args(*args)
25
+ hashed_args = args.detect {|f| f.class == Hash }
26
+ hashed_args.each_with_object({}) {|(k, v), memo| memo[k.to_sym] = v; }
27
+ end
28
+
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,67 +1,91 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "tmpdir"
4
3
  require "open3"
5
- # require 'fileutils'
6
4
 
7
5
  module Jekyll
8
6
  module Latex
9
7
  module Pdf
10
8
  # The Latex Class will create the tex file and compile it to the pdf file.
11
9
  class Latex < Jekyll::Document
10
+
11
+ include Utilities
12
+
12
13
  attr_accessor :source, :latex
13
14
  attr_reader :pdf_file
14
- def initialize(source, site, options)
15
- @options = options
16
- @engine = @options.options[:pdf_engine]
17
- @bibengine = @options.options[:bib_engine]
15
+ def initialize(source, site, data, name)
16
+ # @options = options
17
+ @kramdowndata = data
18
18
  @site = site
19
+ @name = name
20
+ @engine = @site.config["pdf"]["pdf_engine"] # @options.options[:pdf_engine]
21
+ @bibengine = @site.config["pdf"]["bib_engine"] # @options.options[:bib_engine]
19
22
 
20
23
  @source = source
21
24
  end
22
25
 
26
+ def find_template
27
+ template = @site.config["pdf"]["template"]
28
+
29
+ template.concat(".latex") unless template.end_with?(".latex")
30
+
31
+ t = File.expand_path(File.join(@site.config["pdf"]["template_path"], template))
32
+ if File.file? t
33
+ return t
34
+ else
35
+ t = File.expand_path(File.join(@site.config["pdf"]["default_template_path"], template))
36
+ if File.file? t
37
+ return t
38
+ else
39
+ Jekyll.warn "jekyll-latex-pdf", "Could not find template #{t}."
40
+ end
41
+ end
42
+ end
43
+
23
44
  def prepare_latex
24
45
  TempLiquid.run do
25
- liquid_parsed = Liquid::Template.parse(@source, :error_mode => :strict)
46
+ liquid_parsed = Liquid::Template.parse(@source, error_mode: :strict)
26
47
  unless liquid_parsed.errors.empty?
27
48
  Jekyll.logger.warn("Liquid parse errors", liquid_parsed.errors.join(", "))
28
49
  end
29
- prep_latex = liquid_parsed.render(:strict_filters => true,
30
- :strict_variables => true)
50
+ prep_latex = liquid_parsed.render(strict_filters: true,
51
+ strict_variables: true)
31
52
  unless liquid_parsed.errors.empty?
32
- Jekyll.logger.warn("Liquid render errors", liquid_parsed.errors.join(", "))
53
+ Jekyll.logger.warn liquid_parsed.errors.join ", "
33
54
  end
34
- @latex = Kramdown::Document
35
- .new(prep_latex, @options.options)
36
- .to_latex
55
+ options = {"data" => @kramdowndata.data,
56
+ "template" => find_template}
57
+ @latex = Kramdown::Document.
58
+ new(prep_latex, options).
59
+ to_latex
37
60
  end
38
61
  end
39
62
 
40
63
  def prepare_abstract
41
64
  # only when excerpt is present
42
- unless @options.data.key? :abstract
65
+ unless @kramdowndata.data.key? :abstract
43
66
  Jekyll.logger.debug "Abstract missing. This may be ok for your latex template."
44
- if @options.data.key? :excerpt
67
+ if @kramdowndata.data.key? :excerpt
45
68
  Jekyll.logger.debug "Trying to get the abstract from the excerpt."
46
69
  abstract, _, @source = @source.to_s.partition(excerpt_separator)
47
- @options.add_data(:abstract => Kramdown::Document.new(abstract).to_latex)
70
+ @kramdowndata.add(abstract: Kramdown::Document.new(abstract).to_latex)
48
71
  end
49
- end
72
+ end
50
73
  end
51
74
 
52
75
  def prepare_date_as_note
53
- @options.add_data(:note => "\\printdate{#{@options.data[:date_str]}}")
76
+ @kramdowndata.add(note: "\\printdate{#{@kramdowndata.data[:date_str]}}")
54
77
  end
55
78
 
56
79
  def prepare
57
80
  prepare_abstract
58
- prepare_date_as_note if @options[:date_as_note]
81
+ prepare_date_as_note if @site.config["pdf"]["date_as_note"]
59
82
  prepare_latex
60
83
 
61
- @tempdir = Dir.mktmpdir("jekyll-latex-pdf")
62
- @latexfile = "texput.tex" # File.join(@tempdir, "texput.tex")
84
+ basename = File.basename(@name, ".*")
85
+ @tempdir = File.join(Dir.pwd, ".latex-cache", basename)
86
+ FileUtils.mkdir_p @tempdir
87
+ @latexfile = basename + ".tex"
63
88
 
64
- # puts "writing to #{@latexfile}:", latex
65
89
  File.open(File.join(@tempdir, @latexfile), "w:UTF-8") do |f|
66
90
  f.write(latex)
67
91
  end
@@ -70,25 +94,30 @@ module Jekyll
70
94
  end
71
95
 
72
96
  def add_bibliography
73
- if @options.data.key? :bibtex_files
74
- @options.data[:bibtex_files].each do |bibfile|
75
- bibpath = File.join(@tempdir, File.dirname(bibfile))
76
- FileUtils.mkdir_p bibpath unless File.directory? bibpath
77
- FileUtils.cp(bibfile, bibpath)
97
+ if @kramdowndata.data.key? :bibtex_files
98
+ @kramdowndata.data[:bibtex_files].each do |bibfile|
99
+ bib_target = File.join(@tempdir, bibfile)
100
+ if File.exist?(bib_target)
101
+ unless FileUtils.compare_file(bibfile, bib_target)
102
+ FileUtils.cp(bibfile, bib_target)
103
+ end
104
+ else
105
+ FileUtils.mkdir_p File.dirname(bib_target)
106
+ FileUtils.cp(bibfile, bib_target)
107
+ end
78
108
  end
79
109
  end
80
110
  end
81
111
 
82
112
  def prepare_cmds
83
- cmds = [[@options.options[:pdf_engine],
84
- # "--output-directory=#{@tempdir}",
113
+ cmds = [[@site.config["pdf"]["pdf_engine"],
85
114
  "--output-format=pdf",
86
115
  "--interaction=batchmode",
87
- @latexfile,]]
116
+ @latexfile]]
88
117
  # biber if bibfiles given
89
- if @options.data.key? :bibtex_files
90
- cmds << [@options.options[:bib_engine],
91
- File.basename(@latexfile, File.extname(@latexfile)),]
118
+ if @kramdowndata.data.key? :bibtex_files
119
+ cmds << [@site.config["pdf"]["bib_engine"],
120
+ File.basename(@latexfile, File.extname(@latexfile))]
92
121
  cmds << cmds[0]
93
122
  end
94
123
  cmds
@@ -98,29 +127,23 @@ module Jekyll
98
127
  prepare
99
128
  cmds = prepare_cmds
100
129
 
101
- Jekyll.logger.info "jekyll-latex-pdf", "compiling in tempdir: #{@tempdir}"
130
+ Jekyll.logger.debug "jekyll-latex-pdf", "compiling in tempdir: #{@tempdir}"
102
131
 
103
- status = 0
104
- out = "\n"
105
- cmds.each do |cmd|
106
- Open3.popen2(*cmd, :chdir => @tempdir) do |_i, oe, t|
107
- oe.each { |l| out += l + "\n" }
108
- status = t.value
109
- end
110
- end
132
+ out, status = run_cmds cmds, @tempdir
111
133
 
112
- # puts stdout_str
113
- if status == 0
114
- @pdf_file = File.join(@tempdir, "texput.pdf")
134
+ if 0 == status
135
+ @pdf_file = File.join(@tempdir, File.basename(@latexfile, ".*") + ".pdf")
115
136
  else
116
- # puts stdout_str
117
- Jekyll.logger.error "jekyll-latex-pdf", "Error when trying to run #{@options.options[:pdf_engine]}."
137
+ Jekyll.logger.error "jekyll-latex-pdf",
138
+ "Error when trying to run #{@site.config['pdf']['pdf_engine']}."
118
139
  Jekyll.logger.error "jekyll-latex-pdf", "status: #{status}"
119
- Jekyll.logger.error "jekyll-latex-pdf", "output: #{out}"
120
- Jekyll.logger.error "jekyll-latex-pdf", "See #{@tempdir}/texput.log"
140
+ Jekyll.logger.error "jekyll-latex-pdf",
141
+ "Hint: Try to run #{site.config['pdf']['pdf_engine']} \
142
+ inside #{@tempdir} by hand."
121
143
  end
122
144
  status
123
145
  end
146
+
124
147
  end
125
148
  end
126
149
  end