Packages
Multi-surface application runtime for Elixir. One TEA module renders to terminal, browser (LiveView), SSH, and MCP (agents). 30+ widgets, flexbox + CSS grid, AI agent runtime, distributed swarm with CRDTs, time-travel debugging, session recording, sandboxed REPL, and agentic commerce.
Current section
Files
Jump to
Current section
Files
lib/raxol/terminal/ansi/sequence_parser.ex
defmodule Raxol.Terminal.ANSI.SequenceParser do
@moduledoc """
Helper module for parsing ANSI escape sequences.
This module provides common utilities for parsing and handling ANSI sequences,
extracted from duplicate implementations in other ANSI-related modules.
"""
@doc """
Parses parameters from an ANSI sequence.
Splits the parameter string by semicolons and converts them to integers.
## Returns
* `{:ok, params}` - Successfully parsed parameters
* `:error` - Failed to parse parameters
"""
@spec parse_params(binary()) :: {:ok, list(integer())} | :error
def parse_params(params) do
case String.split(params, ";", trim: true) do
[] ->
{:ok, []}
param_strings ->
case Enum.map(param_strings, &Integer.parse/1) do
list when length(list) == length(param_strings) ->
{:ok, Enum.map(list, fn {num, _} -> num end)}
_ ->
:error
end
end
end
@doc """
Generic parser for ANSI sequences that follow the pattern: params + operation code.
## Parameters
* `sequence` - The binary sequence to parse
* `operation_decoder` - Function to decode operation from character code
## Returns
* `{:ok, operation, params}` - Successfully parsed sequence
* `:error` - Failed to parse sequence
"""
@spec parse_sequence(binary(), function()) ::
{:ok, atom(), list(integer())} | :error
def parse_sequence(sequence, operation_decoder) do
with [param_string, command_char] <-
Regex.run(~r/^([0-9;]*)([a-zA-Z])$/, sequence,
capture: :all_but_first
),
true <- String.length(command_char) == 1,
{:ok, parsed_params} <- parse_params(param_string) do
operation_code = :binary.first(command_char)
{:ok, operation_decoder.(operation_code), parsed_params}
else
_ -> :error
end
end
end