Class: IsoDoc::ExtendedDateFormatter

Inherits:
Object
  • Object
show all
Defined in:
lib/isodoc/extended_date.rb

Overview

Extended strftime-style date formatter on top of Ruby’s Date#strftime.

Adds three POSIX-flavoured surfaces:

%E[YyC]              - era year (calendar-aware)
%O[mdYy]             - alternative numbering for date components
%_                   - legacy alias for a literal space (kept for
                       backwards compatibility with IsoDoc::I18n#date)

Optional square-bracket-delimited ARGS may follow the conversion letter for %E* and %O* tokens (e.g. %EY, %Om). Square brackets rather than braces, so format strings remain safe to inline inside Liquid {{…}} templates.

The localised name directives (%B, %b, %h, %A, %a, %P, %p) are also routed through the formatter so they pick up CLDR locale data without the previous ZWNJ-marker hack in IsoDoc::I18n.

ARGS is a comma-separated list of either a positional numbering-system name (numeric, spellout, hanidec, roman, roman-lower) or key=value pairs. The only key currently honoured is cal= (japanese|gregorian); other CLDR calendar identifiers (roc, buddhist, persian, islamic, indian, hebrew) are reserved as documented extension points and raise NotImplementedError today.

Constant Summary collapse

TOKEN_RX =
/
  %_                                  |
  %\^?[BbhPpAa]                       |
  %E[YyC](?:\[[^\]]*\])?              |
  %O[mdYy](?:\[[^\]]*\])?
/x.freeze
DAY_KEYS =
%i[sun mon tue wed thu fri sat].freeze
HANIDEC_FROM =
"0123456789".freeze
HANIDEC_TO =
"〇一二三四五六七八九".freeze
SUPPORTED_CALENDARS =
%i[gregorian japanese].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(lang:, script: nil, calendar: nil, calendar_en: nil) ⇒ ExtendedDateFormatter

Returns a new instance of ExtendedDateFormatter.



73
74
75
76
77
78
# File 'lib/isodoc/extended_date.rb', line 73

def initialize(lang:, script: nil, calendar: nil, calendar_en: nil)
  @lang = lang.to_s
  @script = script
  @cal = calendar || twitter_cldr_calendar
  @cal_en = calendar_en || TwitterCldr::Shared::Calendar.new(:en)
end

Instance Attribute Details

#langObject (readonly)

Returns the value of attribute lang.



71
72
73
# File 'lib/isodoc/extended_date.rb', line 71

def lang
  @lang
end

#scriptObject (readonly)

Returns the value of attribute script.



71
72
73
# File 'lib/isodoc/extended_date.rb', line 71

def script
  @script
end

Class Method Details

.format(value, fmt, **opts) ⇒ Object



43
44
45
# File 'lib/isodoc/extended_date.rb', line 43

def self.format(value, fmt, **opts)
  new(**opts).format(value, fmt)
end

.format_iso_date(isodate, year: nil, year_month: nil, full: nil, **opts) ⇒ Object

Convenience wrapper for ISO 8601 date strings of variable arity (year-only, year-month, or full date). Picks one of three format strings keyed by the arity of the input. Each format string may be nil, in which case the input is returned unchanged for that arity. Used by metanorma-flavour metadata helpers to delegate their arity-branching logic instead of duplicating it per gem.



53
54
55
56
57
58
59
60
61
# File 'lib/isodoc/extended_date.rb', line 53

def self.format_iso_date(isodate, year: nil, year_month: nil, full: nil,
                         **opts)
  normalized, fmt = iso_normalize(isodate, [year, year_month, full])
  return isodate if fmt.nil?

  format(normalized, fmt, **opts)
rescue StandardError
  isodate
end

.iso_normalize(isodate, fmts) ⇒ Object



63
64
65
66
67
68
69
# File 'lib/isodoc/extended_date.rb', line 63

def self.iso_normalize(isodate, fmts)
  return [isodate, nil] if isodate.nil? || isodate.to_s.empty?

  parts = isodate.to_s.split("-")
  fmt = fmts[parts.size - 1] or return [isodate, nil]
  [[parts[0], parts[1] || "01", parts[2] || "01"].join("-"), fmt]
end

Instance Method Details

#format(value, fmt) ⇒ Object



80
81
82
83
# File 'lib/isodoc/extended_date.rb', line 80

def format(value, fmt)
  time = coerce(value)
  tokenise(fmt).map { |kind, payload| render(time, kind, payload) }.join
end