Class: Fontisan::Commands::ConvertCommand

Inherits:
BaseCommand
  • Object
show all
Defined in:
lib/fontisan/commands/convert_command.rb

Overview

Command for converting fonts between formats

ConvertCommand provides CLI interface for font format conversion operations using the universal transformation pipeline. It supports:

  • Same-format operations (copy/optimize)
  • TTF ↔ OTF outline format conversion
  • Variable font operations (preserve/instance generation)
  • WOFF/WOFF2 compression

The command uses TransformationPipeline to orchestrate conversions with appropriate strategies.

Examples:

Convert TTF to OTF

command = ConvertCommand.new(
  'input.ttf',
  to: 'otf',
  output: 'output.otf'
)
command.run

Generate instance at coordinates

command = ConvertCommand.new(
  'variable.ttf',
  to: 'ttf',
  output: 'bold.ttf',
  coordinates: 'wght=700,wdth=100'
)
command.run

Convert with ConversionOptions

options = ConversionOptions.recommended(from: :ttf, to: :otf)
command = ConvertCommand.new(
  'input.ttf',
  to: 'otf',
  output: 'output.otf',
  options: options
)
command.run

Instance Method Summary collapse

Constructor Details

#initialize(font_path, options = {}) ⇒ ConvertCommand

Initialize convert command

Parameters:

  • font_path (String)

    Path to input font file

  • options (Hash) (defaults to: {})

    Conversion options

Options Hash (options):

  • :to (String)

    Target format (ttf, otf, woff, woff2)

  • :output (String)

    Output file path (required)

  • :font_index (Integer)

    Index for TTC/OTC (default: 0)

  • :coordinates (String)

    Coordinate string (e.g., "wght=700,wdth=100")

  • :instance_coordinates (Hash)

    Axis coordinates hash (e.g., => 700.0)

  • :instance_index (Integer)

    Named instance index

  • :preserve_variation (Boolean)

    Preserve variation data (default: auto)

  • :preserve_hints (Boolean)

    Preserve rendering hints (default: false)

  • :target_format (String)

    Target outline format for collections: 'preserve' (default), 'ttf', or 'otf'

  • :no_validate (Boolean)

    Skip output validation

  • :verbose (Boolean)

    Verbose output

  • :options (ConversionOptions)

    ConversionOptions object



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
# File 'lib/fontisan/commands/convert_command.rb', line 61

def initialize(font_path, options = {})
  super(font_path, options)

  # Convert string keys to symbols for Thor compatibility. All command
  # code reads @options with symbol keys (e.g., @options[:quiet]);
  # normalizing once at construction is cleaner than threading a
  # second opts hash alongside @options.
  @options = options.transform_keys(&:to_sym)

  @output_path = @options[:output]

  # Parse target format
  @target_format = parse_target_format(@options[:to])

  # Extract ConversionOptions if provided
  @conv_options = extract_conversion_options(@options)

  # Parse coordinates if string provided
  @coordinates = if @options[:coordinates]
                   parse_coordinates(@options[:coordinates])
                 elsif @options[:instance_coordinates]
                   @options[:instance_coordinates]
                 end

  @instance_index = @options[:instance_index]
  @preserve_variation = @options[:preserve_variation]
  @preserve_hints = @options.fetch(:preserve_hints, false)
  @collection_target_format = @options.fetch(:target_format,
                                             "preserve").to_s
  @validate = !@options[:no_validate]
end

Instance Method Details

#runHash

Execute the conversion

Returns:

  • (Hash)

    Result information

Raises:

  • (ArgumentError)

    If output path is not specified

  • (Error)

    If conversion fails



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/fontisan/commands/convert_command.rb', line 98

def run
  validate_options!

  # Check if input is a collection
  if collection_file?
    convert_collection
  else
    convert_single_font
  end
rescue ArgumentError
  # Let ArgumentError propagate for validation errors
  raise
rescue StandardError => e
  raise Error, "Conversion failed: #{e.message}"
end