Class: Uniword::Mhtml::CssNumberFormatter

Inherits:
Object
  • Object
show all
Defined in:
lib/uniword/mhtml/css_number_formatter.rb

Overview

Formats CSS numeric values for Word-compatible MHTML.

Responsibility: Provide consistent CSS number formatting with proper units, precision, and handling of edge cases like zero values.

Examples:

Format a font size

CssNumberFormatter.format(16, 'pt')  # => "16pt"

Format a margin with precision

CssNumberFormatter.format(1.5, 'pt')  # => "1.5pt"

Format zero value

CssNumberFormatter.format(0, 'px')  # => "0"

Constant Summary collapse

DEFAULT_PRECISION =

Default decimal precision for CSS values

2
OMIT_UNIT_FOR_ZERO =

Units that should be omitted for zero values

%w[px pt em rem % cm mm in].freeze
TWIPS_PER_POINT =

Convert twips to points (1pt = 20 twips)

20

Class Method Summary collapse

Class Method Details

.format(value, unit, precision: DEFAULT_PRECISION) ⇒ String?

Format a CSS number value with appropriate unit and precision.

Examples:

Format with default precision

format(12.5, 'pt')  # => "12.5pt"

Format zero value

format(0, 'px')  # => "0"

Format with custom precision

format(1.23456, 'em', 3)  # => "1.235em"

Parameters:

  • value (Numeric, nil)

    The numeric value

  • unit (String)

    The CSS unit (pt, px, em, %, in, cm, mm)

  • precision (Integer) (defaults to: DEFAULT_PRECISION)

    Decimal places (default: 2)

Returns:

  • (String, nil)

    Formatted CSS value or nil if value is nil



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/uniword/mhtml/css_number_formatter.rb', line 43

def self.format(value, unit, precision: DEFAULT_PRECISION)
  return nil if value.nil?

  # Convert to float
  numeric_value = value.to_f

  # Handle zero specially - omit unit
  return "0" if numeric_value.zero? && OMIT_UNIT_FOR_ZERO.include?(unit)

  # Round to specified precision
  rounded = numeric_value.round(precision)

  # Format and remove unnecessary trailing zeros
  formatted = if rounded == rounded.to_i
                rounded.to_i.to_s
              else
                # Format with precision, then remove trailing zeros
                Kernel.format("%.#{precision}f", rounded).sub(/\.?0+$/,
                                                              "")
              end

  "#{formatted}#{unit}"
end

.format_font_size(half_points, precision: 1) ⇒ String?

Format a font size value (typically in half-points).

Examples:

Format font size

format_font_size(24)  # => "12pt"

Parameters:

  • half_points (Numeric, nil)

    Font size in half-points

  • precision (Integer) (defaults to: 1)

    Decimal places (default: 1)

Returns:

  • (String, nil)

    Formatted font size



106
107
108
109
110
111
# File 'lib/uniword/mhtml/css_number_formatter.rb', line 106

def self.format_font_size(half_points, precision: 1)
  return nil if half_points.nil?

  points = half_points.to_f / 2.0
  format(points, "pt", precision: precision)
end

.format_percentage(value, precision: 0) ⇒ String?

Format percentage value.

Examples:

Format percentage

format_percentage(50)  # => "50%"

Parameters:

  • value (Numeric, nil)

    Percentage value (0-100)

  • precision (Integer) (defaults to: 0)

    Decimal places (default: 0)

Returns:

  • (String, nil)

    Formatted percentage



121
122
123
124
125
# File 'lib/uniword/mhtml/css_number_formatter.rb', line 121

def self.format_percentage(value, precision: 0)
  return nil if value.nil?

  format(value, "%", precision: precision)
end

.twips_to_in(twips, precision: DEFAULT_PRECISION) ⇒ String?

Convert twips to inches and format.

Examples:

Convert 1440 twips to inches

twips_to_in(1440)  # => "1in"

Parameters:

  • twips (Numeric, nil)

    Value in twips

  • precision (Integer) (defaults to: DEFAULT_PRECISION)

    Decimal places (default: 2)

Returns:

  • (String, nil)

    Formatted value in inches



90
91
92
93
94
95
96
# File 'lib/uniword/mhtml/css_number_formatter.rb', line 90

def self.twips_to_in(twips, precision: DEFAULT_PRECISION)
  return nil if twips.nil?

  # 1 inch = 1440 twips
  inches = twips.to_f / 1440.0
  format(inches, "in", precision: precision)
end

.twips_to_pt(twips, precision: DEFAULT_PRECISION) ⇒ String?

Convert twips to points and format.

Examples:

Convert 1440 twips to inches

twips_to_pt(1440)  # => "72pt"

Parameters:

  • twips (Numeric, nil)

    Value in twips

  • precision (Integer) (defaults to: DEFAULT_PRECISION)

    Decimal places (default: 2)

Returns:

  • (String, nil)

    Formatted value in points



75
76
77
78
79
80
# File 'lib/uniword/mhtml/css_number_formatter.rb', line 75

def self.twips_to_pt(twips, precision: DEFAULT_PRECISION)
  return nil if twips.nil?

  points = twips.to_f / TWIPS_PER_POINT
  format(points, "pt", precision: precision)
end