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