@@ -308,49 +308,14 @@ public struct HtmlRenderer: MarkupWalker {
308
308
public mutating func visitCodeBlock( _ codeBlock: CodeBlock ) {
309
309
let language = codeBlock. language ?? " "
310
310
logger. trace ( " Rendering code block with language: \( language) " )
311
- let ( filename, codeWithoutFilename) = extractFilename ( from: codeBlock. code, language: language)
312
311
313
- // Count the number of lines for line numbers - ensure we count the right number of lines
314
- // Handle empty lines at the end properly
315
- let lines = codeWithoutFilename. components ( separatedBy: . newlines)
316
- let lineCount = codeWithoutFilename. isEmpty ? 0 : ( codeWithoutFilename. hasSuffix ( " \n " ) ? lines. count - 1 : lines. count)
317
-
318
- // Build the HTML for the code block
319
- html += " <div class= \" code-block-wrapper \" > "
320
-
321
- // Add filename if available and enabled
322
- if showCodeFilename, let filename = filename {
323
- html += " <div class= \" code-language \" > \( filename) </div> "
324
- }
325
-
326
- // Add copy button if enabled
327
- if showCopyButton {
328
- html += " <button class= \" copy-button \" onclick= \" navigator.clipboard.writeText(this.parentElement.querySelector('code').innerText) \" >Copy</button> "
329
- }
330
-
331
- if showLineNumbers {
332
- // Generate line numbers HTML - ensure we have the right count
333
- let lineNumbersHTML = lineCount > 0
334
- ? ( 1 ... lineCount) . map { " <span> \( $0) </span> " } . joined ( separator: " \n " )
335
- : " <span>1</span> " // At least one line number for empty blocks
336
-
337
- html += " <pre class= \" line-numbers \" ><div class= \" line-numbers-container \" > \( lineNumbersHTML) </div> "
338
- } else {
339
- html += " <pre> "
340
- }
341
-
342
- // Add the code with syntax highlighting
343
- html += " <code class= \" language- \( language) \" > "
344
-
345
- if enableSyntaxHighlighting {
346
- html += applySyntaxHighlighting ( codeWithoutFilename, language: language)
347
- } else {
348
- // Escape HTML in the code to prevent injection if not highlighting
349
- html += escapeHTML ( codeWithoutFilename)
350
- }
312
+ // Simply extract the code content
313
+ let code = escapeHTML ( codeBlock. code)
351
314
315
+ // Build the basic HTML for the code block
316
+ html += " <pre><code> "
317
+ html += code
352
318
html += " </code></pre> "
353
- html += " </div> "
354
319
}
355
320
356
321
/// Visits an inline code node and generates corresponding HTML.
@@ -525,304 +490,5 @@ public struct HtmlRenderer: MarkupWalker {
525
490
526
491
527
492
528
- /// Applies syntax highlighting to the given code in the given language.
529
- /// Apply syntax highlighting based on the language type
530
- private func applySyntaxHighlighting( _ code: String , language: String ) -> String {
531
- switch language. lowercased ( ) {
532
- case " swift " : return highlightSwift ( code)
533
- case " sh " , " bash " , " shell " : return highlightShell ( code)
534
- case " js " , " javascript " : return applyJavaScriptHighlighting ( code)
535
- case " yaml " , " yml " : return highlightYAML ( code)
536
- default : return escapeHTML ( code)
537
- }
538
- }
539
-
540
- /// Wraps code lines in spans and generates line numbers HTML.
541
- ///
542
- /// - Parameter code: The code to wrap.
543
- /// - Returns: A tuple containing the wrapped code lines and the HTML for line numbers.
544
- public func wrapWithLineNumbers( _ code: String ) -> ( String , String ) {
545
- let lines = code. components ( separatedBy: . newlines)
546
- let linesHTML = lines. map { " <span class= \" code-line \" > \( $0) </span> " } . joined ( separator: " \n " )
547
- let numbersHTML = ( 1 ... lines. count) . map { " <span class= \" line-number \" > \( $0) </span> " } . joined ( separator: " \n " )
548
- return ( linesHTML, numbersHTML)
549
- }
550
-
551
- /// Applies JavaScript syntax highlighting to the code.
552
- ///
553
- /// - Parameter code: The code to highlight.
554
- /// - Returns: The HTML string with syntax highlighting.
555
- private func applyJavaScriptHighlighting( _ code: String ) -> String {
556
- let keywords = [ " var " , " let " , " const " , " function " , " class " , " if " , " else " , " for " , " while " , " do " , " switch " , " case " , " default " , " break " , " continue " , " return " , " try " , " catch " , " finally " , " throw " , " new " , " this " , " super " , " extends " , " static " , " import " , " export " , " from " , " as " , " async " , " await " , " yield " ]
557
- let types = [ " String " , " Number " , " Boolean " , " Object " , " Array " , " Symbol " , " undefined " , " null " , " true " , " false " ]
558
-
559
- var highlighted = escapeHTML ( code)
560
-
561
- // Highlight keywords
562
- for keyword in keywords {
563
- let pattern = " \\ b \( keyword) \\ b "
564
- highlighted = highlighted. replacingOccurrences (
565
- of: pattern,
566
- with: " <span class= \" hl-keyword \" > \( keyword) </span> " ,
567
- options: [ . regularExpression]
568
- )
569
- }
570
-
571
- // Highlight types
572
- for type in types {
573
- let pattern = " \\ b \( type) \\ b "
574
- highlighted = highlighted. replacingOccurrences (
575
- of: pattern,
576
- with: " <span class= \" hl-type \" > \( type) </span> " ,
577
- options: [ . regularExpression]
578
- )
579
- }
580
-
581
- // Highlight string literals (handle both single and double quotes)
582
- let doubleQuotePattern = " "[^" \\ \\ ]*( \\ \\ .[^" \\ \\ ]*)*" "
583
- highlighted = highlighted. replacingOccurrences (
584
- of: doubleQuotePattern,
585
- with: " <span class= \" hl-string \" >$0</span> " ,
586
- options: [ . regularExpression]
587
- )
588
-
589
- let singleQuotePattern = " '[^' \\ \\ ]*( \\ \\ .[^' \\ \\ ]*)*' "
590
- highlighted = highlighted. replacingOccurrences (
591
- of: singleQuotePattern,
592
- with: " <span class= \" hl-string \" >$0</span> " ,
593
- options: [ . regularExpression]
594
- )
595
-
596
- // Highlight numbers
597
- let numberPattern = " \\ b \\ d+( \\ . \\ d+)? \\ b "
598
- highlighted = highlighted. replacingOccurrences (
599
- of: numberPattern,
600
- with: " <span class= \" hl-number \" >$0</span> " ,
601
- options: [ . regularExpression]
602
- )
603
-
604
- // Highlight comments
605
- let lineCommentPattern = " //.*?$ "
606
- highlighted = highlighted. replacingOccurrences (
607
- of: lineCommentPattern,
608
- with: " <span class= \" hl-comment \" >$0</span> " ,
609
- options: [ . regularExpression]
610
- )
611
-
612
- return highlighted
613
- }
614
-
615
- /// Highlights shell script code.
616
- ///
617
- /// - Parameter code: The code string.
618
- /// - Returns: The HTML string with shell syntax highlighting.
619
- public func highlightShell( _ code: String ) -> String {
620
- let keywords = [ " if " , " then " , " else " , " fi " , " for " , " in " , " do " , " done " , " while " , " case " , " esac " , " function " , " echo " , " exit " ]
621
- let literals = [ " true " , " false " , " null " ]
622
- let commands = [ " cd " , " pwd " , " ls " , " mkdir " , " rm " , " cp " , " mv " , " cat " , " grep " , " find " , " sed " , " awk " , " curl " , " wget " , " sudo " , " chmod " , " chown " , " export " , " source " , " touch " , " git " , " ssh " , " tar " , " unzip " , " ssh-keygen " , " ssh-add " , " eval " , " printf " , " cat " , " pbcopy " ]
623
-
624
- var highlighted = escapeHTML ( code)
625
-
626
- // First handle comments to avoid highlighting inside them
627
- let commentPattern = " #.*?$ "
628
- highlighted = highlighted. replacingOccurrences (
629
- of: commentPattern,
630
- with: " <span class= \" hl-comment \" >$0</span> " ,
631
- options: [ . regularExpression]
632
- )
633
-
634
- // Highlight strings (single and double quotes)
635
- let doubleQuotePattern = " (")(?:[^" \\ \\ ]| \\ \\ .| \\ \\ \\ n)*?(") "
636
- highlighted = highlighted. replacingOccurrences (
637
- of: doubleQuotePattern,
638
- with: " <span class= \" hl-string \" >$0</span> " ,
639
- options: [ . regularExpression]
640
- )
641
-
642
- let singleQuotePattern = " (')(?:[^' \\ \\ ]| \\ \\ .| \\ \\ \\ n)*?(') "
643
- highlighted = highlighted. replacingOccurrences (
644
- of: singleQuotePattern,
645
- with: " <span class= \" hl-string \" >$0</span> " ,
646
- options: [ . regularExpression]
647
- )
648
-
649
- // Highlight variables (do this before commands to avoid issues)
650
- let variablePattern = " \\ $ \\ {?[A-Za-z0-9_]+ \\ }? "
651
- highlighted = highlighted. replacingOccurrences (
652
- of: variablePattern,
653
- with: " <span class= \" hl-variable \" >$0</span> " ,
654
- options: [ . regularExpression]
655
- )
656
-
657
- // Highlight commands - only at beginning of lines or after specific shell operators
658
- for command in commands {
659
- // Match command only at start of line or after pipe, semicolon, ampersand, or parentheses
660
- let pattern = " (^| \\ s|;| \\ ||&| \\ (| \\ `| \\ $ \\ () \\ s* \\ b( \( command) ) \\ b "
661
- highlighted = highlighted. replacingOccurrences (
662
- of: pattern,
663
- with: " $1<span class= \" hl-command \" >$2</span> " ,
664
- options: [ . regularExpression]
665
- )
666
- }
667
-
668
- // Highlight keywords
669
- for keyword in keywords {
670
- let pattern = " \\ b \( keyword) \\ b "
671
- highlighted = highlighted. replacingOccurrences (
672
- of: pattern,
673
- with: " <span class= \" hl-keyword \" > \( keyword) </span> " ,
674
- options: [ . regularExpression]
675
- )
676
- }
677
-
678
- // Highlight literals
679
- for literal in literals {
680
- let pattern = " \\ b \( literal) \\ b "
681
- highlighted = highlighted. replacingOccurrences (
682
- of: pattern,
683
- with: " <span class= \" hl-literal \" > \( literal) </span> " ,
684
- options: [ . regularExpression]
685
- )
686
- }
687
-
688
- return highlighted
689
- }
690
-
691
- /// Highlights Swift code.
692
- ///
693
- /// - Parameter code: The code string.
694
- /// - Returns: The HTML string with Swift syntax highlighting.
695
- public func highlightSwift( _ code: String ) -> String {
696
- let keywords = [ " class " , " struct " , " enum " , " protocol " , " extension " , " func " , " var " , " let " , " if " , " else " , " guard " , " return " , " for " , " while " , " in " , " switch " , " case " , " break " , " default " , " where " , " self " , " init " , " deinit " , " get " , " set " , " public " , " private " , " internal " , " fileprivate " , " open " , " import " , " typealias " , " associatedtype " , " try " , " catch " , " throws " , " rethrows " , " throw " , " async " , " await " , " actor " , " main " ]
697
- let types = [ " String " , " Int " , " Double " , " Float " , " Bool " , " Character " , " Array " , " Dictionary " , " Set " , " Optional " , " Any " , " AnyObject " , " Void " , " Never " , " Result " , " Date " , " URL " , " Data " , " Error " ]
698
-
699
- var highlighted = escapeHTML ( code)
700
-
701
- // Process comments first to avoid highlighting inside comments
702
- let commentPattern = " //.*?$ "
703
- highlighted = highlighted. replacingOccurrences (
704
- of: commentPattern,
705
- with: " <span class= \" hl-comment \" >$0</span> " ,
706
- options: [ . regularExpression]
707
- )
708
-
709
- // Highlight string literals with better regex
710
- let stringPattern = " (")(?:[^" \\ \\ ]| \\ \\ .| \\ \\ \\ n)*?(") "
711
- highlighted = highlighted. replacingOccurrences (
712
- of: stringPattern,
713
- with: " <span class= \" hl-string \" >$0</span> " ,
714
- options: [ . regularExpression]
715
- )
716
-
717
- // Highlight numbers
718
- let numberPattern = " \\ b \\ d+( \\ . \\ d+)? \\ b "
719
- highlighted = highlighted. replacingOccurrences (
720
- of: numberPattern,
721
- with: " <span class= \" hl-number \" >$0</span> " ,
722
- options: [ . regularExpression]
723
- )
724
-
725
- // Highlight keywords
726
- for keyword in keywords {
727
- let pattern = " \\ b \( keyword) \\ b "
728
- highlighted = highlighted. replacingOccurrences (
729
- of: pattern,
730
- with: " <span class= \" hl-keyword \" > \( keyword) </span> " ,
731
- options: [ . regularExpression]
732
- )
733
- }
734
-
735
- // Highlight types
736
- for type in types {
737
- let pattern = " \\ b \( type) \\ b "
738
- highlighted = highlighted. replacingOccurrences (
739
- of: pattern,
740
- with: " <span class= \" hl-type \" > \( type) </span> " ,
741
- options: [ . regularExpression]
742
- )
743
- }
744
-
745
- // Highlight symbol names (after struct, class, enum declarations)
746
- let symbolPattern = " (?<= \\ b(?:struct|class|enum|protocol|typealias|actor) \\ s+) \\ b([A-Za-z][A-Za-z0-9_]*) \\ b "
747
- highlighted = highlighted. replacingOccurrences (
748
- of: symbolPattern,
749
- with: " <span class= \" hl-type \" >$1</span> " ,
750
- options: [ . regularExpression]
751
- )
752
-
753
- // Highlight function names
754
- let functionPattern = " (?<= \\ bfunc \\ s+) \\ b([A-Za-z][A-Za-z0-9_]*) \\ b "
755
- highlighted = highlighted. replacingOccurrences (
756
- of: functionPattern,
757
- with: " <span class= \" hl-function \" >$1</span> " ,
758
- options: [ . regularExpression]
759
- )
760
-
761
- // Highlight conformance types (after : in declarations)
762
- let conformancePattern = " (?<=: \\ s*)([A-Za-z][A-Za-z0-9_]*(?: \\ s*, \\ s*[A-Za-z][A-Za-z0-9_]*)*) "
763
- highlighted = highlighted. replacingOccurrences (
764
- of: conformancePattern,
765
- with: " <span class= \" hl-type \" >$1</span> " ,
766
- options: [ . regularExpression]
767
- )
768
-
769
- return highlighted
770
- }
771
-
772
- /// Highlights YAML code.
773
- ///
774
- /// - Parameter code: The code string.
775
- /// - Returns: The HTML string with YAML syntax highlighting.
776
- public func highlightYAML( _ code: String ) -> String {
777
- var highlighted = escapeHTML ( code)
778
-
779
- // Highlight keys
780
- let keyPattern = " ^ \\ s*([ \\ w \\ - \\ .]+): "
781
- highlighted = highlighted. replacingOccurrences (
782
- of: keyPattern,
783
- with: " <span class= \" hl-attribute \" >$1</span>: " ,
784
- options: [ . regularExpression]
785
- )
786
-
787
- // Highlight string literals
788
- let doubleQuotePattern = " "[^" \\ \\ ]*( \\ \\ .[^" \\ \\ ]*)*" "
789
- highlighted = highlighted. replacingOccurrences (
790
- of: doubleQuotePattern,
791
- with: " <span class= \" hl-string \" >$0</span> " ,
792
- options: [ . regularExpression]
793
- )
794
-
795
- let singleQuotePattern = " '[^' \\ \\ ]*( \\ \\ .[^' \\ \\ ]*)*' "
796
- highlighted = highlighted. replacingOccurrences (
797
- of: singleQuotePattern,
798
- with: " <span class= \" hl-string \" >$0</span> " ,
799
- options: [ . regularExpression]
800
- )
801
-
802
- // Highlight numbers
803
- let numberPattern = " \\ b \\ d+( \\ . \\ d+)? \\ b "
804
- highlighted = highlighted. replacingOccurrences (
805
- of: numberPattern,
806
- with: " <span class= \" hl-number \" >$0</span> " ,
807
- options: [ . regularExpression]
808
- )
809
-
810
- // Highlight booleans and null
811
- let literalPattern = " \\ b(true|false|null) \\ b "
812
- highlighted = highlighted. replacingOccurrences (
813
- of: literalPattern,
814
- with: " <span class= \" hl-literal \" >$0</span> " ,
815
- options: [ . regularExpression, . caseInsensitive]
816
- )
817
-
818
- // Highlight comments
819
- let commentPattern = " #.*?$ "
820
- highlighted = highlighted. replacingOccurrences (
821
- of: commentPattern,
822
- with: " <span class= \" hl-comment \" >$0</span> " ,
823
- options: [ . regularExpression]
824
- )
825
-
826
- return highlighted
827
- }
493
+ // Removed syntax highlighting functions
828
494
}
0 commit comments