deliver markdown to browser over websockets
This commit is contained in:
		
							parent
							
								
									4a33ecd7fa
								
							
						
					
					
						commit
						cf66b5a48d
					
				@ -7,3 +7,9 @@ Depends on:
 | 
			
		||||
 | 
			
		||||
* markdown-mode
 | 
			
		||||
* websocket.el
 | 
			
		||||
 | 
			
		||||
table header 1 | header 2 | head 3
 | 
			
		||||
--------------|---------|------
 | 
			
		||||
cell1 | cell2 | cell3
 | 
			
		||||
cell1 | cell2 | cell3
 | 
			
		||||
cell1 | cell2 | [cell3](#asdfsadf)
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
;; Copyright (C) 2014 <igor.shimko@gmail.com>
 | 
			
		||||
 | 
			
		||||
;; Author: Kostafey <kostafey@gmail.com>
 | 
			
		||||
;; Author: Igor Shymko <igor.shimko@gmail.com>
 | 
			
		||||
;; URL: https://github.com/ancane/markdown-preview-mode
 | 
			
		||||
;; Keywords: markdown, preview
 | 
			
		||||
;; Package-Requires: ((websocket "1.3"))
 | 
			
		||||
@ -34,10 +34,20 @@
 | 
			
		||||
 | 
			
		||||
(defvar mdpm:websocket-port 7379)
 | 
			
		||||
(defvar mdpm:websocket-server nil)
 | 
			
		||||
(defvar mdpm:websocket-clients nil)
 | 
			
		||||
(defvar mdpm:local-client nil)
 | 
			
		||||
(defvar mdpm:remote-clients nil)
 | 
			
		||||
(defvar mdpm:directory (file-name-directory load-file-name))
 | 
			
		||||
 | 
			
		||||
;; (setq mdpm:websocket-server (get-process "websocket server on port 7379"))
 | 
			
		||||
(defun mdpm:open-browser-preview ()
 | 
			
		||||
  (browse-url (concat mdpm:directory "preview.html")))
 | 
			
		||||
 | 
			
		||||
(defun mdpm:stop-websocket-server ()
 | 
			
		||||
  (when mdpm:local-client
 | 
			
		||||
    (websocket-close mdpm:local-client))
 | 
			
		||||
  (when mdpm:websocket-server
 | 
			
		||||
    (delete-process mdpm:websocket-server)
 | 
			
		||||
    (setq mdpm:websocket-server nil
 | 
			
		||||
          mdpm:remote-clients nil)))
 | 
			
		||||
 | 
			
		||||
(defun mdpm:start-websocket-server ()
 | 
			
		||||
  (when (not mdpm:websocket-server)
 | 
			
		||||
@ -46,39 +56,46 @@
 | 
			
		||||
           mdpm:websocket-port
 | 
			
		||||
           :on-message (lambda (websocket frame)
 | 
			
		||||
                         (mapc (lambda (ws)
 | 
			
		||||
                                 ;; send frame only if ws != websocket
 | 
			
		||||
                                 (websocket-send-text
 | 
			
		||||
                                  ws
 | 
			
		||||
                                  (websocket-frame-payload frame))))
 | 
			
		||||
                         mdpm:websocket-clients)
 | 
			
		||||
                                 (websocket-send-text ws
 | 
			
		||||
                                  (websocket-frame-payload frame)))
 | 
			
		||||
                               mdpm:remote-clients))
 | 
			
		||||
           :on-open (lambda (websocket)
 | 
			
		||||
                      (push websocket mdpm:websocket-clients))
 | 
			
		||||
                      (push websocket mdpm:remote-clients)
 | 
			
		||||
                      )
 | 
			
		||||
           :on-close (lambda (websocket)
 | 
			
		||||
                       (delete websocket mdpm:websocket-clients)))))
 | 
			
		||||
  (add-hook 'kill-emacs-hook 'mdpm:stop-websocket-server)
 | 
			
		||||
  (mdpm:open-browser))
 | 
			
		||||
                       (delete websocket mdpm:remote-clients)
 | 
			
		||||
                       )
 | 
			
		||||
           ))
 | 
			
		||||
    (add-hook 'kill-emacs-hook 'mdpm:stop-websocket-server)
 | 
			
		||||
    (mdpm:open-browser-preview)))
 | 
			
		||||
 | 
			
		||||
(defun mdpm:open-browser ()
 | 
			
		||||
  (browse-url (concat mdpm:directory "preview.html")))
 | 
			
		||||
(defun mdpm:start-local-client ()
 | 
			
		||||
  (when (not mdpm:local-client)
 | 
			
		||||
    (setq mdpm:local-client
 | 
			
		||||
          (websocket-open
 | 
			
		||||
           (format "ws://localhost:%d" mdpm:websocket-port)
 | 
			
		||||
           :on-error (lambda (ws type err)
 | 
			
		||||
                       (message "error connecting"))
 | 
			
		||||
           :on-close (lambda (websocket)
 | 
			
		||||
                       (setq mdpm:local-client nil))))))
 | 
			
		||||
 | 
			
		||||
(defun mdpm:stop-websocket-server ()
 | 
			
		||||
  (when mdpm:websocket-server
 | 
			
		||||
    (delete-process mdpm:websocket-server)
 | 
			
		||||
    (setq mdpm:websocket-server nil
 | 
			
		||||
          mdpm:websocket-clients nil)))
 | 
			
		||||
 | 
			
		||||
(defun mdpm:send ())
 | 
			
		||||
(defun mdpm:send-preview ()
 | 
			
		||||
  (markdown markdown-output-buffer-name)
 | 
			
		||||
  (with-current-buffer (get-buffer markdown-output-buffer-name)
 | 
			
		||||
    (websocket-send-text mdpm:local-client (buffer-substring-no-properties (point-min) (point-max))))
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
(defun mdpm:start ()
 | 
			
		||||
  (mdpm:start-websocket-server)
 | 
			
		||||
  (add-hook 'after-save-hook 'mdpm:send nil t))
 | 
			
		||||
  (mdpm:start-local-client)
 | 
			
		||||
  (add-hook 'after-save-hook 'mdpm:send-preview nil t))
 | 
			
		||||
 | 
			
		||||
(defun mdpm:stop ()
 | 
			
		||||
  (remove-hook 'after-save-hook 'mdpm:send))
 | 
			
		||||
  (remove-hook 'after-save-hook 'mdpm:send-preview))
 | 
			
		||||
 | 
			
		||||
(defun markdown-preview-open-browser ()
 | 
			
		||||
  (interactive)
 | 
			
		||||
  (mdpm:open-browser))
 | 
			
		||||
  (mdpm:open-browser-preview))
 | 
			
		||||
 | 
			
		||||
(defun markdown-preview-kill-websocket-server ()
 | 
			
		||||
  (interactive)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										40
									
								
								preview.html
									
									
									
									
									
								
							
							
						
						
									
										40
									
								
								preview.html
									
									
									
									
									
								
							@ -4,25 +4,29 @@
 | 
			
		||||
    <meta charset="utf-8">
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1, minimal-ui">
 | 
			
		||||
    <title>Markdown preview</title>
 | 
			
		||||
    <link href="style.css" media="all" rel="stylesheet" type="text/css">
 | 
			
		||||
    <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
     var socket = new WebSocket("ws://localhost:7379");
 | 
			
		||||
     socket.onopen = function() {
 | 
			
		||||
         alert("Connection established.");
 | 
			
		||||
     };
 | 
			
		||||
     socket.onclose = function(event) {
 | 
			
		||||
         if (event.wasClean) {
 | 
			
		||||
             alert('Connection closed gracefully.');
 | 
			
		||||
         } else {
 | 
			
		||||
             alert('Connection terminated.');
 | 
			
		||||
         }
 | 
			
		||||
         alert('Code: ' + event.code + ' reason: ' + event.reason);
 | 
			
		||||
     };
 | 
			
		||||
     socket.onmessage = function(event) {
 | 
			
		||||
         alert("Message received: " + event.data);
 | 
			
		||||
     };
 | 
			
		||||
     socket.onerror = function(error) {
 | 
			
		||||
         alert("Error: " + error.message);
 | 
			
		||||
     };
 | 
			
		||||
     (function($, undefined) {
 | 
			
		||||
         var socket = new WebSocket("ws://localhost:7379");
 | 
			
		||||
         socket.onopen = function() {
 | 
			
		||||
             console.log("Connection established.");
 | 
			
		||||
         };
 | 
			
		||||
         socket.onclose = function(event) {
 | 
			
		||||
             if (event.wasClean) {
 | 
			
		||||
                 alert('Connection closed gracefully.');
 | 
			
		||||
             } else {
 | 
			
		||||
                 alert('Connection terminated.');
 | 
			
		||||
             }
 | 
			
		||||
             console.log('Code: ' + event.code + ' reason: ' + event.reason);
 | 
			
		||||
         };
 | 
			
		||||
         socket.onmessage = function(event) {
 | 
			
		||||
             $("#markdown-body").html(event.data);
 | 
			
		||||
         };
 | 
			
		||||
         socket.onerror = function(error) {
 | 
			
		||||
             alert("Error: " + error.message);
 | 
			
		||||
         };
 | 
			
		||||
     })(jQuery);
 | 
			
		||||
    </script>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1
									
								
								style.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								style.css
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
article,aside,details,figcaption,figure,footer,header,hgroup,nav,section,summary {display: block;}audio,canvas,video {display: inline-block;}audio:not([controls]) {display: none;height: 0;}[hidden] {display: none;}html {font-family: sans-serif;-webkit-text-size-adjust: 100%;-ms-text-size-adjust: 100%;}body {margin: 0;}a:focus {outline: thin dotted;}a:active,a:hover {outline: 0;}h1 {font-size: 2em;}abbr[title] {border-bottom: 1px dotted;}b,strong {font-weight: bold;}dfn {font-style: italic;}mark {background: #ff0;color: #000;}code,kbd,pre,samp {font-family: monospace, serif;font-size: 1em;}pre {white-space: pre-wrap;word-wrap: break-word;}q {quotes: "\201C" "\201D" "\2018" "\2019";}small {font-size: 80%;}sub,sup {font-size: 75%;line-height: 0;position: relative;vertical-align: baseline;}sup {top: -0.5em;}sub {bottom: -0.25em;}img {border: 0;}svg:not(:root) {overflow: hidden;}figure {margin: 0;}fieldset {border: 1px solid #c0c0c0;margin: 0 2px;padding: 0.35em 0.625em 0.75em;}legend {border: 0;padding: 0;}button,input,select,textarea {font-family: inherit;font-size: 100%;margin: 0;}button,input {line-height: normal;}button,html input[type="button"],input[type="reset"],input[type="submit"] {-webkit-appearance: button;cursor: pointer;}button[disabled],input[disabled] {cursor: default;}input[type="checkbox"],input[type="radio"] {box-sizing: border-box;padding: 0;}input[type="search"] {-webkit-appearance: textfield;-moz-box-sizing: content-box;-webkit-box-sizing: content-box;box-sizing: content-box;}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration {-webkit-appearance: none;}button::-moz-focus-inner,input::-moz-focus-inner {border: 0;padding: 0;}textarea {overflow: auto;vertical-align: top;}table {border-collapse: collapse;border-spacing: 0;}@import url(//fonts.googleapis.com/css?family=Inconsolata);@import url(//fonts.googleapis.com/css?family=PT+Sans);@import url(//fonts.googleapis.com/css?family=PT+Sans+Narrow:400,700);html {font-family: 'PT Sans', sans-serif;}pre,code {font-family: 'Inconsolata', sans-serif;}h1,h2,h3,h4,h5,h6 {font-family: 'PT Sans Narrow', sans-serif;font-weight: 700;}html {background-color: #002b36;color: #839496;margin: 1em;}code {background-color: #073642;padding: 2px;}a {color: #b58900;}a:visited {color: #cb4b16;}a:hover {color: #cb4b16;}h1 {color: #d33682;}h2,h3,h4,h5,h6 {color: #859900;}pre {background-color: #002b36;color: #839496;border: 1pt solid #586e75;padding: 1em;box-shadow: 5pt 5pt 8pt #073642;}pre code {background-color: #002b36;}h1 {font-size: 2.8em;}h2 {font-size: 2.4em;}h3 {font-size: 1.8em;}h4 {font-size: 1.4em;}h5 {font-size: 1.3em;}h6 {font-size: 1.15em;}.tag {background-color: #073642;color: #d33682;padding: 0 0.2em;}.todo,.next,.done {color: #002b36;background-color: #dc322f;padding: 0 0.2em;}.tag {-webkit-border-radius: 0.35em;-moz-border-radius: 0.35em;border-radius: 0.35em;}.TODO {-webkit-border-radius: 0.2em;-moz-border-radius: 0.2em;border-radius: 0.2em;background-color: #2aa198;}.NEXT {-webkit-border-radius: 0.2em;-moz-border-radius: 0.2em;border-radius: 0.2em;background-color: #268bd2;}.ACTIVE {-webkit-border-radius: 0.2em;-moz-border-radius: 0.2em;border-radius: 0.2em;background-color: #268bd2;}.DONE {-webkit-border-radius: 0.2em;-moz-border-radius: 0.2em;border-radius: 0.2em;background-color: #859900;}.WAITING {-webkit-border-radius: 0.2em;-moz-border-radius: 0.2em;border-radius: 0.2em;foreground-color: #cb4b16;}.HOLD {-webkit-border-radius: 0.2em;-moz-border-radius: 0.2em;border-radius: 0.2em;foreground-color: #d33682;}.NOTE {-webkit-border-radius: 0.2em;-moz-border-radius: 0.2em;border-radius: 0.2em;foreground-color: #d33682;}.CANCELLED {-webkit-border-radius: 0.2em;-moz-border-radius: 0.2em;border-radius: 0.2em;foreground-color: #859900;}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user