11import Foundation
22@_implementationOnly import cmark_gfm
3+ @_implementationOnly import cmark_gfm_extensions
34
45extension Array where Element == BlockNode {
56 init ( markdown: String ) {
@@ -317,7 +318,7 @@ extension UnsafeNode {
317318 return node
318319 case . table( let columnAlignments, let rows) :
319320 guard let table = cmark_find_syntax_extension ( " table " ) ,
320- let node = cmark_node_new_with_ext ( CMARK_NODE_TABLE, table)
321+ let node = cmark_node_new_with_ext ( ExtensionNodeTypes . shared . CMARK_NODE_TABLE, table)
321322 else {
322323 return nil
323324 }
@@ -354,7 +355,7 @@ extension UnsafeNode {
354355
355356 fileprivate static func make( _ tableRow: RawTableRow ) -> UnsafeNode ? {
356357 guard let table = cmark_find_syntax_extension ( " table " ) ,
357- let node = cmark_node_new_with_ext ( CMARK_NODE_TABLE_ROW, table)
358+ let node = cmark_node_new_with_ext ( ExtensionNodeTypes . shared . CMARK_NODE_TABLE_ROW, table)
358359 else {
359360 return nil
360361 }
@@ -364,7 +365,7 @@ extension UnsafeNode {
364365
365366 fileprivate static func make( _ tableCell: RawTableCell ) -> UnsafeNode ? {
366367 guard let table = cmark_find_syntax_extension ( " table " ) ,
367- let node = cmark_node_new_with_ext ( CMARK_NODE_TABLE_CELL, table)
368+ let node = cmark_node_new_with_ext ( ExtensionNodeTypes . shared . CMARK_NODE_TABLE_CELL, table)
368369 else {
369370 return nil
370371 }
@@ -400,7 +401,8 @@ extension UnsafeNode {
400401 return node
401402 case . strikethrough( let children) :
402403 guard let strikethrough = cmark_find_syntax_extension ( " strikethrough " ) ,
403- let node = cmark_node_new_with_ext ( CMARK_NODE_STRIKETHROUGH, strikethrough)
404+ let node = cmark_node_new_with_ext (
405+ ExtensionNodeTypes . shared. CMARK_NODE_STRIKETHROUGH, strikethrough)
404406 else {
405407 return nil
406408 }
@@ -480,3 +482,34 @@ private struct UnsafeNodeSequence: Sequence {
480482 . init( self . node)
481483 }
482484}
485+
486+ // Extension node types are not exported in `cmark_gfm_extensions`,
487+ // so we need to look for them in the symbol table
488+ private struct ExtensionNodeTypes {
489+ let CMARK_NODE_TABLE : cmark_node_type
490+ let CMARK_NODE_TABLE_ROW : cmark_node_type
491+ let CMARK_NODE_TABLE_CELL : cmark_node_type
492+ let CMARK_NODE_STRIKETHROUGH : cmark_node_type
493+
494+ static let shared = ExtensionNodeTypes ( )
495+
496+ private init ( ) {
497+ func findNodeType( _ name: String , in handle: UnsafeMutableRawPointer ! ) -> cmark_node_type ? {
498+ guard let symbol = dlsym ( handle, name) else {
499+ return nil
500+ }
501+ return symbol. assumingMemoryBound ( to: cmark_node_type. self) . pointee
502+ }
503+
504+ let handle = dlopen ( nil , RTLD_LAZY)
505+
506+ self . CMARK_NODE_TABLE = findNodeType ( " CMARK_NODE_TABLE " , in: handle) ?? CMARK_NODE_NONE
507+ self . CMARK_NODE_TABLE_ROW = findNodeType ( " CMARK_NODE_TABLE_ROW " , in: handle) ?? CMARK_NODE_NONE
508+ self . CMARK_NODE_TABLE_CELL =
509+ findNodeType ( " CMARK_NODE_TABLE_CELL " , in: handle) ?? CMARK_NODE_NONE
510+ self . CMARK_NODE_STRIKETHROUGH =
511+ findNodeType ( " CMARK_NODE_STRIKETHROUGH " , in: handle) ?? CMARK_NODE_NONE
512+
513+ dlclose ( handle)
514+ }
515+ }
0 commit comments