1
1
import Foundation
2
2
@_implementationOnly import cmark_gfm
3
+ @_implementationOnly import cmark_gfm_extensions
3
4
4
5
extension Array where Element == BlockNode {
5
6
init ( markdown: String ) {
@@ -317,7 +318,7 @@ extension UnsafeNode {
317
318
return node
318
319
case . table( let columnAlignments, let rows) :
319
320
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)
321
322
else {
322
323
return nil
323
324
}
@@ -354,7 +355,7 @@ extension UnsafeNode {
354
355
355
356
fileprivate static func make( _ tableRow: RawTableRow ) -> UnsafeNode ? {
356
357
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)
358
359
else {
359
360
return nil
360
361
}
@@ -364,7 +365,7 @@ extension UnsafeNode {
364
365
365
366
fileprivate static func make( _ tableCell: RawTableCell ) -> UnsafeNode ? {
366
367
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)
368
369
else {
369
370
return nil
370
371
}
@@ -400,7 +401,8 @@ extension UnsafeNode {
400
401
return node
401
402
case . strikethrough( let children) :
402
403
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)
404
406
else {
405
407
return nil
406
408
}
@@ -480,3 +482,34 @@ private struct UnsafeNodeSequence: Sequence {
480
482
. init( self . node)
481
483
}
482
484
}
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