nguyen 1.0.3 → 2.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: acfaf8065a261f6cc2b2f5b95887a48d450686b6529a315664982c13ecc0c8d0
4
- data.tar.gz: 99729f86c46f23fc9846f1af8c727da593066dc9df39c4283eceba5b6bd2bb68
3
+ metadata.gz: 74a1c2e3015f9f5338b2e3140a85f26bc7190d6884f5fcfcd22b76bf0e5ed23a
4
+ data.tar.gz: 9704aa598ac801cd59171aa081ca3c3d9b76d2dc3d9d0001ea33e9dceba9e217
5
5
  SHA512:
6
- metadata.gz: 5d65ce412084256c66f6061c32301f4d48772aafd28b438049877191bb93d72592cc13b9727c46d445be4d7cb8d41fb1db2163ba22c1d03d3739fd0a64907d8f
7
- data.tar.gz: b8ebe36c4cbff4e667b38dad208c305035bfc18623b68bace90ff8753f0a6aa7fb203fcec0332a959b155166c9a646d3cee455bb9601cf26b2abeee9d85f7d07
6
+ metadata.gz: 22d0fe163418da9d6023d757d1a2a48ccd5dd976ee186d6c68e5a5965d8b49ddba1638e324e286dfeee536bd310e5ec506b62270a55fe33472119c15b6bde85f
7
+ data.tar.gz: 8b8328c35cd0a98be573d9dd50fb6ddb79e27b9275df57be34b682016ca7c85ecc7e88e5e966f36a99e62d2de4e107018e1927eec23b13aaf83a494c39b63b8e
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  (The MIT License)
2
2
 
3
- Copyright (c) 2014 Trung Lê
3
+ Copyright (c) 2014 - 2026 Trung Lê
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining
6
6
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,13 +1,16 @@
1
- # Nguyên the PDF Field Merger
1
+ # Nguyễn the PDF Field Merger
2
2
 
3
3
  A very lightweight library that fill PDF forms using XFDF/FDF with pdftk
4
4
 
5
5
  You could download pdftk at http://www.accesspdf.com/pdftk/
6
6
 
7
- Nguyên is a fork of Jens Krämer's pdf-forms with addition of filling forms with XFDF feature.
7
+ Nguyễn is a fork of Jens Krämer's pdf-forms with addition of filling forms with XFDF feature.
8
8
 
9
- [![Build Status](https://secure.travis-ci.org/ruby-journal/nguyen.png)](http://travis-ci.org/ruby-journal/nguyen)
9
+ [![CI](https://github.com/ruby-journal/nguyen/actions/workflows/ci.yml/badge.svg)](https://github.com/ruby-journal/nguyen/actions/workflows/ci.yml)
10
10
  [![Code Climate](https://codeclimate.com/github/ruby-journal/nguyen/badges/gpa.svg)](https://codeclimate.com/github/ruby-journal/nguyen)
11
+ [![From Vietnam with <3](https://raw.githubusercontent.com/webuild-community/badge/master/svg/love.svg)](https://webuild.community)
12
+ [![Made in Vietnam](https://raw.githubusercontent.com/webuild-community/badge/master/svg/made.svg)](https://webuild.community)
13
+ [![Built with WeBuild](https://raw.githubusercontent.com/webuild-community/badge/master/svg/WeBuild.svg)](https://webuild.community)
11
14
 
12
15
  ## EXAMPLE:
13
16
 
@@ -59,6 +62,19 @@ XML
59
62
  pdftk.fill_form('/path/to/form', 'myform.pdf', xfdf_string)
60
63
  ```
61
64
 
65
+ ### Stamp PDFs
66
+
67
+ ```ruby
68
+ pdftk = Nguyen::PdftkWrapper.new('/usr/local/bin/pdftk')
69
+
70
+ # overlay stamp.pdf (e.g. a watermark or signature) on top of every page of source.pdf
71
+ pdftk.stamp('source.pdf', 'stamp.pdf', 'stamped.pdf')
72
+
73
+ # overlay stamp.pdf page by page: page 1 of stamp.pdf onto page 1 of source.pdf, etc.
74
+ # the last page of stamp.pdf is repeated if source.pdf has more pages
75
+ pdftk.multistamp('source.pdf', 'stamp.pdf', 'stamped.pdf')
76
+ ```
77
+
62
78
  ## INSTALL:
63
79
 
64
80
  gem install nguyen
data/lib/nguyen/fdf.rb CHANGED
@@ -5,9 +5,9 @@ module Nguyen
5
5
  # Straight port of Perl's PDF::FDF::Simple by Steffen Schwigon.
6
6
  # Parsing FDF files is not supported (yet).
7
7
  class Fdf
8
-
8
+
9
9
  attr_reader :options
10
-
10
+
11
11
  def initialize(data = {}, options = {})
12
12
  @data = data
13
13
  @options = {
@@ -20,7 +20,7 @@ module Nguyen
20
20
  # generate FDF content
21
21
  def to_fdf
22
22
  fdf = header
23
-
23
+
24
24
  @data.each do |key, value|
25
25
  if Hash === value
26
26
  value.each do |sub_key, sub_value|
@@ -34,34 +34,42 @@ module Nguyen
34
34
  fdf << footer
35
35
  return fdf
36
36
  end
37
-
37
+
38
38
  # write fdf content to path
39
39
  def save_to(path)
40
40
  File.write(path, to_fdf)
41
41
  end
42
-
42
+
43
43
  protected
44
-
44
+
45
45
  def header
46
- header = "%FDF-1.2\n\n1 0 obj\n<<\n/FDF << /Fields 2 0 R"
47
-
46
+ header = +"%FDF-1.2\n\n1 0 obj\n<<\n/FDF << /Fields 2 0 R"
47
+
48
48
  # /F
49
49
  header << "/F (#{options[:file]})" if options[:file]
50
50
  # /UF
51
51
  header << "/UF (#{options[:ufile]})" if options[:ufile]
52
52
  # /ID
53
53
  header << "/ID[" << options[:id].join << "]" if options[:id]
54
-
54
+
55
55
  header << ">>\n>>\nendobj\n2 0 obj\n["
56
56
  return header
57
57
  end
58
58
 
59
59
  def field(key, value)
60
- "<</T(#{key})/V" +
61
- (Array === value ? "[#{value.map{ |v|"(#{quote(v)})" }.join}]" : "(#{quote(value)})") +
62
- ">>\n"
60
+ value_string = case value
61
+ when TrueClass
62
+ '/1'
63
+ when FalseClass
64
+ '/0'
65
+ when Array
66
+ '[' + value.map { |v| "(#{quote(v)})" }.join + ']'
67
+ else
68
+ "(#{quote(value)})"
69
+ end
70
+ "<<\n/T(#{key})\n/V #{value_string}\n>>\n"
63
71
  end
64
-
72
+
65
73
  def quote(value)
66
74
  value.to_s.strip.
67
75
  gsub( /\\/, '\\' ).
@@ -69,7 +77,7 @@ module Nguyen
69
77
  gsub( /\)/, '\)' ).
70
78
  gsub( /\n/, '\r' )
71
79
  end
72
-
80
+
73
81
  FOOTER =<<-EOFOOTER
74
82
  ]
75
83
  endobj
@@ -80,10 +88,10 @@ trailer
80
88
  >>
81
89
  %%EOF
82
90
  EOFOOTER
83
-
91
+
84
92
  def footer
85
93
  FOOTER
86
94
  end
87
-
95
+
88
96
  end
89
97
  end
data/lib/nguyen/pdf.rb CHANGED
@@ -14,13 +14,13 @@ module Nguyen
14
14
 
15
15
  protected
16
16
 
17
- def read_fields
18
- field_output = @pdftk.call_pdftk %Q("#{path}"), 'dump_data_fields'
19
- @fields = field_output.split(/^---\n/).map do |field_text|
20
- if field_text =~ /^FieldName: (\w+)$/
21
- $1
22
- end
23
- end.compact.uniq
24
- end
17
+ def read_fields
18
+ field_output = @pdftk.call_pdftk path, 'dump_data_fields_utf8'
19
+ @fields = field_output.split("\n").map do |field_text|
20
+ if field_text =~ /^FieldName: (.+)$/
21
+ $1
22
+ end
23
+ end.compact.uniq
24
+ end
25
25
  end
26
26
  end
@@ -1,4 +1,6 @@
1
1
  require 'tempfile'
2
+ require 'open3'
3
+ require 'shellwords'
2
4
  module Nguyen
3
5
  class PdftkError < StandardError
4
6
  end
@@ -19,15 +21,27 @@ module Nguyen
19
21
  tmp = Tempfile.new('pdf_forms-fdf')
20
22
  tmp.close
21
23
  form_data.respond_to?(:save_to) ? form_data.save_to(tmp.path) : File.write(tmp.path, form_data)
22
- command = pdftk_command %Q("#{template}"), 'fill_form', %Q("#{tmp.path}"), 'output', destination, add_options(tmp.path)
23
- output = %x{#{command}}
24
+ args = [template, 'fill_form', tmp.path, 'output', destination, add_options(tmp.path)]
25
+ output = call_pdftk(*args)
24
26
  unless File.readable?(destination) && File.size(destination) > 0
25
- raise PdftkError.new("failed to fill form with command\n#{command}\ncommand output was:\n#{output}")
27
+ raise PdftkError.new("failed to fill form with command\n#{describe_command(args)}\ncommand output was:\n#{output}")
26
28
  end
27
29
  ensure
28
30
  tmp.unlink if tmp
29
31
  end
30
32
 
33
+ # pdftk.stamp '/path/to/source.pdf', '/path/to/stamp.pdf', '/path/to/destination.pdf'
34
+ # overlays the stamp PDF on top of every page of the source PDF
35
+ def stamp(template, stamp_file, destination)
36
+ stamp_operation 'stamp', template, stamp_file, destination
37
+ end
38
+
39
+ # pdftk.multistamp '/path/to/source.pdf', '/path/to/stamp.pdf', '/path/to/destination.pdf'
40
+ # overlays the stamp PDF onto the source PDF page by page
41
+ def multistamp(template, stamp_file, destination)
42
+ stamp_operation 'multistamp', template, stamp_file, destination
43
+ end
44
+
31
45
  # pdftk.read '/path/to/form.pdf'
32
46
  # returns an instance of Nguyen::Pdf representing the given template
33
47
  def read(path)
@@ -38,20 +52,37 @@ module Nguyen
38
52
  read(template).fields
39
53
  end
40
54
 
55
+ # invokes pdftk with the given arguments and returns its output (stdout
56
+ # and stderr combined); arguments are passed to the process verbatim,
57
+ # without any shell involved, so paths need no quoting or escaping
41
58
  def call_pdftk(*args)
42
- %x{#{pdftk_command args}}
59
+ output, _status = Open3.capture2e(pdftk, *normalize_args(args))
60
+ output
43
61
  end
44
62
 
45
- def cat(*files,output)
46
- files = files[0] if files[0].class == Array
47
- input = files.map{|f| %Q(#{f})}
48
- call_pdftk(*input,'output',output)
63
+ def cat(*files, output)
64
+ files = files.flatten
65
+ input = files.flat_map { |f| f.to_s.include?('*') ? Dir.glob(f) : [f] }
66
+ call_pdftk(*input, 'output', output)
49
67
  end
50
68
 
51
69
  protected
52
70
 
53
- def pdftk_command(*args)
54
- "#{pdftk} #{args.flatten.compact.join ' '} 2>&1"
71
+ def stamp_operation(operation, template, stamp_file, destination)
72
+ args = [template, operation, stamp_file, 'output', destination]
73
+ output = call_pdftk(*args)
74
+ unless File.readable?(destination) && File.size(destination) > 0
75
+ raise PdftkError.new("failed to #{operation} with command\n#{describe_command(args)}\ncommand output was:\n#{output}")
76
+ end
77
+ end
78
+
79
+ def normalize_args(args)
80
+ args.flatten.compact.map(&:to_s)
81
+ end
82
+
83
+ # human readable rendition of a pdftk invocation, for error messages
84
+ def describe_command(args)
85
+ Shellwords.join([pdftk, *normalize_args(args)])
55
86
  end
56
87
 
57
88
  def add_options(pwd)
@@ -61,7 +92,8 @@ module Nguyen
61
92
  opt_args << 'flatten'
62
93
  end
63
94
  if options[:encrypt]
64
- opt_args.concat ['encrypt_128bit', 'owner_pw', pwd, options[:encrypt_options]]
95
+ opt_args.concat ['encrypt_128bit', 'owner_pw', pwd]
96
+ opt_args.concat Shellwords.split(options[:encrypt_options]) if options[:encrypt_options]
65
97
  end
66
98
  opt_args
67
99
  end
@@ -1,3 +1,3 @@
1
1
  module Nguyen
2
- VERSION = '1.0.3'
2
+ VERSION = '2.1.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nguyen
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Trung Lê
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2020-06-11 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: nokogiri
@@ -16,14 +15,14 @@ dependencies:
16
15
  requirements:
17
16
  - - "~>"
18
17
  - !ruby/object:Gem::Version
19
- version: '1.10'
18
+ version: '1.16'
20
19
  type: :runtime
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
23
  - - "~>"
25
24
  - !ruby/object:Gem::Version
26
- version: '1.10'
25
+ version: '1.16'
27
26
  - !ruby/object:Gem::Dependency
28
27
  name: minitest
29
28
  requirement: !ruby/object:Gem::Requirement
@@ -38,7 +37,7 @@ dependencies:
38
37
  - - ">="
39
38
  - !ruby/object:Gem::Version
40
39
  version: '0'
41
- description: Forms for Nguyên is Ruby library that could merge PDF fields by XFDF/FDF
40
+ description: Forms for Nguyễn is Ruby library that could merge PDF fields by XFDF/FDF
42
41
  via pdftk.
43
42
  email: trung.le@ruby-journal.com
44
43
  executables: []
@@ -58,7 +57,6 @@ homepage: http://github.com/ruby-journal/nguyen
58
57
  licenses:
59
58
  - MIT
60
59
  metadata: {}
61
- post_install_message:
62
60
  rdoc_options: []
63
61
  require_paths:
64
62
  - lib
@@ -66,7 +64,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
66
64
  requirements:
67
65
  - - ">="
68
66
  - !ruby/object:Gem::Version
69
- version: 2.5.0
67
+ version: 3.3.0
70
68
  required_rubygems_version: !ruby/object:Gem::Requirement
71
69
  requirements:
72
70
  - - ">="
@@ -74,8 +72,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
74
72
  version: '0'
75
73
  requirements:
76
74
  - pdtk 1.44.1 or newer
77
- rubygems_version: 3.0.3
78
- signing_key:
75
+ rubygems_version: 4.0.10
79
76
  specification_version: 4
80
77
  summary: Fill out PDF forms by XFDF/FDF via pdftk.
81
78
  test_files: []