11import CodeParserCore
22import Foundation
33
4- /// Main construction state for Markdown language with line-based processing
4+ /// Minimal construction state for Markdown language
5+ /// Only contains state that cannot be derived from the AST (context.current)
56public class MarkdownConstructState : CodeConstructState {
67 public typealias Node = MarkdownNodeElement
78 public typealias Token = MarkdownTokenElement
89
9- // Current token index in the line
10- public var position : Int = 0
11- // Flag indicates if the block builders should run another round on the same line.
12- public var refreshed : Bool = false
13- // Flag indicates if the current line is being reprocessed after partial consumption
14- public var isPartialLine : Bool = false
15-
16- // Fenced code block state
17- public var openFence : OpenFenceInfo ?
18-
19- // HTML block state
20- public var openHTMLBlock : OpenHTMLBlockInfo ?
21-
22- /// Stack for nested list processing
23- public var listStack : [ ListNode ] = [ ]
24- public var currentDefinitionList : DefinitionListNode ?
25-
26- /// Enhanced list context tracking for better indentation and nesting management
27- public var listContextStack : [ ListContextInfo ] = [ ]
28-
29- /// Indicates the last consumed line break formed a blank line (two or more consecutive newlines)
30- public var lastWasBlankLine : Bool = false
31-
32- /// When a quoted blank line (`>\\n`) is seen inside a blockquote, the next quoted
33- /// content should start a new paragraph inside the same blockquote instead of
34- /// merging into the previous one.
35- public var pendingBlockquoteParagraphSplit : Bool = false
36-
37- /// True when the previous quoted line (inside a blockquote) began with a token
38- /// that could start a block (e.g., `#`, `-`, `*`, `+`, number.). We use this to
39- /// prevent merging the next quoted line into the same paragraph, matching CommonMark
40- /// semantics where block-starting constructs introduce a new block.
41- public var prevBlockquoteLineWasBlockStart : Bool = false
42-
4310 /// Reference link definitions storage for resolving reference links
4411 /// Key is normalized reference identifier (case-insensitive, whitespace collapsed)
12+ /// Note: This cannot be derived from AST since reference definitions may appear
13+ /// anywhere in the document and need to be available for link resolution
4514 public var referenceDefinitions : [ String : ( url: String , title: String ) ] = [ : ]
46-
47- /// Pending reference link definition being parsed across multiple lines
48- public var pendingReference : PendingReferenceDefinition ?
15+
16+ /// Current line tokens being processed - builders can modify these
17+ /// This allows builders to consume their part and leave remaining tokens for further processing
18+ public var tokens : [ any CodeToken < MarkdownTokenElement > ] = [ ]
19+
20+ /// Flag indicating if current line has been fully processed by a builder
21+ /// When false, MarkdownBlockBuilder should continue processing the remaining tokens
22+ public var currentLineProcessed : Bool = true
4923
5024 public init ( ) { }
5125
@@ -72,85 +46,3 @@ public class MarkdownConstructState: CodeConstructState {
7246 . trimmingCharacters ( in: . whitespacesAndNewlines)
7347 }
7448}
75-
76- /// Information about a pending reference link definition being parsed across multiple lines
77- public struct PendingReferenceDefinition {
78- public let identifier : String
79- public let referenceNode : ReferenceNode
80- public var hasDestination : Bool
81- public var hasTitle : Bool
82- public let originalLineTokens : [ any CodeToken < MarkdownTokenElement > ] // For fallback to paragraph
83-
84- public init ( identifier: String , referenceNode: ReferenceNode , originalLineTokens: [ any CodeToken < MarkdownTokenElement > ] ) {
85- self . identifier = identifier
86- self . referenceNode = referenceNode
87- self . hasDestination = false
88- self . hasTitle = false
89- self . originalLineTokens = originalLineTokens
90- }
91- }
92-
93- /// Information about an open fenced code block
94- public struct OpenFenceInfo {
95- public let character : String
96- public let length : Int
97- public let indentation : Int
98- public let codeBlock : CodeBlockNode
99-
100- public init ( character: String , length: Int , indentation: Int , codeBlock: CodeBlockNode ) {
101- self . character = character
102- self . length = length
103- self . indentation = indentation
104- self . codeBlock = codeBlock
105- }
106- }
107-
108- /// Information about an open HTML block
109- public struct OpenHTMLBlockInfo {
110- public let type : Int // HTML block type (1-7)
111- public let endCondition : String ? // What string ends this block
112- public let htmlBlock : HTMLBlockNode
113-
114- public init ( type: Int , endCondition: String ? , htmlBlock: HTMLBlockNode ) {
115- self . type = type
116- self . endCondition = endCondition
117- self . htmlBlock = htmlBlock
118- }
119- }
120-
121- /// Information about detected HTML block type
122- public struct HTMLBlockTypeInfo {
123- public let type : Int
124- public let name : String
125- public let closedOnSameLine : Bool
126- public let endCondition : String ?
127-
128- public init ( type: Int , name: String , closedOnSameLine: Bool , endCondition: String ? = nil ) {
129- self . type = type
130- self . name = name
131- self . closedOnSameLine = closedOnSameLine
132- self . endCondition = endCondition
133- }
134- }
135-
136- /// Enhanced list context information for better nesting and indentation management
137- public struct ListContextInfo {
138- /// The list node itself
139- public let list : ListNode
140- /// The parent list item that contains this list (nil for top-level lists)
141- public let parentListItem : ListItemNode ?
142- /// The calculated indentation level for content in this list context
143- public let contentIndent : Int
144- /// The nesting level (1 for top-level, 2 for first nested, etc.)
145- public let level : Int
146- /// The marker type for compatibility checking
147- public let markerType : String
148-
149- public init ( list: ListNode , parentListItem: ListItemNode ? , contentIndent: Int , level: Int , markerType: String ) {
150- self . list = list
151- self . parentListItem = parentListItem
152- self . contentIndent = contentIndent
153- self . level = level
154- self . markerType = markerType
155- }
156- }
0 commit comments