Preview local Markdown files live in a web browser
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.ts 1.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. #!/usr/bin/env node
  2. import { ArgumentParser } from 'argparse';
  3. import chokidar from 'chokidar';
  4. import express, { Request, Response } from 'express';
  5. import marked from 'marked';
  6. import WebSocket from 'ws';
  7. import hljs from 'highlight.js';
  8. import * as fs from 'fs';
  9. import * as path from 'path';
  10. import template from './template';
  11. const parser = new ArgumentParser({
  12. add_help: true,
  13. description: 'Realtime Markdown preview',
  14. });
  15. parser.add_argument('file');
  16. parser.add_argument('-p', '--port', {
  17. default: 1729,
  18. help: 'The port to run on',
  19. type: 'int',
  20. });
  21. parser.add_argument('-t', '--theme', {
  22. default: 'zenburn',
  23. help:
  24. 'The theme to use for highlighted code blocks. A full list of available themes can be found at https://highlightjs.org/static/demo.',
  25. type: 'str',
  26. });
  27. const { file, port, theme } = parser.parse_args();
  28. const filepath = path.resolve(file);
  29. const getRenderedHTML = () => {
  30. const fileContents = fs.readFileSync(filepath, 'utf-8');
  31. return marked(fileContents, {
  32. highlight: (code, language) => {
  33. const validLanguage = hljs.getLanguage(language) ? language : 'plaintext';
  34. return hljs.highlight(validLanguage, code).value;
  35. },
  36. });
  37. };
  38. const wss = new WebSocket.Server({
  39. port: 40510,
  40. });
  41. wss.on('connection', (ws) => {
  42. chokidar.watch(filepath).on('change', () => {
  43. ws.send(getRenderedHTML(), (err) => {
  44. if (err) console.log(err);
  45. });
  46. });
  47. });
  48. const app = express();
  49. app.get('/', (_req: Request, res: Response) => {
  50. res.send(template(path.basename(file), getRenderedHTML(), theme));
  51. });
  52. app.listen(port, () => {
  53. console.log(`Listening at http://localhost:${port}`);
  54. });