Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Add foler browser and render on github server if possible

  • Loading branch information...
commit 3fdb17fe7cb63fc4d5b5afe712c7ff877132352f 1 parent 0282575
Forbes Lindesay ForbesLindesay authored committed
6 README.md
Source Rendered
@@ -11,16 +11,16 @@ via npm:
11 11
12 12 ## Usage
13 13
14   - $ greadme [path/to/some.markdown]
  14 + $ greadme [port-number]
15 15
16 16 view your markdown at http://localhost:8124/
17 17 press CTRL+C to quit
18 18
19   -Execute `greadme` passing an optional path to a markdown file and it will be parsed and served from a locally running http server with Github styling applied.
  19 +Execute `greadme` passing an optional port number and markdown in the current directory will be parsed and served from a locally running http server with Github styling applied.
20 20
21 21 If you are running on a mac, a browser will automatically be opened to preview the markdown.
22 22
23   -When no file path is specified, `greadme` attempts to locate a Readme file in the current directory and renders it instead. The following filenames and extensions are tried, if none are found, an error is printed and the program exits.
  23 +When no file path is specified, `greadme` attempts to locate a Readme file in the current directory and renders it instead. The following filenames and extensions are tried.
24 24
25 25 - README.md
26 26 - README.markdown
149 bin/greadme
... ... @@ -1,22 +1,23 @@
1 1 #!/usr/bin/env node
2 2
  3 +var express = require('express');
  4 +var app = express();
  5 +var path = require('path');
3 6 var fs = require('fs')
4 7 var md = require('marked')
5 8 var http = require('http')
6 9 var request = require('request')
7 10
8 11 // TODO configurable
  12 +var arg = process.argv[2];
9 13 var host = 'localhost'
10   -var port = 8124
  14 +var port = +(arg||8124)
11 15
12   -var dir = process.cwd()
13   -var exts = 'markdown md'.split(' ')
14   -
15   -var file = process.argv[2] || ''
16   -
17   -if (!file) {
  16 +function readme(dir) {
  17 + var exts = 'markdown md'.split(' ')
  18 + var file;
18 19 var names = 'README Readme readme'.split(' ')
19   - names.some(function (name) {
  20 + if (names.some(function (name) {
20 21 return exts.some(function (ext) {
21 22 try {
22 23 var filename = dir + '/' + name + '.' + ext
@@ -27,66 +28,96 @@ if (!file) {
27 28 return false
28 29 }
29 30 })
30   - })
  31 + })) {
  32 + return file;
  33 + }
31 34 }
32 35
33   -if (!file) {
34   - console.error('no readme.md found')
35   - return process.exit(1)
  36 +function getStyle(cb) {
  37 + request({ uri: "https://github.com/aheckmann/greadme", timeout: 4000 }, function (err, res, body) {
  38 + try {
  39 + var css = []
  40 + if (err) {
  41 + // ignore error, use old css instead
  42 + console.log('\u001B[35m %s\u001B[0m', 'could not retreive latest github css. using old version');
  43 + css.unshift('/css/style.css')
  44 + } else {
  45 + var rgx = /href=["']([^"']+\.css)/g
  46 + ;(body || '').replace(rgx, function (_, href) {
  47 + css.unshift(href);
  48 + })
  49 + }
  50 + } catch (ex) {
  51 + return cb(ex);
  52 + }
  53 + cb(null, css);
  54 + });
36 55 }
37 56
38   -function getHTML(file, css) {
39   - var contents = fs.readFileSync(file, 'utf8')
40   - var html = md(contents)
41   -
42   -
43   - html = '<div id="readme"><article class="markdown-body entry-content">'
44   - + html
45   - + '</article></div>'
46   -
47   - html = '<style type="text/css">'
48   - + '#readme { width: 920px;margin: 0 auto; }'
49   - + '</style>'
50   - + html;
  57 +function listDir(dir) {
  58 + var all = fs.readdirSync(dir);
  59 + var md = [];
  60 + var dirs = dir == process.cwd() ? [] : ['..'];
  61 + all.forEach(function (item) {
  62 + var stat = fs.statSync(path.join(dir, item));
  63 + if (stat.isDirectory()) {
  64 + dirs.push(item);
  65 + } else if (stat.isFile() && (/\.md$/.test(item) || /\.markdown$/.test(item))) {
  66 + md.push(item);
  67 + }
  68 + });
  69 + function canonical(item) {
  70 + return {
  71 + href: path.join(dir, item).replace(process.cwd(), '').replace(/\\/g, '/') || '/',
  72 + name: item
  73 + };
  74 + }
  75 + return {
  76 + md: md.map(canonical),
  77 + dirs: dirs.map(canonical)
  78 + }
  79 +}
51 80
52   - css.forEach(function (href) {
53   - html = '<link href="' + href + '" rel="stylesheet">' + html;
  81 +function render(fileContent, cb) {
  82 + request({
  83 + url: 'https://api.github.com/markdown/raw',
  84 + body: fileContent,
  85 + method: 'POST',
  86 + headers: {
  87 + 'content-type': 'text/plain'
  88 + },
  89 + timeout: 2000
  90 + }, function (err, res, body) {
  91 + if (err) console.log(err);
  92 + if (err || res.statusCode != 200) {
  93 + return cb(null, md(fileContent));
  94 + } else {
  95 + return cb(null, body);
  96 + }
54 97 })
55   -
56   - html = '<html><body>' + html + '</body></html>'
57   -
58   - return html;
59 98 }
60 99
61   -var stylesheet = ''
62   -
63 100 // get github css
64   -request({ uri: "https://github.com/aheckmann/greadme", timeout: 4000 }, function (err, res, body) {
65   - var css = []
66   -
67   - if (err) {
68   - // ignore error, use old css instead
69   - console.log('\u001B[35m %s\u001B[0m', 'could not retreive latest github css. using old version');
70   - css.unshift('/css/style.css')
71   - stylesheet = fs.readFileSync(__dirname + '/../css/style.css', 'utf8');
72   -
73   - } else {
74   - var rgx = /href=["']([^"']+\.css)/g
75   - ;(body || '').replace(rgx, function (_, href) {
76   - css.unshift(href);
77   - })
78   - }
79   -
80   - var server = http.createServer(function (req, res) {
81   - if (/css$/.test(req.url)) {
82   - res.writeHead(200, { 'Content-Type': 'text/css' })
83   - res.end(stylesheet)
84   - return;
85   - }
86   -
87   - res.writeHead(200, { 'Content-Type': 'text/html' })
88   - res.end(getHTML(file, css))
89   - }).listen(port, host)
  101 +getStyle(function (err, css) {
  102 + if (err) throw err;
  103 +
  104 + app.use(express.favicon());
  105 + app.use('/css', express.static(path.join(__dirname, '..', 'css')))
  106 + app.use(function (req, res, next) {
  107 + var p = path.join(process.cwd(), req.url.substring(1));
  108 + var stat = fs.statSync(p);
  109 + var dir = stat.isDirectory();
  110 + var file = dir ? readme(p) : p;
  111 + var contents = file ? fs.readFileSync(file, 'utf8') : 'No readme found';
  112 + render(contents, function (err, markdown) {
  113 + res.render(path.join(__dirname, '..', 'view.ejs'), {
  114 + css: css,
  115 + markdown: markdown,
  116 + dir: dir && listDir(p)
  117 + });
  118 + });
  119 + });
  120 + var server = http.createServer(app).listen(port, host)
90 121
91 122 server.on('listening', function () {
92 123 var url = 'http://' + host + ':' + port
BIN  css/directory.png
BIN  css/file.png
13 package.json
@@ -2,7 +2,9 @@
2 2 "name": "greadme",
3 3 "version": "0.0.5",
4 4 "description": "Locally preview your markdown, Github style",
5   - "bin": { "greadme": "./bin/greadme" },
  5 + "bin": {
  6 + "greadme": "./bin/greadme"
  7 + },
6 8 "scripts": {
7 9 "test": "make test"
8 10 },
@@ -17,12 +19,17 @@
17 19 ],
18 20 "dependencies": {
19 21 "marked": "0.2.5",
20   - "request": "2.11.1"
  22 + "request": "2.11.1",
  23 + "express": "3.0.3",
  24 + "ejs": "~0.8.3"
21 25 },
22 26 "devDependencies": {
23 27 "mocha": "1.4.1"
24 28 },
25 29 "author": "Aaron Heckmann <aaron.heckmann+github@gmail.com>",
26 30 "license": "MIT",
27   - "repository": { "type": "git", "url": "git://github.com/aheckmann/greadme.git" }
  31 + "repository": {
  32 + "type": "git",
  33 + "url": "git://github.com/aheckmann/greadme.git"
  34 + }
28 35 }
37 view.ejs
... ... @@ -0,0 +1,37 @@
  1 +<html>
  2 + <head>
  3 + <% css.forEach(function (href) { %>
  4 + <link href="<%= href %>" rel="stylesheet">
  5 + <% }) %>
  6 + <style type="text/css">
  7 + #readme, #file-explorer { width: 920px;margin: 0 auto; }
  8 + </style>
  9 + </head>
  10 + <body>
  11 + <% if (dir) { %>
  12 + <div id="file-explorer" class="bubble tree-browser-wrapper">
  13 + <table class="tree-browser css-truncate" cellpadding="0" cellspacing="0">
  14 + <tbody class="tree-entries">
  15 + <% dir.dirs.forEach(function (dir) { %>
  16 + <tr>
  17 + <td class="icon"><img width="20" src="/css/directory.png"/></td>
  18 + <td class="content"><a href="<%= dir.href %>"><%= dir.name %></a></td>
  19 + </tr>
  20 + <% }) %>
  21 + <% dir.md.forEach(function (file) { %>
  22 + <tr>
  23 + <td class="icon"><img width="20" src="/css/file.png"/></td>
  24 + <td class="content"><a href="<%= file.href %>"><%= file.name %></a></td>
  25 + </tr>
  26 + <% }) %>
  27 + </tbody>
  28 + </table>
  29 + </div>
  30 + <% } %>
  31 + <div id="readme">
  32 + <article class="markdown-body entry-content">
  33 + <%- markdown %>
  34 + </article>
  35 + </div>
  36 + </body>
  37 +</html>

0 comments on commit 3fdb17f

Please sign in to comment.
Something went wrong with that request. Please try again.