@@ -29,8 +29,6 @@ class MicronParser {
2929 console . warn ( 'DOMPurify is not installed. Include it above micron-parser.js or run npm install dompurify' ) ;
3030 }
3131
32- this . SELECTED_STYLES = null ;
33-
3432 this . STYLES_DARK = {
3533 "plain" : { fg : this . DEFAULT_FG_DARK , bg : this . DEFAULT_BG , bold : false , underline : false , italic : false } ,
3634 "heading1" : { fg : "222" , bg : "bbb" , bold : false , underline : false , italic : false } ,
@@ -45,11 +43,7 @@ class MicronParser {
4543 "heading3" : { fg : "222" , bg : "ccc" , bold : false , underline : false , italic : false }
4644 } ;
4745
48- if ( this . darkTheme ) {
49- this . SELECTED_STYLES = this . STYLES_DARK ;
50- } else {
51- this . SELECTED_STYLES = this . STYLES_LIGHT ;
52- }
46+ this . SELECTED_STYLES = this . darkTheme ? this . STYLES_DARK : this . STYLES_LIGHT ;
5347
5448 }
5549
@@ -84,14 +78,57 @@ class MicronParser {
8478 return `nomadnetwork://${ url } ` ;
8579 }
8680
81+
82+ parseHeaderTags ( markup ) {
83+ let pageFg = null ;
84+ let pageBg = null ;
85+
86+ const lines = markup . split ( "\n" ) ;
87+
88+ for ( let line of lines ) {
89+ const trimmedLine = line . trim ( ) ;
90+
91+ if ( trimmedLine . length === 0 ) {
92+ continue ;
93+ }
94+
95+ if ( ! trimmedLine . startsWith ( "#!" ) ) {
96+ break ;
97+ }
98+
99+ if ( trimmedLine . startsWith ( "#!fg=" ) ) {
100+ let color = trimmedLine . substring ( 5 ) . trim ( ) ;
101+ if ( color . length === 3 || color . length === 6 ) {
102+ pageFg = color ;
103+ }
104+ }
105+
106+ if ( trimmedLine . startsWith ( "#!bg=" ) ) {
107+ let color = trimmedLine . substring ( 5 ) . trim ( ) ;
108+ if ( color . length === 3 || color . length === 6 ) {
109+ pageBg = color ;
110+ }
111+ }
112+ }
113+
114+ return { fg : pageFg , bg : pageBg } ;
115+ }
116+
87117 convertMicronToHtml ( markup ) {
88118 let html = "" ;
89119
120+ // parse header tags for page-level color defaults
121+ const headerColors = this . parseHeaderTags ( markup ) ;
122+
123+ const plainStyle = this . SELECTED_STYLES ?. plain || { fg : this . DEFAULT_FG_DARK , bg : this . DEFAULT_BG } ;
124+ const defaultFg = headerColors . fg || plainStyle . fg ;
125+ const defaultBg = headerColors . bg || this . DEFAULT_BG ;
126+
90127 let state = {
91128 literal : false ,
92129 depth : 0 ,
93- fg_color : this . SELECTED_STYLES . plain . fg ,
94- bg_color : this . DEFAULT_BG ,
130+ fg_color : defaultFg ,
131+ bg_color : defaultBg ,
95132 formatting : {
96133 bold : false ,
97134 underline : false ,
@@ -100,6 +137,8 @@ class MicronParser {
100137 } ,
101138 default_align : "left" ,
102139 align : "left" ,
140+ default_fg : defaultFg ,
141+ default_bg : defaultBg ,
103142 radio_groups : { }
104143 } ;
105144
@@ -131,11 +170,17 @@ class MicronParser {
131170 // Create a fragment to hold all the Micron output
132171 const fragment = document . createDocumentFragment ( ) ;
133172
173+ const headerColors = this . parseHeaderTags ( markup ) ;
174+
175+ const plainStyle = this . SELECTED_STYLES ?. plain || { fg : this . DEFAULT_FG_DARK , bg : this . DEFAULT_BG } ;
176+ const defaultFg = headerColors . fg || plainStyle . fg ;
177+ const defaultBg = headerColors . bg || this . DEFAULT_BG ;
178+
134179 let state = {
135180 literal : false ,
136181 depth : 0 ,
137- fg_color : this . SELECTED_STYLES . plain . fg ,
138- bg_color : this . DEFAULT_BG ,
182+ fg_color : defaultFg ,
183+ bg_color : defaultBg ,
139184 formatting : {
140185 bold : false ,
141186 underline : false ,
@@ -144,6 +189,8 @@ class MicronParser {
144189 } ,
145190 default_align : "left" ,
146191 align : "left" ,
192+ default_fg : defaultFg ,
193+ default_bg : defaultBg ,
147194 radio_groups : { }
148195 } ;
149196
@@ -177,7 +224,7 @@ class MicronParser {
177224
178225
179226 if ( ! state . literal ) {
180- // Comments
227+ // Comments, and header tags s
181228 if ( line [ 0 ] === "#" ) {
182229 return [ ] ;
183230 }
@@ -201,10 +248,11 @@ class MicronParser {
201248 // apply heading style if it exists
202249 let style = null ;
203250 let wanted_style = "heading" + i ;
204- if ( this . SELECTED_STYLES [ wanted_style ] ) {
251+ const defaultPlain = { fg : this . darkTheme ? this . DEFAULT_FG_DARK : this . DEFAULT_FG_LIGHT , bg : this . DEFAULT_BG , bold : false , underline : false , italic : false } ;
252+ if ( this . SELECTED_STYLES ?. [ wanted_style ] ) {
205253 style = this . SELECTED_STYLES [ wanted_style ] ;
206254 } else {
207- style = this . SELECTED_STYLES . plain ;
255+ style = this . SELECTED_STYLES ? .plain || defaultPlain ;
208256 }
209257
210258 const latched_style = this . stateToStyle ( state ) ;
@@ -627,8 +675,8 @@ applyStyleToElement(el, style) {
627675 }
628676 break ;
629677 case 'f' :
630- // reset fg
631- state . fg_color = this . SELECTED_STYLES . plain . fg ;
678+ // reset fg to page default
679+ state . fg_color = state . default_fg ;
632680 break ;
633681 case 'B' :
634682 // next 3 chars => bg color
@@ -640,16 +688,16 @@ applyStyleToElement(el, style) {
640688 }
641689 break ;
642690 case 'b' :
643- // reset bg
644- state . bg_color = this . DEFAULT_BG ;
691+ // reset bg to page default
692+ state . bg_color = state . default_bg ;
645693 flushPart ( ) ; // flush to allow for ` tags on same line
646694 break ;
647695 case '`' :
648696 state . formatting . bold = false ;
649697 state . formatting . underline = false ;
650698 state . formatting . italic = false ;
651- state . fg_color = this . SELECTED_STYLES . plain . fg ;
652- state . bg_color = this . DEFAULT_BG ;
699+ state . fg_color = state . default_fg ;
700+ state . bg_color = state . default_bg ;
653701 state . align = state . default_align ;
654702 mode = "text" ;
655703 break ;
@@ -710,8 +758,8 @@ applyStyleToElement(el, style) {
710758 state . formatting . bold = false ;
711759 state . formatting . underline = false ;
712760 state . formatting . italic = false ;
713- state . fg_color = this . SELECTED_STYLES . plain . fg ;
714- state . bg_color = this . DEFAULT_BG ;
761+ state . fg_color = state . default_fg ;
762+ state . bg_color = state . default_bg ;
715763 state . align = state . default_align ;
716764 i += 2 ;
717765 continue ;
@@ -721,17 +769,6 @@ applyStyleToElement(el, style) {
721769 i ++ ;
722770 continue ;
723771 }
724- } else if ( c === '[' ) {
725- flushPart ( ) ;
726- let linkDataText = this . parseLink ( line , i , state ) ;
727- if ( linkDataText ) {
728- output . push ( linkDataText . obj ) ;
729- i += linkDataText . skip ;
730- continue ;
731- } else {
732- // not a link
733- part += '[' ;
734- }
735772 } else {
736773 // normal text char
737774 part += c ;
@@ -882,12 +919,9 @@ applyStyleToElement(el, style) {
882919
883920 splitAtSpaces ( line ) {
884921 let out = "" ;
885- let wordArr = line . split ( " " ) ;
922+ let wordArr = line . split ( / (?< = ) / g ) ;
886923 for ( let i = 0 ; i < wordArr . length ; i ++ ) {
887924 out += "<span class='Mu-mws'>" + this . forceMonospace ( wordArr [ i ] ) + "</span>" ;
888- if ( i < wordArr . length - 1 ) {
889- out += " " ;
890- }
891925 }
892926 return out ;
893927 }
@@ -903,4 +937,4 @@ applyStyleToElement(el, style) {
903937 }
904938}
905939
906- export default MicronParser ;
940+ export default MicronParser ;
0 commit comments