Class: Vectory::GhostscriptWrapper

Inherits:
Object
  • Object
show all
Defined in:
lib/vectory/ghostscript_wrapper.rb

Overview

GhostscriptWrapper converts PS and EPS files to PDF using Ghostscript

Uses Ukiryu for platform-adaptive command execution.

Constant Summary collapse

SUPPORTED_INPUT_FORMATS =
%w[ps eps].freeze

Class Method Summary collapse

Class Method Details

.available?Boolean

Returns:

  • (Boolean)


15
16
17
18
19
20
# File 'lib/vectory/ghostscript_wrapper.rb', line 15

def available?
  ghostscript_tool
  true
rescue GhostscriptNotFoundError
  false
end

.convert(content, options = {}) ⇒ Object



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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/vectory/ghostscript_wrapper.rb', line 31

def convert(content, options = {})
  raise GhostscriptNotFoundError unless available?

  eps_crop = options.fetch(:eps_crop, false)
  input_ext = eps_crop ? ".eps" : ".ps"

  # Create temporary input file
  input_file = Tempfile.new(["gs_input", input_ext])
  output_file = Tempfile.new(["gs_output", ".pdf"])

  begin
    # Write content and close the input file so GhostScript can read it
    input_file.binmode
    input_file.write(content)
    input_file.flush
    input_file.close

    # Close output file so GhostScript can write to it
    output_file.close

    # Get the tool and execute
    tool = ghostscript_tool
    params = build_convert_params(input_file.path, output_file.path,
                                  eps_crop: eps_crop)

    result = tool.execute(:convert,
                          execution_timeout: Configuration.instance.timeout,
                          **params)

    unless result.success?
      raise ConversionError,
            "GhostScript conversion failed. " \
            "Command: #{result.command}, " \
            "Exit status: #{result.status}, " \
            "stdout: '#{result.stdout.strip}', " \
            "stderr: '#{result.stderr.strip}'"
    end

    unless File.exist?(output_file.path)
      raise ConversionError,
            "GhostScript did not create output file: #{output_file.path}"
    end

    output_content = File.binread(output_file.path)

    # Check if the PDF is valid (should be more than just the header)
    if output_content.size < 100
      raise ConversionError,
            "GhostScript created invalid PDF (#{output_content.size} bytes). " \
            "Command: #{result.command}, " \
            "stdout: '#{result.stdout.strip}', " \
            "stderr: '#{result.stderr.strip}'"
    end

    output_content
  ensure
    # Clean up temp files
    input_file.close unless input_file.closed?
    input_file.unlink
    output_file.close unless output_file.closed?
    output_file.unlink
  end
end

.pdf_to_eps(pdf_content) ⇒ String

Convert PDF content to PostScript

This is useful as a fallback when Inkscape’s PDF import fails. Ghostscript can reliably convert PDF to EPS, and Inkscape can then import the EPS file.

Parameters:

  • pdf_content (String)

    the PDF content to convert

Returns:

  • (String)

    the EPS content

Raises:



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/vectory/ghostscript_wrapper.rb', line 105

def pdf_to_eps(pdf_content)
  raise GhostscriptNotFoundError unless available?

  input_file = Tempfile.new(["pdf_input", ".pdf"])
  output_file = Tempfile.new(["eps_output", ".eps"])

  begin
    input_file.binmode
    input_file.write(pdf_content)
    input_file.flush
    input_file.close
    output_file.close

    tool = ghostscript_tool
    params = {
      inputs: [input_file.path],
      device: :eps2write,
      output: output_file.path,
      batch: true,
      no_pause: true,
      quiet: true,
    }

    result = tool.execute(:convert,
                          execution_timeout: Configuration.instance.timeout,
                          **params)

    unless result.success?
      raise ConversionError,
            "GhostScript PDF to EPS conversion failed. " \
            "Command: #{result.command}, " \
            "Exit status: #{result.status}, " \
            "stdout: '#{result.stdout.strip}', " \
            "stderr: '#{result.stderr.strip}'"
    end

    unless File.exist?(output_file.path)
      raise ConversionError,
            "GhostScript did not create output file: #{output_file.path}"
    end

    File.binread(output_file.path)
  ensure
    input_file.close unless input_file.closed?
    input_file.unlink
    output_file.close unless output_file.closed?
    output_file.unlink
  end
end

.versionObject



22
23
24
25
26
27
28
29
# File 'lib/vectory/ghostscript_wrapper.rb', line 22

def version
  return nil unless available?

  tool = ghostscript_tool
  tool.version
rescue StandardError
  nil
end