11#!/usr/bin/env node
2- 
3- var  MarkdownIt  =  require ( 'markdown-it' ) ; 
4- var  hljs  =  require ( 'highlight.js' ) ; 
5- var  server  =  require ( 'http' ) . createServer ( httpHandler ) , 
2+ "use strict" ; 
3+ const  MarkdownIt  =  require ( 'markdown-it' ) ; 
4+ const  hljs  =  require ( 'highlight.js' ) ; 
5+ const  server  =  require ( 'http' ) . createServer ( httpHandler ) , 
66    exec  =  require ( 'child_process' ) . exec , 
77    io  =  require ( 'socket.io' ) . listen ( server ) , 
88    os  =  require ( 'os' ) , 
9+     fs  =  require ( 'fs' ) , 
910    send  =  require ( 'send' ) ; 
1011
11- var  mjpage  =  require ( 'mathjax-node-page' ) . mjpage ; 
12- // var fs = require('fs');  // for debugging 
13- var  enableMathJax  =  process . argv [ 2 ]  ===  "--mathjax" ; 
12+ const  mjpage  =  require ( 'mathjax-node-page' ) . mjpage ; 
13+ const  taskLists  =  require ( 'markdown-it-task-lists' ) ; 
14+ const  argv  =  require ( 'minimist' ) ( process . argv . slice ( 2 ) ,  { 
15+   string : [ 'browser' ] , 
16+   default : { port : 8090 ,  debug : false } , 
17+   alias : { V : 'version' ,  h : 'help' } , 
18+ } ) ; 
19+ 
20+ if  ( argv . version  ||  argv . debug )  { 
21+   const  version =  require ( './version' ) ; 
22+   console . log ( `instant-mardown-d version: v${ version }  ` ) ; 
23+   console . log ( `nodejs version: ${ process . version }  ` ) ; 
24+ } 
25+ if  ( argv . help )  { 
26+   console . log ( `\ 
27+ Usage: instant-markdown-d [OPTIONS] 
28+ 
29+ Options: 
30+   --mathjax          Enable MathJax parsing 
31+   --browser BROWSER  Use a custom browser 
32+   --port PORT        Use a custom port (default: 8090) 
33+   --debug           Be verbose and do not open browser 
34+   -V, --version      Display version 
35+   -h, --help         Display help\ 
36+   ` ) ; 
37+ } 
38+ if  ( argv . version  ||  argv . help )  process . exit ( 0 ) ; 
1439
40+ if  ( argv . verbose )  console . dir ( argv ) ; 
41+ 
42+ // console.dir(argv); 
1543// WARNING: By setting this environment variable, anyone on your network may 
1644// run arbitrary code in your browser and read arbitrary files in the working 
1745// directory of the open file! 
1846if  ( process . env . INSTANT_MARKDOWN_OPEN_TO_THE_WORLD )  { 
1947  // Listen on any interface. 
20-   server . listen ( 8090 ,  onListening ) . once ( 'error' ,  onServerError ) ; 
48+   server . listen ( argv . port ,  onListening ) . once ( 'error' ,  onServerError ) ; 
2149}  else  { 
2250  // Listen locally. 
23-   server . listen ( 8090 ,  '127.0.0.1' ,  onListening ) . once ( 'error' ,  onServerError ) ; 
51+   server . listen ( argv . port ,  '127.0.0.1' ,  onListening ) . once ( 'error' ,  onServerError ) ; 
2452} 
2553
26- var  md  =  new  MarkdownIt ( { 
54+ let  md  =  new  MarkdownIt ( { 
2755  html : true , 
2856  linkify : true , 
2957  highlight : function ( str ,  lang )  { 
@@ -37,9 +65,9 @@ var md = new MarkdownIt({
3765      return  str ; 
3866    } 
3967  } 
40- } ) ; 
68+ } ) . use ( taskLists ) ; 
4169
42- if  ( enableMathJax )  md . use ( require ( 'markdown-it-mathjax' ) ( ) ) ; 
70+ if  ( argv . mathjax )  md . use ( require ( 'markdown-it-mathjax' ) ( ) ) ; 
4371
4472const  mjPageConfig  =  { 
4573  format : [ "TeX" ] , 
@@ -59,14 +87,17 @@ const mjNodeConfig = {
5987} ; 
6088
6189function  mathJaxRenderEmit ( newHtml )  { 
62-   if ( enableMathJax )  { 
90+   if ( argv . mathjax )  { 
6391    mjpage ( 
6492      newHtml , 
6593      mjPageConfig , 
6694      mjNodeConfig , 
6795      function ( data )  { 
68-           // console.log(data); // resulting HTML string 
69-           // fs.writeFileSync('output.html', data, 'utf-8'); // debug 
96+           if  ( argv . debug )  { 
97+             console . log ( "Rendered html saved as debug.html" ) 
98+             // console.log(data); // resulting HTML string 
99+             fs . writeFileSync ( 'debug.html' ,  data ,  'utf-8' ) ;  // debug 
100+           } 
70101          io . sockets . emit ( 'newContent' ,  data ) ; 
71102      } 
72103    ) ; 
@@ -76,14 +107,14 @@ function mathJaxRenderEmit(newHtml) {
76107  } 
77108} 
78109
79- var  lastWrittenMarkdown  =  '' ; 
110+ let  lastWrittenMarkdown  =  '' ; 
80111function  writeMarkdown ( body )  { 
81112  lastWrittenMarkdown  =  md . render ( body ) ; 
82113  mathJaxRenderEmit ( lastWrittenMarkdown ) ; 
83114} 
84115
85116function  readAllInput ( input ,  callback )  { 
86-   var  body  =  '' ; 
117+   let  body  =  '' ; 
87118  input . on ( 'data' ,  function ( data )  { 
88119    body  +=  data ; 
89120    if  ( body . length  >  1e6 )  { 
@@ -96,12 +127,12 @@ function readAllInput(input, callback) {
96127} 
97128
98129function  addSecurityHeaders ( req ,  res ,  isIndexFile )  { 
99-   var  csp  =  [ ] ; 
130+   let  csp  =  [ ] ; 
100131
101132  // Cannot use 'self' because Chrome does not treat 'self' as http://host 
102133  // when the sandbox directive is set. 
103-   var  HTTP_HOST  =  req . headers . host  ||  'localhost:8090'  ; 
104-   var  CSP_SELF  =  'http://'  +  HTTP_HOST ; 
134+   let  HTTP_HOST  =  req . headers . host  ||  'localhost:'    +   argv . port ; 
135+   let  CSP_SELF  =  'http://'  +  HTTP_HOST ; 
105136
106137  if  ( ! process . env . INSTANT_MARKDOWN_ALLOW_UNSAFE_CONTENT )  { 
107138    if  ( isIndexFile )  { 
@@ -131,35 +162,39 @@ function httpHandler(req, res) {
131162  { 
132163    case  'GET' :
133164      // Example: /my-repo/raw/master/sub-dir/some.png 
134-       var  githubUrl  =  req . url . match ( / \/ [ ^ \/ ] + \/ r a w \/ [ ^ \/ ] + \/ ( .+ ) / ) ; 
165+       let  githubUrl  =  req . url . match ( / \/ [ ^ \/ ] + \/ r a w \/ [ ^ \/ ] + \/ ( .+ ) / ) ; 
135166      if  ( githubUrl )  { 
136167        addSecurityHeaders ( req ,  res ,  false ) ; 
137168         // Serve the file out of the current working directory 
138-         send ( req ,  githubUrl [ 1 ] ) 
139-          . root ( process . cwd ( ) ) 
169+         send ( req ,  githubUrl [ 1 ] ,  { root : process . cwd ( ) } ) 
140170         . pipe ( res ) ; 
141171        return ; 
142172      } 
143173
144-       var  isIndexFile  =  / ^ \/ ( i n d e x \. h t m l ) ? ( \? | $ ) / . test ( req . url ) ; 
174+       let  isIndexFile  =  / ^ \/ ( i n d e x \. h t m l ) ? ( \? | $ ) / . test ( req . url ) ; 
145175      addSecurityHeaders ( req ,  res ,  isIndexFile ) ; 
146176
177+       let  cwd  =  process . cwd ( ) ; 
178+       let  mount  =  cwd  &&  ! fs . existsSync ( __dirname  +  req . url )  ? cwd  : __dirname ; 
179+ 
147180      // Otherwise serve the file from the directory this module is in 
148-       send ( req ,  req . url ) 
149-         . root ( __dirname ) 
181+       send ( req ,  req . url ,  { root : mount } ) 
150182        . pipe ( res ) ; 
151183      break ; 
152184
153185    // case 'HEAD': 
154186      // res.writeHead(200); 
155187      // res.end(); 
156-       // exec('open -g http://localhost:8090' , function(error, stdout, stderr){ 
157-         // http.request({port: 8090 }) 
188+       // exec('open -g http://localhost:' + argv.port , function(error, stdout, stderr){ 
189+         // http.request({port: argv.port }) 
158190      // }); 
159191      // break; 
160192
161193    case  'DELETE' :
194+       res . setHeader ( 'Content-Type' ,  'text/plain' ) ; 
195+       res . writeHead ( 204 ,  {  'Content-Type' : 'text/plain'  } ) ; 
162196      io . sockets . emit ( 'die' ) ; 
197+       res . end ( 'ok' ) 
163198      process . exit ( ) ; 
164199      break ; 
165200
@@ -177,18 +212,26 @@ io.sockets.on('connection', function(sock){
177212  process . stdout . write ( 'connection established!' ) ; 
178213  if  ( lastWrittenMarkdown )  { 
179214    sock . emit ( 'newContent' ,  lastWrittenMarkdown ) ;   // Quick preview 
180-     if  ( enableMathJax )  mathJaxRenderEmit ( lastWrittenMarkdown ) ; 
215+     if  ( argv . mathjax )  mathJaxRenderEmit ( lastWrittenMarkdown ) ; 
181216  } 
182217} ) ; 
183218
184219
185220function  onListening ( )  { 
186-   if  ( os . platform ( )  ===  'win32' )  { 
187-     exec ( 'start /b http://localhost:8090' ,  function ( error ,  stdout ,  stderr ) { } ) ; 
188-   }  else  if  ( os . platform ( )  ===  'darwin' )  { 
189-     exec ( 'open -g http://localhost:8090' ,  function ( error ,  stdout ,  stderr ) { } ) ; 
190-   }  else  {  // assume unix/linux 
191-     exec ( 'xdg-open http://localhost:8090/' ,  function ( error ,  stdout ,  stderr ) { } ) ; 
221+   if  ( ! argv . browser )  { 
222+     if  ( os . platform ( )  ===  'win32' )  { 
223+       argv . browser  =  'start /b' ; 
224+     }  else  if  ( os . platform ( )  ===  'darwin' )  { 
225+       argv . browser  =  'open -g' ; 
226+     }  else  {  // assume unix/linux 
227+       argv . browser  =  'xdg-open' ; 
228+     } 
229+   } 
230+   let  cmd  =  argv . browser  +  ' http://localhost:'  +  argv . port  +  '/' ; 
231+   if  ( argv . debug )  { 
232+     console . log ( "Run the following to manually open browser: \n    "  +  cmd ) ; 
233+   }  else  { 
234+     exec ( cmd ,  function ( error ,  stdout ,  stderr ) { } ) ; 
192235  } 
193236  readAllInput ( process . stdin ,  function ( body )  { 
194237    writeMarkdown ( body ) ; 
@@ -202,7 +245,7 @@ function onServerError(e) {
202245      // Forward to existing instant-markdown-d server. 
203246      require ( 'http' ) . request ( { 
204247        hostname : 'localhost' , 
205-         port : 8090 , 
248+         port : argv . port , 
206249        path : '/' , 
207250        method : 'PUT' , 
208251      } ) . end ( body ) ; 
0 commit comments