@@ -78,6 +78,7 @@ class Settings {
78
78
@objc var customCSSOverride : Bool = false
79
79
@objc var openInlineLink : Bool = false
80
80
81
+ @objc var renderAsCode : Bool = false
81
82
@objc var debug : Bool = false
82
83
83
84
@@ -250,6 +251,9 @@ class Settings {
250
251
if let opt = defaultsDomain [ " inline-link " ] as? Bool {
251
252
openInlineLink = opt
252
253
}
254
+ if let opt = defaultsDomain [ " render-as-code " ] as? Bool {
255
+ renderAsCode = opt
256
+ }
253
257
254
258
sanitizeEmojiOption ( )
255
259
}
@@ -307,6 +311,7 @@ class Settings {
307
311
self . openInlineLink = s. openInlineLink
308
312
309
313
self . debug = s. debug
314
+ self . renderAsCode = s. renderAsCode
310
315
311
316
DistributedNotificationCenter . default ( ) . post ( name: . QLMarkdownSettingsUpdated, object: nil )
312
317
}
@@ -445,7 +450,60 @@ class Settings {
445
450
return " ```yaml \n " + text+ " ``` \n "
446
451
}
447
452
453
+ func renderCode( text: String , forAppearance appearance: Appearance , baseDir: String , log: OSLog ? = nil ) -> String ? {
454
+
455
+ if let path = getHighlightSupportPath ( ) {
456
+ cmark_syntax_highlight_init ( " \( path) / " . cString ( using: . utf8) )
457
+ } else {
458
+ if let l = log {
459
+ os_log ( " Unable to found the `highlight` support dir! " , log: l, type: . error)
460
+ }
461
+ }
462
+
463
+ let theme : String
464
+ switch appearance {
465
+ case . light:
466
+ theme = self . syntaxThemeLight
467
+ case . dark:
468
+ theme = self . syntaxThemeDark
469
+ case . undefined:
470
+ let mode = UserDefaults . standard. string ( forKey: " AppleInterfaceStyle " ) ?? " Light "
471
+ if mode == " Light " {
472
+ theme = self . syntaxThemeLight
473
+ } else {
474
+ theme = self . syntaxThemeDark
475
+ }
476
+ }
477
+
478
+ // Initialize a new generator and clear previous settings.
479
+ highlight_init_generator ( )
480
+
481
+ highlight_set_print_line_numbers ( self . syntaxLineNumbersOption ? 1 : 0 )
482
+ highlight_set_formatting_mode ( Int32 ( self . syntaxWordWrapOption) , Int32 ( self . syntaxTabsOption) )
483
+
484
+ if !self . syntaxFontFamily. isEmpty {
485
+ highlight_set_current_font ( self . syntaxFontFamily, self . syntaxFontSize > 0 ? String ( format: " %.02f " , self . syntaxFontSize) : " 1rem " ) // 1rem is rendered as 1rempt, so it is ignored.
486
+ } else {
487
+ highlight_set_current_font ( " ui-monospace, -apple-system, BlinkMacSystemFont, sans-serif " , " 10 " ) ;
488
+ }
489
+
490
+ if let s = colorizeCode ( text, " md " , theme, true , self . syntaxLineNumbersOption) {
491
+ defer {
492
+ s. deallocate ( )
493
+ }
494
+ let code = String ( cString: s)
495
+ return code
496
+ } else {
497
+ return nil
498
+ }
499
+ }
500
+
448
501
func render( text: String , filename: String , forAppearance appearance: Appearance , baseDir: String , log: OSLog ? = nil ) throws -> String {
502
+
503
+ if self . renderAsCode, let code = self . renderCode ( text: text, forAppearance: appearance, baseDir: baseDir, log: log) {
504
+ return code
505
+ }
506
+
449
507
cmark_gfm_core_extensions_ensure_registered ( )
450
508
451
509
var options = CMARK_OPT_DEFAULT
@@ -912,7 +970,8 @@ table.debug td {
912
970
}
913
971
}
914
972
915
- func getCompleteHTML( title: String , body: String , header: String = " " , footer: String = " " , basedir: URL ) -> String {
973
+ func getCompleteHTML( title: String , body: String , header: String = " " , footer: String = " " , basedir: URL , forAppearance appearance: Appearance ) -> String {
974
+
916
975
let css_doc : String
917
976
let css_doc_extended : String
918
977
@@ -923,40 +982,81 @@ table.debug td {
923
982
return " <style type='text/css'> \( css) \n </style> \n "
924
983
}
925
984
926
- if let css = self . getCustomCSSCode ( ) {
927
- css_doc_extended = formatCSS ( css)
928
- if !self . customCSSOverride {
929
- css_doc = formatCSS ( getBundleContents ( forResource: " default " , ofType: " css " ) )
985
+ if !self . renderAsCode {
986
+ if let css = self . getCustomCSSCode ( ) {
987
+ css_doc_extended = formatCSS ( css)
988
+ if !self . customCSSOverride {
989
+ css_doc = formatCSS ( getBundleContents ( forResource: " default " , ofType: " css " ) )
990
+ } else {
991
+ css_doc = " "
992
+ }
930
993
} else {
931
- css_doc = " "
994
+ css_doc_extended = " "
995
+ css_doc = formatCSS ( getBundleContents ( forResource: " default " , ofType: " css " ) )
932
996
}
997
+ // css_doc = "<style type=\"text/css\">\n\(css_doc)\n</style>\n"
933
998
} else {
934
999
css_doc_extended = " "
935
- css_doc = formatCSS ( getBundleContents ( forResource : " default " , ofType : " css " ) )
1000
+ css_doc = " "
936
1001
}
937
- // css_doc = "<style type=\"text/css\">\n\(css_doc)\n</style>\n"
938
1002
939
1003
var css_highlight : String = " "
940
- if self . syntaxHighlightExtension, let ext = cmark_find_syntax_extension ( " syntaxhighlight " ) , cmark_syntax_extension_highlight_get_rendered_count ( ext) > 0 {
1004
+ if self . renderAsCode {
1005
+ let theme : String
1006
+ var background : String = " "
1007
+ switch appearance {
1008
+ case . light:
1009
+ theme = self . syntaxThemeLight
1010
+ case . dark:
1011
+ theme = self . syntaxThemeDark
1012
+ case . undefined:
1013
+ let mode = UserDefaults . standard. string ( forKey: " AppleInterfaceStyle " ) ?? " Light "
1014
+ if mode == " Light " {
1015
+ theme = self . syntaxThemeLight
1016
+ } else {
1017
+ theme = self . syntaxThemeDark
1018
+ }
1019
+ }
1020
+ var release : ReleaseTheme ?
1021
+ var exit_code : Int32 = 0
1022
+ if let theme = highlight_get_theme2 ( theme, & exit_code, & release) {
1023
+ defer {
1024
+ release ? ( theme)
1025
+ }
1026
+ if let s = theme. pointee. canvas? . pointee. color {
1027
+ background = String ( cString: s)
1028
+ }
1029
+ }
1030
+ exit_code = 0
1031
+ if let p = highlight_format_style2 ( & exit_code, background) {
1032
+ css_highlight = String ( cString: p) + " \n pre.hl { white-space: pre; } \n "
1033
+ p. deallocate ( )
1034
+ }
1035
+ } else if self . syntaxHighlightExtension, let ext = cmark_find_syntax_extension ( " syntaxhighlight " ) , cmark_syntax_extension_highlight_get_rendered_count ( ext) > 0 {
941
1036
let theme = String ( cString: cmark_syntax_extension_highlight_get_theme_name ( ext) )
942
1037
if !theme. isEmpty, let p = cmark_syntax_extension_get_style ( ext) {
943
1038
// Embed the theme style.
944
- let font = self . syntaxFontFamily
945
1039
css_highlight = String ( cString: p)
946
- if font != " " {
947
- css_highlight += """
948
- :root {
949
- --code-font: " \( font) " , -apple-system, Menlo, monospace;
950
- }
951
- """ ;
952
- }
953
- css_highlight = formatCSS ( css_highlight) ;
954
- p. deallocate ( ) ;
1040
+ p. deallocate ( )
955
1041
}
956
1042
}
1043
+ if !css_highlight. isEmpty {
1044
+ let font = self . syntaxFontFamily
1045
+ if font != " " {
1046
+ let code = """
1047
+ :root {
1048
+ --code-font: " \( font) " , ui-monospace, -apple-system, Menlo, monospace;
1049
+ }
1050
+ """
1051
+ css_highlight += code
1052
+ }
1053
+ css_highlight = formatCSS ( css_highlight)
1054
+ }
957
1055
958
1056
let style = css_doc + css_highlight + css_doc_extended
959
-
1057
+ let wrapper_open = self . renderAsCode ? " <pre class='hl'> " : " <article class='markdown-body'> "
1058
+ let wrapper_close = self . renderAsCode ? " </pre> " : " </article> "
1059
+ let body_style = self . renderAsCode ? " class='hl' " : " "
960
1060
var html =
961
1061
"""
962
1062
<!doctype html>
@@ -968,15 +1068,15 @@ table.debug td {
968
1068
\( style)
969
1069
\( header)
970
1070
</head>
971
- <body>
972
- <article class= " markdown-body " >
1071
+ <body \( body_style ) >
1072
+ \( wrapper_open )
973
1073
\( body)
974
- </article>
1074
+ \( wrapper_close )
975
1075
\( footer)
976
1076
</body>
977
1077
</html>
978
1078
"""
979
- if self . unsafeHTMLOption && self . inlineImageExtension, let ext = cmark_find_syntax_extension ( " inlineimage " ) , cmark_syntax_extension_inlineimage_get_raw_images_count ( ext) > 0 {
1079
+ if ! self . renderAsCode && self . unsafeHTMLOption && self . inlineImageExtension, let ext = cmark_find_syntax_extension ( " inlineimage " ) , cmark_syntax_extension_inlineimage_get_raw_images_count ( ext) > 0 {
980
1080
var changed = false
981
1081
do {
982
1082
let doc = try SwiftSoup . parse ( html, basedir. path)
0 commit comments