Module: Sghtmltopdf::Options

Defined in:
lib/sghtmltopdf/options.rb

Overview

オプションハッシュを変換する。

  • ネイティブ拡張へ渡すCLIの引数列(argv) … [.to_argv]
  • HTTPサーバモードへ渡すクエリ文字列 … [.to_query]

Constant Summary collapse

ARGV_PREFIX =

入力は常に標準入力を表す-を置く(実際のバイト列はFFIで直接渡すため 読まれない)。出力先はRust側のSinkが決めるので、ここもダミーの--入力のときCLIは--outputを必須にするため、省略はできない。

["sghtmltopdf", "-", "--output", "-"].freeze
TRANSPORT_KEYS =

Ruby側だけで解釈するキー。変換オプションではないので、argvにも クエリにも出さない。

%i[server_url server_open_timeout server_read_timeout chunk_size].freeze

Class Method Summary collapse

Class Method Details

.args_for(key, value) ⇒ Object

1つのキーと値をargvの断片へ変換する。

page_size: "A4"     → ["--page-size", "A4"]
grayscale: true     → ["--grayscale"]
grayscale: false    → []
allow: ["/a", "/b"] → ["--allow", "/a", "--allow", "/b"]


50
51
52
# File 'lib/sghtmltopdf/options.rb', line 50

def args_for(key, value)
  pairs_for(key, value).flat_map { |name, arg| arg.nil? ? ["--#{name}"] : ["--#{name}", arg] }
end

.each_pair(options, &block) ⇒ Object

変換オプションだけを、渡された順にペアとして列挙する。



114
115
116
117
118
119
120
# File 'lib/sghtmltopdf/options.rb', line 114

def each_pair(options, &block)
  options.each do |key, value|
    next if TRANSPORT_KEYS.include?(key.to_sym)

    pairs_for(key, value).each(&block)
  end
end

.escape(value) ⇒ Object



122
123
124
# File 'lib/sghtmltopdf/options.rb', line 122

def escape(value)
  URI.encode_www_form_component(value.to_s)
end

.flag_name(key) ⇒ Object

:page_sizepage-size



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

def flag_name(key)
  key.to_s.tr("_", "-")
end

.font_args(value) ⇒ Object

--font--font-indexは出現順で対応付けられる(CLIは ArgMatches#indices_ofで「--font-indexより手前にある最後の--font」 へ結び付ける)。そのため、フェイス番号は 必ず対応する--fontの直後へ置く。

font: "a.ttf"                        → ["--font", "a.ttf"]
font: {path: "a.ttc", index: 1}      → ["--font", "a.ttc", "--font-index", "1"]
font: ["a.ttf", {path: "b.ttc", index: 2}]
→ ["--font", "a.ttf", "--font", "b.ttc", "--font-index", "2"]


88
89
90
# File 'lib/sghtmltopdf/options.rb', line 88

def font_args(value)
  font_pairs(value).flat_map { |name, arg| ["--#{name}", arg] }
end

.font_pairs(value) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/sghtmltopdf/options.rb', line 92

def font_pairs(value)
  case value
  when nil, false then []
  when Array then value.flat_map { |element| font_pairs(element) }
  when Hash
    path = value[:path] || value["path"]
    raise ArgumentError, "fontのHashにはpathが必要です: #{value.inspect}" if path.nil?

    index = value[:index] || value["index"]
    pairs = [["font", path.to_s]]
    pairs << ["font-index", index.to_s] unless index.nil?
    pairs
  else [["font", value.to_s]]
  end
end

.pairs_for(key, value) ⇒ Object

1つのキーと値を「フラグ名と値」のペアの列にする。値がnilのペアは 値を取らないフラグ(--tocなど)。



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/sghtmltopdf/options.rb', line 56

def pairs_for(key, value)
  name = flag_name(key)
  return font_pairs(value) if name == "font"

  case value
  when nil, false then []
  when true then [[name, nil]]
  # 配列は同じオプションの繰り返し。要素ごとに同じ規則を適用する。
  when Array then value.flat_map { |element| pairs_for(key, element) }
  when Hash
    # wicked_pdfの`margin: {top: 10}`のような入れ子は受けない。数値の
    # 単位の解釈が違う(wicked_pdfはmm・こちらはpx)ため、機械的に
    # 平坦化すると黙って別の余白になる。移行時は
    # 移行ガイドの対応表を見て書き換えてもらう。
    example = value.keys.first
    raise ArgumentError,
      "#{key}にHashは渡せません(pathとindexを取るのは:fontだけです)。" \
      "入れ子のオプションは平坦なキーで指定してください" \
      "#{": 例 #{key}_#{example}: \"…\"" if example}"
  else [[name, value.to_s]]
  end
end

.to_argv(options) ⇒ Array<String>

Returns clapへ渡す引数列.

Parameters:

  • options (Hash)

    Rubyのオプションハッシュ

Returns:

  • (Array<String>)

    clapへ渡す引数列



24
25
26
27
28
29
30
31
# File 'lib/sghtmltopdf/options.rb', line 24

def to_argv(options)
  argv = ARGV_PREFIX.dup
  each_pair(options) do |name, value|
    argv.push("--#{name}")
    argv.push(value) unless value.nil?
  end
  argv
end

.to_query(options) ⇒ String

Returns POST /pdfのクエリ文字列(先頭に?は付けない).

Parameters:

  • options (Hash)

    Rubyのオプションハッシュ

Returns:

  • (String)

    POST /pdfのクエリ文字列(先頭に?は付けない)



35
36
37
38
39
40
41
42
# File 'lib/sghtmltopdf/options.rb', line 35

def to_query(options)
  parts = []
  each_pair(options) do |name, value|
    # 値なしのフラグはキーだけを置く(サーバは値なし=真として扱う)。
    parts << (value.nil? ? escape(name) : "#{escape(name)}=#{escape(value)}")
  end
  parts.join("&")
end