//
// Copyright (c) 2024, Brian Frank and Andy Frank
// Licensed under the Academic Free License version 3.0
//
// History:
// 10 Oct 2024 Matthew Giannini Creation
//
**
** Parser for inline content (text, links, emphasized text, etc.)
**
@Js
mixin InlineParser
{
** Parse the lines as inline and append resulting nodes to node (as children)
abstract Void parse(SourceLines lines, Node node)
}
**************************************************************************
** InlineParserContext
**************************************************************************
@Js
class InlineParserContext
{
internal new make(Parser parser, Definitions defs)
{
this.factories = parser.inlineContentParserFactories
this.customDelimiterProcessors = parser.delimiterProcessors
this.customLinkProcessors = parser.linkProcessors
this.customLinkMarkers = parser.linkMarkers
this.definitions = defs
}
const InlineContentParserFactory[] factories
const DelimiterProcessor[] customDelimiterProcessors
const LinkProcessor[] customLinkProcessors
const Int[] customLinkMarkers
internal Definitions definitions
** Lookup a definition of a type for a given label.
**
** Note that the label does not need to be normalized; implementations are
** responsible for doing this normalization before lookup.
Block? def(Type type, Str label) { definitions.def(type, label) }
}
**************************************************************************
** InlineParserState
**************************************************************************
@Js
mixin InlineParserState
{
** Return a scanner for the input for the current position (on the trigger
** character that the inline parser was added for).
**
** Note that this always returns the same instance, if you want to backtrack you
** need to use `Scanner.pos` and `Scanner.setPos`.
abstract Scanner? scanner()
}
**************************************************************************
** InlineContentParserFactory
**************************************************************************
**
** A factory for extending inline content parsing.
**
@Js
const mixin InlineContentParserFactory
{
** An inline content parser needs to have a special "trigger" character which
** activates it. When this character is encountered during inline parsing,
** `InlineContentParser.tryParse` is called wit hthe current parser state.
** It can also register for more than one trigger character
abstract Int[] triggerChars()
** Create an `InlineContentParser` that will do the parsing. Create is called
** once per text snippet of inline content inside block structures, and then
** called each time a trigger character is encountered.
abstract InlineContentParser create()
}
**************************************************************************
** InlineContentParser
**************************************************************************
** Parser for a type of inline content. Registered via a `InlineContentParserFactory`
** and created by its `InlineContentParserFactory.create` method. The lifetime of this is
** tied to each inline content snippet that is parsed, as a new instance is created for
** each.
@Js
mixin InlineContentParser
{
** Try to parse inline content starting from the current position. Note that the
** character at the current position is one of `InlineContentParserFactory.triggerChars`
** of the factory that created this parser.
**
** For a given inline content snippet that is being parsed, this method can be called
** multiple times: each time a trigger character is encountered.
**
** Return the result of parsing; can indicate that this parser is not interested,
** or that parsing was successful.
abstract ParsedInline? tryParse(InlineParserState inlineParserState)
}
**************************************************************************
** ParsedInline
**************************************************************************
@Js
class ParsedInline
{
static new none() { null }
static new of(Node node, Position pos) { ParsedInline.priv_make(node, pos) }
private new priv_make(Node node, Position pos)
{
this.node = node
this.pos = pos
}
Node node { private set }
const Position pos
}