Fork me on GitHub

Ruby Socket + RedCarpet = Browser-Based Markdown Preview

Published by Miles Sandlar on April 29, 2012 at 3:19AM

So I’ve been preparing some documents with markdown lately. I had been using my Markdown Tree project in order to faciliate a sort of “live-preview” of the markdown I was editing, however I felt there was a simpler way. Nothing against Sinatra but I wanted a lighter solution. I didn’t feel I needed a library for just viewing some Markdown in my browser. What I wanted was a commandline tool I could use like markview.rb somefile.md and it would give me a live URL on localhost of the markdown file rendered as HTML.

Lucky Ruby provides an execellent Socket Class. Combine that with a markdown render such as Redcarpet and you have a simplistic web-based markdown viewing utility. It can even handle multiple clients! Basically this is a bit of ruby that interpolates RedCarpet render results with some HTML. Then, along with a HTTP Header, the HTML is then served on port 2010. A CSS file for styling is stored in ~/.config/markview.

markview.rb (/home/mil/bin/markview.rb)

#!/usr/bin/ruby
require "socket"
require "redcarpet"

def generatePage(filePath)
	#Read style file
	style = File.read("/home/mil/.config/markview/style.css")

	#Use Redcarpet to convert Markdown->HTML
	redcarpet = Redcarpet::Markdown.new(Redcarpet::Render::HTML)
	markdown = redcarpet.render(File.read(filePath))

	#The Content Header Well Be Serving
	header = "HTTP/1.1 200/OK\r\nContent-type:text/html\r\n\r\n"

	#The Content We'll Be Serving
	content = %(
	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
	<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
		<title>Markview : #{filePath}</title>
		<style type="text/css">#{style}</style>
	</head>
	<body>#{markdown}</body>
	)
	return header, content
end

#Start it Up
server = TCPServer.new('localhost', 2000)
loop do
	header, content = generatePage("#{Dir.getwd}/#{ARGV[0]}")
	Thread.start(server.accept) do |session|
		session.print(header)
		session.print(content)
		session.close
	end
end

And that’s it. Instead of using some graphical tool, you can just replace your markdown preview utility with a single-purpose web server. Also one other note: starting this script up is very snappy in comparison with Sinatra scripts.