1
+ /*
2
+
3
+ MIT License
4
+
5
+ Copyright (c) 2025 JustDeveloper <https://justdeveloper.is-a.dev/>
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in all
15
+ copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ SOFTWARE.
24
+
25
+ */
26
+
27
+ const fs = require ( 'fs' ) ;
28
+ const path = require ( 'path' ) ;
29
+
30
+ const [ HTML , CSS , JS ] = process . argv . slice ( 2 ) ;
31
+
32
+ const biMDtoHTML = ( input ) => {
33
+ let text = input ;
34
+
35
+ text = text . replace ( / _ _ _ ( .* ?) _ _ _ / g, '<em><strong>$1</strong></em>' ) ;
36
+
37
+ text = text . replace ( / (?< = \s | ^ | [ . , ! ? ; : ] ) _ _ \* ( .* ?) \* \_ _ (? = \s | [ . , ! ? ; : ] | $ ) / g, '<strong>$1</strong>' ) ;
38
+ text = text . replace ( / (?< = \s | ^ | [ . , ! ? ; : ] ) \* \* ( .* ?) \* \* (? = \s | [ . , ! ? ; : ] | $ ) / g, '<strong>$1</strong>' ) ;
39
+
40
+ text = text . replace ( / (?< = \s | ^ | [ . , ! ? ; : ] ) _ ( .* ?) _ (? = \s | [ . , ! ? ; : ] | $ ) / g, '<em>$1</em>' ) ;
41
+ text = text . replace ( / (?< = \s | ^ | [ . , ! ? ; : ] ) _ _ \s * ( .* ?) \s * _ _ (? = \s | [ . , ! ? ; : ] | $ ) / g, '<em>$1</em>' ) ;
42
+
43
+ text = text . replace ( / (?< = \s | ^ | [ . , ! ? ; : ] ) _ _ \* \s * ( .* ?) \s * \* \_ _ (? = \s | [ . , ! ? ; : ] | $ ) / g, '<em><strong>$1</strong></em>' ) ;
44
+ text = text . replace ( / (?< = \s | ^ | [ . , ! ? ; : ] ) \* \* \s * ( .* ?) \s * _ * * (? = \s | [ . , ! ? ; : ] | $ ) / g, '<em><strong>$1</strong></em>' ) ;
45
+
46
+ return text ;
47
+ }
48
+ function hbuoclpMDtoHTML ( text , maxBlockquoteLevel = 4 ) {
49
+ for ( let i = 6 ; i >= 1 ; i -- ) {
50
+ const regex = new RegExp ( `^#{${ i } }\\s+(.*?)\\s*$` , 'gm' ) ;
51
+ text = text . replace ( regex , biMDtoHTML ( `<h${ i } >$1</h${ i } >` ) ) ;
52
+ }
53
+
54
+ function processBlockquotes ( inputText , level ) {
55
+ const regex = new RegExp ( `^(>\\s+){${ level } }(.*?)\\s*$` , 'gm' ) ;
56
+ return biMDtoHTML ( inputText . replace ( regex , ( match , p1 , p2 ) => {
57
+ const innerBlockquote = processBlockquotes ( p2 . trim ( ) , level + 1 ) ;
58
+ const classAttr = p1 . includes ( '[!NOTE]' ) ? ' class="note"' : '' ;
59
+ return `<blockquote${ classAttr } >${ ( level > 1 ? '<br>' : '' ) } ${ innerBlockquote } </blockquote>` ;
60
+ } ) ) ;
61
+ }
62
+
63
+ for ( let i = 1 ; i <= maxBlockquoteLevel ; i ++ ) {
64
+ text = processBlockquotes ( text , i ) ;
65
+ }
66
+
67
+ const ulRegex = / ^ (?: - \s + | \* \s + | \+ \s + ) ( .* ?) (?: \n (?: - \s + | \* \s + | \+ \s + ) ( .* ?) ) * $ / gm;
68
+ const olRegex = / ^ (?: \d + \. \s + ) ( .* ?) (?: \n (?: \d + \. \s + ) ( .* ?) ) * $ / gm;
69
+
70
+ text = text . replace ( ulRegex , ( match ) => {
71
+ const items = match . split ( '\n' ) . map ( item => item . replace ( / ^ - \s * / , '' ) . replace ( / ^ \* \s * / , '' ) . replace ( / ^ \+ \s * / , '' ) ) ;
72
+ return `<ul>${ items . map ( item => `<li>${ biMDtoHTML ( item . trim ( ) ) } </li>` ) . join ( '' ) } </ul>` ;
73
+ } ) ;
74
+
75
+ text = text . replace ( olRegex , ( match ) => {
76
+ const items = match . split ( '\n' ) . map ( item => item . replace ( / ^ \d + \. \s * / , '' ) ) ;
77
+ return `<ol>${ items . map ( item => `<li>${ biMDtoHTML ( item . trim ( ) ) } </li>` ) . join ( '' ) } </ol>` ;
78
+ } ) ;
79
+
80
+ text = text . replace ( / ` ( [ ^ ` ] + ) ` / g, '<code>$1</code>' ) ;
81
+
82
+ const multiLineCodeRegex = / ` ` ` ( [ \w ] * ) [ \r \n ] + ( [ \S \s ] * ?) ` ` ` / g;
83
+ text = text . replace ( multiLineCodeRegex , '<code>$2</code>' ) ;
84
+
85
+ const dividerRegex = / ( \n \s * [ * _ - ] { 3 , } \s * \n ) + / g;
86
+ text = text . replace ( dividerRegex , '<div class="line"></div>' ) ;
87
+
88
+ const paragraphsRegex = / ( [ ^ \n ] + (?: \n (? ! [ \* _ - ] { 3 } ) .* ) * ) / g;
89
+
90
+ let resultTextArray = [ ] ;
91
+
92
+ let match ;
93
+
94
+ while ( ( match = paragraphsRegex . exec ( text ) ) !== null ) {
95
+ let paragraphContent = match [ 0 ] . trim ( ) ;
96
+
97
+ if ( paragraphContent ) {
98
+ resultTextArray . push ( `<p>${ biMDtoHTML ( paragraphContent ) } </p>` ) ;
99
+ }
100
+
101
+ text = text . slice ( match . index + match [ 0 ] . length ) ;
102
+
103
+ if ( / ^ \n \s * $ / . test ( text ) ) {
104
+ resultTextArray . push ( '<p></p>' ) ;
105
+ break ;
106
+ }
107
+
108
+ if ( / ^ [ * _ ] { 3 } / . test ( text ) ) {
109
+ break ;
110
+ }
111
+
112
+ if ( text . length > 0 ) {
113
+ resultTextArray . push ( `<p>${ biMDtoHTML ( text . trim ( ) ) } </p>` ) ;
114
+ break ;
115
+ }
116
+
117
+ paragraphsRegex . lastIndex -= match [ 0 ] . length ;
118
+
119
+ }
120
+
121
+ return resultTextArray . join ( '' ) ;
122
+ }
123
+
124
+ function findMarkdownFiles ( dir ) {
125
+ let results = [ ] ;
126
+ const list = fs . readdirSync ( dir ) ;
127
+ list . forEach ( file => {
128
+ file = path . join ( dir , file ) ;
129
+ const stat = fs . statSync ( file ) ;
130
+ if ( stat && stat . isDirectory ( ) ) {
131
+ results = results . concat ( findMarkdownFiles ( file ) ) ;
132
+ } else if ( file . endsWith ( '.md' ) || file . endsWith ( '.mdx' ) ) {
133
+ results . push ( file ) ;
134
+ }
135
+ } ) ;
136
+ return results ;
137
+ }
138
+
139
+ const rootDir = process . cwd ( ) ;
140
+ const markdownFiles = findMarkdownFiles ( rootDir ) ;
141
+
142
+ markdownFiles . forEach ( file => {
143
+ const content = fs . readFileSync ( file , 'utf-8' ) ;
144
+ const fileNameWithoutExt = path . basename ( file , path . extname ( file ) ) ;
145
+ const outFilePath = ( ext ) => path . join ( path . dirname ( file ) , `${ fileNameWithoutExt } .${ ext } ` ) ;
146
+
147
+ const toHTML = hbuoclpMDtoHTML ( content ) ;
148
+
149
+ fs . writeFileSync ( outFilePath ( 'html' ) , HTML . replace ( 'REPLACE_CONTENT' , toHTML ) , 'utf-8' ) ;
150
+ fs . writeFileSync ( outFilePath ( 'css' ) , CSS , 'utf-8' ) ;
151
+ fs . writeFileSync ( outFilePath ( 'js' ) , JS , 'utf-8' ) ;
152
+ } ) ;
0 commit comments