make_pdf-jekyll 0.0.3 → 0.0.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1d09dc6c6f9822fd4b47f10deded424f1cbe2f7766de5fc928ff3a9dd6a6469b
4
- data.tar.gz: 06c2c69b10b75f5034629c315a376cd7c47f3606df2f77fb2f3405cbec12d092
3
+ metadata.gz: b5ca4768cc346d06fd2b534d43a33232e50ba7054da2974ca89bf53d87eb052f
4
+ data.tar.gz: e5fa0a4c6aa2affb970cbd9e950d0af1b359ed60caadad94874924e3c716f88f
5
5
  SHA512:
6
- metadata.gz: 862703fcd0e8f7d88ec5a2e25ed96b3ad9b96411556863656d5f3b367d8de08d87ccfe51ca9e38918d1a0d3fb4d66dac69d8c5cd2917c461cbf8492ed8f4fa23
7
- data.tar.gz: de78393e5aed6ae9543b6f9ea799675a795ee65c4472802f8e9602277e373173900bf8376841526c269812f7fbc5e1839af70e40579140f3289819f011e95eb2
6
+ metadata.gz: 80ef0cd96743d8ec50fd55de00716963e80bf1c9842d4c1578131c9a685758dcc235280555f218d8022780c090768201623fdcc3aa743a7b1d68eeb4941de6c6
7
+ data.tar.gz: a0a030c29b3fb29fbf6a42b8c63067eb8af4d5540518431fd41097726d23ffa6d7acbf530eb2a2c11d3c7356b239efcb5385e16511f8557f0c2d8782c459f173
@@ -23,16 +23,16 @@ module MakePDF
23
23
  "animation-time-budget": nil,
24
24
  }
25
25
 
26
- def initialize(source_url, output_dir, **options)
27
- super(source_url, output_dir, command: COMMAND, **options.merge(DEFAULT_OPTIONS))
26
+ def initialize(**options)
27
+ super(command: COMMAND, **options.merge(DEFAULT_OPTIONS))
28
28
  end
29
29
 
30
- def map_key(key, value)
30
+ def map_option_key(key, value)
31
31
  case key
32
- when 'source_url'
33
- [ "--url", value ]
34
- when 'output_filename'
35
- [ "--pdf", value ]
32
+ when 'source-url'
33
+ [ '--url', value ]
34
+ when 'output-filename'
35
+ [ '--pdf', value ]
36
36
  when DEFAULT_OPTIONS.keys.method(:include?)
37
37
  case value
38
38
  when false, nil?
@@ -8,11 +8,14 @@ module MakePDF
8
8
  attr_reader :base
9
9
 
10
10
  def make_arguments(*options, **more)
11
- [ options, more.map do |key, value|
12
- map_key(key.to_s, value)
13
- end ].flatten.map do |arg|
14
- arg.to_s
15
- end
11
+ [
12
+ options.map { |val| val.to_s },
13
+ more
14
+ .transform_keys { |key| key.to_s.gsub('_','-') }
15
+ .filter_map do |key, value|
16
+ map_option_key(key, value.to_s)
17
+ end
18
+ ].flatten
16
19
  end
17
20
  end
18
21
 
@@ -24,13 +27,12 @@ module MakePDF
24
27
  '--'
25
28
  end
26
29
 
27
- def initialize(url, output_dir, command: COMMAND, **options)
28
- super(url, output_dir, **options)
30
+ def initialize(command: COMMAND, **options)
31
+ super(**options)
29
32
  @command = command
30
- @options = options
31
33
  end
32
34
 
33
- def write(source_url, output_filename, base_path:, **options)
35
+ def write(source_url, output_filename, **options)
34
36
  logger.info("converting #{source_url} with #{@command}")
35
37
  arguments = make_arguments(
36
38
  command: @command,
@@ -47,11 +49,14 @@ module MakePDF
47
49
  logger.info("pdf-writer: Wrote #{output_filename}")
48
50
  end
49
51
 
50
- def output_for(file, base_path:, version: [], **options)
52
+ def output_for(file, output_base_path: ".", version: [], **options)
53
+ output_base_path = Pathname.new(output_base_path)
54
+ file = Pathname.new(file)
55
+
51
56
  if @output_dir.nil?
52
- path = File.dirname(file)
57
+ path = output_base_path / file.dirname
53
58
  else
54
- path = File.expand_path(relative_path(file, base_path), @output)
59
+ path = File.expand_path(relative_path(file, output_base_path), @output_dir)
55
60
  end
56
61
 
57
62
  FileUtils.mkdir_p path
@@ -1,114 +1,160 @@
1
1
  require 'jekyll'
2
2
  require 'make_pdf'
3
+ require 'path_of'
3
4
 
4
5
  module MakePDF
5
-
6
6
  LOG_NAME = "make_pdf:"
7
+
7
8
  # MakePDF Jekyll plugin
8
9
  class Jekyll
10
+ attr_reader :reason
9
11
 
10
- class Logger
12
+ def valid?
13
+ @reason.nil?
14
+ end
11
15
 
12
- def initialize(logger)
13
- @logger = logger
14
- end
16
+ def check_failure(condition, message)
17
+ @reason = message if condition
18
+ condition
19
+ end
15
20
 
16
- def message(*args, **options)
17
- @logger.message(LOG_NAME, *args, **options)
18
- end
21
+ def filter_options(document, **options)
22
+ document.data.filter_map do |key, value|
23
+ key = key.to_s
24
+ if key == "make-pdf"
25
+ possible = {
26
+ "" => true,
27
+ "true" => true,
28
+ "yes" => true,
29
+ "false" => false,
30
+ "no" => false
31
+ }
32
+
33
+ [ key, possible[value.downcase] ]
34
+ else
35
+ [ key.sub("make-pdf-", "").to_sym, value ] if key.start_with?("make-pdf-")
36
+ end
37
+ end.to_h.merge(options)
38
+ end
19
39
 
20
- def warn(*args, **options)
21
- @logger.warn(LOG_NAME, *args, **options)
22
- end
40
+ def initialize(current_doc, **options)
41
+ @file = current_doc.destination(@base_source)
42
+ @options = filter_options(current_doc, **options)
43
+ splited_url = site.config["url"].match(Regexp.new("^\(.*\)://\([^/]+\)/?.*$")).to_a
44
+ @options[:input_base_url] ||= site.baseurl
45
+ @options[:input_host] ||= splited_url[2]
46
+ logger.debug("base_paths: input → #{@options[:input_base_url]} output → #{@options[:output_base_path]} host → #{@options[:input_host]}")
23
47
 
24
- def info(*args, **options)
25
- @logger.info(LOG_NAME, *args, **options)
26
- end
48
+ current_options = make_options(@options, site_options, filter_options(current_doc))
49
+ output_dir = @options[:output_dir] || path_of(site.dest).dirname
50
+
51
+ logger.debug("options : #{current_options}")
52
+
53
+ return if check_failure(File.extname(@file) != '.html', "#{@file} is not an html")
54
+ return if check_failure(current_options[:make_pdf].nil? && !@opt_in, "#{current_doc.name} has not opted in")
55
+ return if check_failure(current_options[:make_pdf] == false, "#{current_doc.name} has opted out")
27
56
 
28
- def debug(*args, **options)
29
- @logger.debug(LOG_NAME, *args, **options)
57
+ writer = current_options[:writer]
58
+ return if check_failure(writer.nil?, "No writer defined for #{current_doc.name} (#{writer})")
59
+
60
+ logger.info(" processing #{current_doc.name}")
61
+ @writer = MakePDF.const_get(writer.capitalize).new(logger:, **current_options)
62
+ end
63
+
64
+ def targets
65
+ @options[:targets] || ""
66
+ end
67
+
68
+ def method_missing(method_name, *args, **options)
69
+ if not Jekyll.site_options.nil? and Jekyll.site_options.include?(method_name)
70
+ return Jekyll.site_options[method_name]
71
+ elsif Jekyll.respond_to?(method_name, false)
72
+ return Jekyll.send(method_name, *args, **options)
73
+ else
74
+ super
30
75
  end
31
76
  end
32
77
 
33
- class << self
34
- include PathManip
35
- attr_reader :file, :site, :current_doc, :options, :command, :output
36
-
37
- def setup(current_doc)
38
- if @site.nil?
39
- @site = current_doc.site
40
- @options = @site.config['make-pdf'] || {}
41
- @opt_in = @options['write-by-default'] || false
42
- @base_url = @options['source'] || "file:"
43
- @base_source = @site.dest
44
- @logger = Logger.new(::Jekyll.logger)
45
-
46
- @logger.debug("Initialized with #{@options}. #{@base_source}")
78
+ def render_option(**options)
79
+ logger.debug("MakePDF rendering options #{options}")
80
+
81
+ attempted = 0
82
+ begin
83
+ @writer.process(@file, **options.merge(@options))
84
+ rescue => error
85
+ attempted += 1
86
+ if attempted <= 2
87
+ logger.warn("Failed to generate #{@file} retrying #{attempted}")
88
+ logger.warn("ERROR: #{error}")
89
+ retry
90
+ else
91
+ logger.warn("Skipping generation of #{@file} with #{options}")
92
+ raise error
47
93
  end
94
+ end
95
+ end
48
96
 
49
- current_options = @options.merge(current_doc.data)
50
- @logger.debug(current_options)
51
- bail = lambda do |error|
52
- @logger.debug(error)
53
- false
97
+ def process(**options)
98
+ render_option(**options)
99
+ unless self.targets.nil?
100
+ self.targets.split(",").each do |option|
101
+ render_option(version: option.split(","), **options)
54
102
  end
103
+ end
104
+ end
55
105
 
56
- writer = current_options['writer']
57
- return bail.call("No writer defined for #{current_doc.name} (#{writer})") if writer.nil?
58
-
59
- @writer = MakePDF.const_get(current_options['writer'].capitalize)
60
-
61
- file = current_doc.destination(@base_source)
62
- output_dir = @options['output_dir'] || path_of(file).dirname
63
-
64
- return bail.call("#{file} is not an html") if File.extname(file) != '.html'
65
- return bail.call("#{current_doc.name} has not opted in") if current_doc.data['make-pdf'].nil? && !@opt_in
66
- return bail.call("#{current_doc.name} has opted out")if current_doc.data['make-pdf'] == false
106
+ class << self
107
+ include PathManip
108
+ attr_reader :site_options, :site
67
109
 
68
- @logger.info(" processing #{current_doc.name}")
110
+ def make_options(options, *more_options)
111
+ return {} if options.nil?
69
112
 
70
- @writer.new(file, output_dir, base_source: @base_source, logger: @logger, **current_options)
113
+ [ options, more_options ].flatten
114
+ .reduce(:merge)
115
+ .transform_keys do |key|
116
+ key.to_s.sub("-", "_").to_sym
117
+ end
71
118
  end
72
119
 
73
- def process(current_doc)
74
- writer = setup(current_doc)
120
+ def logger(**options)
121
+ @logger ||= MakePDF::Logger.new(**options)
122
+ end
75
123
 
76
- @logger.debug(" Ignoring #{current_doc.destination("")}")
77
- return if writer === false
124
+ def setup(site, **options)
125
+ return unless @site.nil?
126
+
127
+ config = site.config["make-pdf"]||{}
128
+ logger(logger: ::Jekyll.logger, level: (config["log-map-level"] || :debug).to_sym, verbose: config['log-verbose'])
129
+ @site = site
130
+ input_location = path_of(site.dest)
131
+ input_base_url = relative_path_of(site.baseurl)
132
+ @site_options = {
133
+ :output_base_path => site.source,
134
+ input_location:,
135
+ input_base_url:,
136
+ :input_scheme => "file"
137
+ }.merge(make_options(@site.config["make-pdf"], options))
138
+ logger.debug("Initialized with #{self.site_options}.")
139
+ end
78
140
 
79
- options = current_doc.data['targets']&.split(';') || []
80
- file = current_doc.destination(@site.dest)
141
+ def process(current_doc, **options)
142
+ setup(current_doc.site, **options) if @site.nil?
81
143
 
82
- render_option(writer, file, base_path: @site.dest, base_url: @base_url)
83
- options.each { |option| render_option(writer, file, base_path: @site.dest, base_url: @base_url, version: option.split(",")) }
84
- end
144
+ processor = self.new(current_doc)
85
145
 
86
- def render_option(writer, file, **options)
87
- @logger.debug("MakePDF options: #{options}")
88
-
89
- raise "File #{file} is not accessible" unless File.readable?(file)
90
-
91
- attempted = 0
92
-
93
- begin
94
- writer.write(file, **options)
95
- rescue => error
96
- attempted += 1
97
- if attempted <= 2
98
- @logger.warn("Failed to generate #{file} retrying #{attempted}")
99
- @logger.warn("ERROR: #{error}")
100
- retry
101
- else
102
- @logger.warn("Skipping generation of #{file} with #{options}")
103
- raise error
104
- end
146
+ unless processor.valid?
147
+ logger.debug "Ignoring #{current_doc.name} #{processor.reason}"
148
+ return false
105
149
  end
150
+
151
+ processor.process(**@site_options)
106
152
  end
107
153
  end
108
154
  end
155
+ end
109
156
 
110
- ::Jekyll.logger.info(LOG_NAME, "loaded")
111
- ::Jekyll::Hooks.register [:pages, :documents, :posts], :post_write do |doc|
112
- MakePDF::Jekyll.process(doc)
113
- end
157
+ ::Jekyll.logger.info("Loaded #{MakePDF::LOG_NAME} plugin")
158
+ ::Jekyll::Hooks.register [:pages, :documents, :posts], :post_write do |doc|
159
+ MakePDF::Jekyll.process(doc)
114
160
  end
data/lib/make_pdf.rb CHANGED
@@ -1,20 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'selenium-webdriver'
3
+ require 'fileutils'
4
+ require 'path_of'
4
5
 
5
6
  module MakePDF
6
7
  module PathManip
7
- def path_of(base, *path_components)
8
- other = unless path_components.empty?
9
- path_components
10
- .map { |component| path_of(component) }
11
- .sum Pathname.new(".")
12
- else
13
- Pathname.new("")
14
- end
15
- base = Pathname.new(".") if base.nil?
16
- if base.instance_of?(Pathname) then base else Pathname.new(base) end + other
17
- end
18
8
 
19
9
  def relative_path(file, base_path)
20
10
  path_of(file).relative_path_from(path_of(base_path))
@@ -22,43 +12,98 @@ module MakePDF
22
12
  end
23
13
 
24
14
  class Logger
25
- def debug(*args)
15
+ LEVELS = [ :debug, :info, :warn, :error ]
16
+
17
+ def level
18
+ @min_level || 0
19
+ end
20
+
21
+ def initialize(logger: nil, level: :debug, verbose: false)
22
+ @logger = logger
23
+ @min_level = LEVELS.index(level) || 2
24
+ @verbose = verbose
25
+ write(:debug, "logging at least level #{LEVELS[@min_level].to_s} with #{logger}")
26
+ end
27
+
28
+ def write(level, *args)
29
+ print("#{level.to_s} : ", *args.map do |msg|
30
+ if (msg.size > 80)
31
+ msg[0..79] + "…"
32
+ else
33
+ msg
34
+ end
35
+ end.join("\n"), "\n")
36
+ return
37
+ end
38
+
39
+ def verbose(*args)
40
+ if (@verbose)
41
+ @logger.send(LEVELS[self.level], LOG_NAME, *args)
42
+ end
26
43
  end
27
44
 
28
- alias info debug
29
- alias warn debug
30
- alias error debug
45
+ def method_missing(method_name, *args, **options)
46
+ if @logger.nil? and LEVELS.include?(method_name)
47
+ return write(method_name, *args)
48
+ end
49
+
50
+ if accepts?(method_name)
51
+ @logger.send(LEVELS[[LEVELS.index(method_name), self.level].max], LOG_NAME, *args, **options)
52
+ else
53
+ super
54
+ end
55
+ end
56
+
57
+ def accepts?(method_name)
58
+ LEVELS.include?(method_name) and @logger.respond_to?(method_name, false)
59
+ end
60
+
61
+ def respond_to_missing?(method_name, include_private = false)
62
+ accepts?(method_name) || super
63
+ end
31
64
  end
32
65
 
33
66
  class PDFWriter
34
67
  include PathManip
35
68
  attr_reader :output_dir, :source_url, :logger
36
69
 
37
- def initialize(source_url, output_dir, logger: Logger.new() ,**options)
38
- @source_url = source_url
39
- @output_dir = path_of(output_dir)
70
+ def initialize(input_base_url:, output_base_path:, input_scheme: "file", input_host: nil, logger: Logger.new() ,**options)
40
71
  @logger = logger
41
- @options = options
72
+ raise ArgumentError.new("Scheme `#{input_scheme}` requires an `input_host`.") if input_scheme != "file" && input_host.nil?
73
+ @options = options.merge({ input_base_url:, output_base_path:, input_scheme:, input_host: })
74
+
42
75
  end
43
76
 
44
- def make_source_url(file, base_path:, base_url: nil, **options)
45
- base_path = Pathname.new(base_path).realpath
46
- target_file = Pathname.new(file).realpath.relative_path_from(base_path)
47
- if (base_url != "file:")
48
- return base_url + target_file.to_s
77
+ def make_relative_file(file, input_location:, **options)
78
+ path_of(file).relative_path_from(path_of(input_location))
79
+ end
80
+
81
+ def make_source_url(file, input_base_url:, output_base_path:, input_scheme: , input_host: , input_location:, **options)
82
+ target_file = make_relative_file(file, input_location:, **options)
83
+ input_location = path_of(input_location)
84
+ input_base_url = relative_path_of(input_base_url)
85
+ if (input_scheme != "file")
86
+ return input_scheme + "://" + input_host + "/" + (input_base_url / target_file).to_path
49
87
  else
50
- return base_path + target_file.to_s
88
+ return (input_location / input_location / target_file).to_path
51
89
  end
52
90
  end
53
91
 
54
- def make_pdf_filename(file, **options)
55
- path_of(file).basename.sub_ext(".pdf")
92
+ def make_pdf_filename(file, output_base_path:, input_location:, output_dir:, **options)
93
+ base_path = path_of(output_base_path)
94
+ filepath = make_relative_file(file, input_location:).sub_ext(".pdf")
95
+ result = base_path / relative_path_of(output_dir) / filepath
96
+ @logger.verbose("make_pdf_filename(#{file}, #{output_base_path}) → base_path: #{base_path}, filepath: #{filepath} ⇒ #{result}")
97
+ result
56
98
  end
57
99
 
58
- def make_output_filename(file, base_path:, **options)
59
- filename = make_pdf_filename(file, base_path:, **options)
60
- output = @output_dir / filename
61
- @logger.debug("filenane : #{filename} output_dir: #{output_dir} output_filename: #{output}")
100
+ def make_output_filename(file, input_location:, output_base_path:, output_dir: ".", **options)
101
+ @logger.verbose("make_output_filename(#{file}, #{input_location}, #{output_base_path})")
102
+ filename = make_pdf_filename(file, output_base_path:, output_dir:, input_location:, **options)
103
+ output_base_path = path_of(output_base_path)
104
+ output = output_base_path / relative_path_of(output_dir) / filename
105
+ FileUtils::mkdir_p(output.dirname)
106
+ @logger.debug("filename: #{filename} ⇒ #{output}")
62
107
  output
63
108
  end
64
109
 
@@ -73,7 +118,6 @@ module MakePDF
73
118
  output_filename
74
119
  end
75
120
  end
76
-
77
121
  end
78
122
 
79
123
  Dir[File.join(__dir__, 'make_pdf/', '**', '*.rb')].each do |file|
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: make_pdf-jekyll
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Bogado da Silva Lins
8
+ autorequire:
8
9
  bindir: bin
9
10
  cert_chain: []
10
- date: 1980-01-02 00:00:00.000000000 Z
11
+ date: 2025-08-27 00:00:00.000000000 Z
11
12
  dependencies: []
12
13
  description: Allows that some documents, or pages to have a pdf version pre generated.
13
14
  email: 'victor@bogado.net '
@@ -24,6 +25,7 @@ homepage: https://rubygems.org/gems/make_pdf-jekyll
24
25
  licenses:
25
26
  - MIT
26
27
  metadata: {}
28
+ post_install_message:
27
29
  rdoc_options: []
28
30
  require_paths:
29
31
  - lib
@@ -38,7 +40,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
38
40
  - !ruby/object:Gem::Version
39
41
  version: '0'
40
42
  requirements: []
41
- rubygems_version: 3.6.7
43
+ rubygems_version: 3.3.25
44
+ signing_key:
42
45
  specification_version: 4
43
46
  summary: Create PDF along side of HTML files for site.
44
47
  test_files: []