require 'sinatra' require 'rack/highlighter' require 'devcenter-parser' module Devcenter::Previewer class WebApp < Sinatra::Base use Rack::Highlighter, :coderay, { misc: { :css => :class, :element => "pre>code" } } include Devcenter::Logger set :logging, false set :connections, [] set :public_folder, File.dirname(__FILE__) set :views, File.join(File.dirname(__FILE__), 'views') helpers do include Devcenter::Helpers end get '/favicon.ico' do end get '/stream', provides: 'text/event-stream' do stream :keep_open do |conn| settings.connections << conn log "New incoming connection (#{settings.connections.size} open)" # refresh connection before browser times out EventMachine::PeriodicTimer.new(20) do log "Refreshing connection" conn << ":refreshing \n\n" end conn.callback do settings.connections.delete(conn) log "Connection closed locally (#{settings.connections.size} open)" end conn.errback do conn.close settings.connections.delete(conn) log "Connection closed externally (#{settings.connections.size} open)" end end end get '/:slug' do log "Local article requested: #{params[:slug]}" src_path = File.join(Dir.pwd, "#{params[:slug]}.md") if File.exists?(src_path) log "Parsing" @article = parse_article(src_path) @article.toc = Nokogiri::HTML(@article.html).search('h2') @page_title = @article.metadata.title log "Serving" erb :article else @referrer_url = request.referrer @page_title = 'Not found' erb :not_found end end def parse_article(src_path) article = OpenStruct.new src = IO.read(src_path) metadata_yaml, article.content = src.split(/\r*\n\r*\n/, 2) article.metadata = OpenStruct.new YAML.load(metadata_yaml) markdown_flavour = article.metadata.markdown_flavour || :maruku begin article.html = ::DevcenterParser.to_html(article.content, markdown_flavour.to_sym) rescue Exception => e article.error = e.to_s end article end def self.send_server_event Devcenter::Logger.log "Serving server side event to #{settings.connections.size} connections" settings.connections.each do |conn| conn << "data: reload\n\n" end end end end