Class: Markbridge::Parsers::TextFormatter::HandlerRegistry

Inherits:
Object
  • Object
show all
Defined in:
lib/markbridge/parsers/text_formatter/handler_registry.rb

Overview

Registry of s9e/TextFormatter XML element handlers

Manages mappings between XML element names and handler objects. Handlers must respond to #process(element:, parent:) and return the created element if children should be processed, or nil otherwise.

Examples:

Using default mappings

registry = HandlerRegistry.default
element = registry.process_element(xml_element, parent)

Customizing mappings with handler objects

registry = HandlerRegistry.build_from_default do |r|
  r.register("CUSTOM", MyCustomHandler.new)
  r.register("B", SimpleHandler.new(AST::Bold))  # Override default
end

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeHandlerRegistry

Returns a new instance of HandlerRegistry.



35
36
37
# File 'lib/markbridge/parsers/text_formatter/handler_registry.rb', line 35

def initialize
  @mappings = {}
end

Class Method Details

.build_from_default {|HandlerRegistry| ... } ⇒ HandlerRegistry

Build from default mappings with custom additions

Yields:

Returns:



31
32
33
# File 'lib/markbridge/parsers/text_formatter/handler_registry.rb', line 31

def self.build_from_default
  default.tap { |registry| yield registry if block_given? }
end

.defaultHandlerRegistry

Create a new registry with default mappings

Returns:



24
25
26
# File 'lib/markbridge/parsers/text_formatter/handler_registry.rb', line 24

def self.default
  new.tap(&:register_defaults)
end

Instance Method Details

#[](element_name) ⇒ #process?

Look up the handler for an element name (case-insensitive).

Parameters:

  • element_name (String)

Returns:

  • (#process, nil)


49
50
51
# File 'lib/markbridge/parsers/text_formatter/handler_registry.rb', line 49

def [](element_name)
  @mappings[element_name.upcase]
end

#has_handler?(element_name) ⇒ Boolean

Check if a handler is registered for an element

Parameters:

  • element_name (String)

    XML element name

Returns:

  • (Boolean)

    true if handler is registered



71
72
73
# File 'lib/markbridge/parsers/text_formatter/handler_registry.rb', line 71

def has_handler?(element_name)
  @mappings.key?(element_name.upcase)
end

#overlay(element_names) {|previous| ... } ⇒ self

Replace the handler bound to one or more element names by yielding the previously-bound handler (which may be nil) and registering whatever the block returns.

Parameters:

  • element_names (String, Array<String>)

Yield Parameters:

  • previous (#process, nil)

Returns:

  • (self)


60
61
62
63
64
65
66
# File 'lib/markbridge/parsers/text_formatter/handler_registry.rb', line 60

def overlay(element_names)
  Array(element_names).each do |name|
    previous = self[name]
    register(name, yield(previous))
  end
  self
end

#process_element(element, parent, processor) ⇒ AST::Element?

Process an XML element using the registered handler

Parameters:

  • element (Nokogiri::XML::Element)
  • parent (AST::Element)

    parent node to add children to

  • processor (Parser)

    the parser, exposed to handlers so they can call back into process_children for nested content

Returns:

  • (AST::Element, nil)

    the created element if children should be processed, nil otherwise



81
82
83
84
# File 'lib/markbridge/parsers/text_formatter/handler_registry.rb', line 81

def process_element(element, parent, processor)
  handler = self[element.name]
  handler&.process(element:, parent:, processor:)
end

#register(element_name, handler) ⇒ Object

Register a handler for an element

Parameters:

  • element_name (String)

    XML element name (case-insensitive)

  • handler (#process)

    Handler object responding to ‘process(element:, parent:)`



42
43
44
# File 'lib/markbridge/parsers/text_formatter/handler_registry.rb', line 42

def register(element_name, handler)
  @mappings[element_name.upcase] = handler
end

#register_defaultsObject

Register all default s9e/TextFormatter element mappings



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/markbridge/parsers/text_formatter/handler_registry.rb', line 87

def register_defaults
  # Simple formatting elements
  register("B", Handlers::SimpleHandler.new(AST::Bold))
  register("I", Handlers::SimpleHandler.new(AST::Italic))
  register("U", Handlers::SimpleHandler.new(AST::Underline))
  register("S", Handlers::SimpleHandler.new(AST::Strikethrough))

  # Complex elements with attributes
  register("URL", Handlers::UrlHandler.new)
  register("EMAIL", Handlers::EmailHandler.new)
  register("CODE", Handlers::CodeHandler.new)
  register("QUOTE", Handlers::QuoteHandler.new)
  register("IMG", Handlers::ImageHandler.new)
  register("LIST", Handlers::ListHandler.new)
  register("COLOR", Handlers::AttributeHandler.new(AST::Color, attribute: :color))
  register("SIZE", Handlers::AttributeHandler.new(AST::Size, attribute: :size))
  register(
    "ALIGN",
    Handlers::AttributeHandler.new(AST::Align, attribute: :align, param: :alignment),
  )
  register("SPOILER", Handlers::AttributeHandler.new(AST::Spoiler, attribute: :title))
  register("ATTACHMENT", Handlers::AttachmentHandler.new)
  register("ATTACH", Handlers::AttachmentHandler.new)

  # List item (supports both LI and * for compatibility)
  register("LI", Handlers::SimpleHandler.new(AST::ListItem))
  register("*", Handlers::SimpleHandler.new(AST::ListItem))

  # Paragraphs
  register("P", Handlers::SimpleHandler.new(AST::Paragraph))

  # Table elements
  register("TABLE", Handlers::SimpleHandler.new(AST::Table))
  register("TR", Handlers::SimpleHandler.new(AST::TableRow))
  register("TD", Handlers::TableCellHandler.new)
  register("TH", Handlers::TableCellHandler.new)
end