mamemose 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ pkg/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mamemose.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 daimatz
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,216 @@
1
+ mamemose: Markdown memo server
2
+ ====
3
+
4
+ 概要
5
+ ----
6
+
7
+ 理想の Markdown メモツールを探したがなかったので自分で作った。要件としては
8
+
9
+ - Markdown など軽量マークアップ言語で書かれたドキュメントを
10
+ コマンド操作無しで勝手に HTML に変換してくれる
11
+ - Sphinx などをそのまま使うのはコマンドを打つ手間があるので嫌だった
12
+ - 複数マシンで内容を共有できる (Dropbox 等を使ってもよい)
13
+ - 使い慣れたエディタを使える
14
+ - 検索できる
15
+ - できれば GitHub Flavored Markdown でシンタックスハイライトもしてほしい
16
+ - できれば LaTeX で数式も書きたい
17
+
18
+ 環境
19
+ ----
20
+
21
+ - おもに Mac OS X 10.8 上の Ruby 1.9.3 でテスト
22
+ - Ruby 1.8.7 でも動くようにした
23
+ - Linux はおそらく大丈夫
24
+ - Windows も、こないだ Cygwin 上で試したら動いたのでたぶん動くと思う
25
+
26
+ インストール方法
27
+ ----
28
+
29
+ ```bash
30
+ $ gem install mamemose
31
+ ```
32
+
33
+ 使い方
34
+ ----
35
+
36
+ 設定ファイル (後述) を書いたら以下で起動
37
+
38
+ ```bash
39
+ $ mamemose &> /dev/null &
40
+ ```
41
+
42
+ ブラウザから
43
+
44
+ ```
45
+ http://localhost:PORT/
46
+ ```
47
+
48
+ にアクセスすればおk
49
+
50
+ `DOCUMENT_ROOT` 以下の Markdown で書かれたテキストを勝手にHTMLに変換して表示します。
51
+ 一覧ページでは Markdown ドキュメントの1行目をタイトルとして読み込みます。
52
+
53
+ `DOCUMENT_ROOT` を Dropbox 以下のディレクトリに指定しておけば、どのマシンからでも
54
+ メモにアクセスできるようになります。
55
+
56
+ ### シンタックスハイライト
57
+
58
+ [コード部分に GitHub Flavored Markdown の記法](http://github.github.com/github-flavored-markdown/)
59
+ を使い、シンタックスハイライトに
60
+ [SyntaxHighlighter](http://alexgorbatchev.com/SyntaxHighlighter/)
61
+ を使うことができます。設定例を参照。
62
+
63
+ ### 数式
64
+
65
+ [MathJax](http://www.mathjax.org/) を使うと数式も書けます。設定例を参照。
66
+
67
+ 設定
68
+ ----
69
+
70
+ ホームディレクトリに `.mamemose.rb` という設定ファイルを置くとそれを読みます。
71
+ 設定項目は以下の通り
72
+
73
+ - `DOCUMENT_ROOT`
74
+ - ドキュメントルート
75
+ - `PORT`
76
+ - ポート。 http://localhost:PORT/ にアクセス
77
+ - `MARKDOWN_PATTERN`
78
+ - Markdown ドキュメントと見なすファイルパターンを正規表現で
79
+ - `IGNORE_FILES`
80
+ - 無視するファイル・ディレクトリのリスト。
81
+ 文字列の場合はそのものを、正規表現の場合はそれにマッチするものを無視する
82
+ - `RECENT_NUM`
83
+ - 「最近更新したファイル」を表示する数
84
+ - `RECENT_PATTERN`
85
+ - 「最近更新したファイル」に表示するファイルパターンを正規表現で
86
+ - `CUSTOM_HEADER`
87
+ - カスタムヘッダ。 `head` タグの最後に入る
88
+ - `CUSTOM_BODY`
89
+ - カスタムボディ。 `body` タグの最初に入る
90
+ - `CUSTOM_FOOTER`
91
+ - カスタムフッタ。 `body` タグの最後に入る
92
+
93
+ 設定されなかったらデフォルト値を使います。
94
+
95
+ ### 設定ファイル例
96
+
97
+ `~/.mamemose.rb`
98
+
99
+ ```ruby
100
+ DOCUMENT_ROOT = "~/memo"
101
+
102
+ PORT = 8888
103
+
104
+ # 通常の Markdown ファイルに加えて .txt ファイルも Markdown と見なす
105
+ MARKDOWN_PATTERN = /\.(md|markdown|txt)$/
106
+
107
+ # 最近更新したファイル一覧がジャマ
108
+ RECENT_NUM = 0
109
+
110
+ # 最近更新したファイル一覧に出すものを Markdown ドキュメントだけにする
111
+ # RECENT_PATTERN = MARKDOWN_PATTERN
112
+
113
+ # すべてのページで MathJax が使えるように
114
+ CUSTOM_HEADER = <<HEADER
115
+ <script type="text/javascript"
116
+ src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML">
117
+ </script>
118
+ HEADER
119
+
120
+ # すべてのページで SyntaxHighlighter が使えるように
121
+ host = "http://alexgorbatchev.com/pub/sh/current" # 変数も使えます
122
+ CUSTOM_FOOTER = <<FOOTER
123
+ <link href="#{host}/styles/shCoreDefault.css" rel="stylesheet" type="text/css" />
124
+ <script src="#{host}/scripts/shCore.js" type="text/javascript"></script>
125
+ <script src="#{host}/scripts/shAutoloader.js" type="text/javascript"></script>
126
+ <script type="text/javascript">
127
+ SyntaxHighlighter.autoloader(
128
+ 'AS3 as3 #{host}/scripts/shBrushAS3.js',
129
+ 'AppleScript applescript #{host}/scripts/shBrushAppleScript.js',
130
+ 'Bash bash #{host}/scripts/shBrushBash.js',
131
+ 'CSharp csharp #{host}/scripts/shBrushCSharp.js',
132
+ 'ColdFusion coldfusion #{host}/scripts/shBrushColdFusion.js',
133
+ 'Cpp cpp #{host}/scripts/shBrushCpp.js',
134
+ 'Css css #{host}/scripts/shBrushCss.js',
135
+ 'Delphi delphi #{host}/scripts/shBrushDelphi.js',
136
+ 'Diff diff #{host}/scripts/shBrushDiff.js',
137
+ 'Erlang erlang #{host}/scripts/shBrushErlang.js',
138
+ 'Groovy groovy #{host}/scripts/shBrushGroovy.js',
139
+ 'JScript jscript #{host}/scripts/shBrushJScript.js',
140
+ 'Java java #{host}/scripts/shBrushJava.js',
141
+ 'JavaFX javafx #{host}/scripts/shBrushJavaFX.js',
142
+ 'Perl perl #{host}/scripts/shBrushPerl.js',
143
+ 'Php php #{host}/scripts/shBrushPhp.js',
144
+ 'Plain plain #{host}/scripts/shBrushPlain.js',
145
+ 'PowerShell powershell #{host}/scripts/shBrushPowerShell.js',
146
+ 'Python python #{host}/scripts/shBrushPython.js',
147
+ 'Ruby ruby #{host}/scripts/shBrushRuby.js',
148
+ 'Sass sass #{host}/scripts/shBrushSass.js',
149
+ 'Scala scala #{host}/scripts/shBrushScala.js',
150
+ 'Sql sql #{host}/scripts/shBrushSql.js',
151
+ 'Vb vb #{host}/scripts/shBrushVb.js',
152
+ 'Xml xml #{host}/scripts/shBrushXml.js'
153
+ );
154
+ SyntaxHighlighter.all();
155
+ </script>
156
+ FOOTER
157
+ ```
158
+
159
+ ### 使用例
160
+
161
+ 上記のように設定すると、次のような Markdown ファイル `~/memo/sample.md` は
162
+
163
+ 数列
164
+ ====
165
+
166
+ 問題
167
+ ----
168
+
169
+ 和の公式
170
+ $$ \sum\_{k=1}^n k = \frac{1}{2}n(n+1) $$
171
+ を計算する関数を C++ で実装せよ。
172
+
173
+ 解答
174
+ ----
175
+
176
+ ```cpp
177
+ int f(int n) {
178
+ int ret = 0;
179
+ for (int k = 1; k <= n; k++) {
180
+ ret += k;
181
+ }
182
+ return ret;
183
+ }
184
+ ```
185
+
186
+ 次のように表示される。
187
+
188
+ ![](https://raw.github.com/daimatz/mamemose/master/sample.png)
189
+
190
+ MathJax と SyntaxHighlighter はローカルにダウンロードして使うのが親切だと思います。
191
+
192
+ 検索
193
+ ----
194
+
195
+ Markdown ドキュメントを全文検索して一致したものを表示します。
196
+ Markdown ドキュメントでないものはファイル名に一致したものを表示します。
197
+
198
+ FAQ と予想されるもの
199
+ ----
200
+
201
+ - 遅いよ
202
+ - 一覧ページでは「最近更新したファイル」を表示するために
203
+ そのディレクトリ以下の全ファイルを舐めているので遅いです。
204
+ `RECENT_NUM = 0` にしてください。
205
+ - 検索が遅いのはどうしようもないです。ファイル数 3000 くらいまでなら
206
+ まあ使えるかなというのは確認したつもりですが
207
+ - SSD 積んでますか?
208
+ - 他の言語もシンタックスハイライトしたいんだけど
209
+ - SyntaxHighlighter の構文ファイルを自分で書いて読み込むようにしましょう
210
+ - Haskell 用のは書きました [gist](https://gist.github.com/3969549)
211
+ - reStructuredText 対応して
212
+ - Python で書いてください
213
+ - 表を書きたいんだけど
214
+ - 無理。 table タグ書いてください
215
+ - 定義リストを書きたいんだけど
216
+ - 同上
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
data/bin/mamemose ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.expand_path("../../lib", __FILE__)
4
+
5
+ load 'mamemose.rb'
6
+
7
+ Mamemose::Server.new.start
@@ -0,0 +1,3 @@
1
+ module Mamemose
2
+ VERSION = "0.1.0"
3
+ end
data/lib/mamemose.rb ADDED
@@ -0,0 +1,349 @@
1
+ require 'rubygems'
2
+ require 'webrick'
3
+ require 'find'
4
+ require 'uri'
5
+ require 'redcarpet'
6
+ require 'htmlentities'
7
+
8
+ require "mamemose/version"
9
+
10
+ conf = File.expand_path("~" + File::SEPARATOR + ".mamemose.rb")
11
+ load conf if File.exists?(conf)
12
+
13
+ DOCUMENT_ROOT = "~/Dropbox/memo" if !defined?(DOCUMENT_ROOT)
14
+ PORT = 20000 if !defined?(PORT)
15
+ RECENT_NUM = 10 if !defined?(RECENT_NUM)
16
+ RECENT_PATTERN = /.*/ if !defined?(RECENT_PATTERN)
17
+ IGNORE_FILES = ['.DS_Store','.AppleDouble','.LSOverride','Icon',/^\./,/~$/,
18
+ '.Spotlight-V100','.Trashes','Thumbs.db','ehthumbs.db',
19
+ 'Desktop.ini','$RECYCLE.BIN',/^#/,'MathJax','syntaxhighlighter'] if !defined?(IGNORE_FILES)
20
+ MARKDOWN_PATTERN = /\.(md|markdown)$/ if !defined?(MARKDOWN_PATTERN)
21
+ CUSTOM_HEADER = '' if !defined?(CUSTOM_HEADER)
22
+ CUSTOM_BODY = '' if !defined?(CUSTOM_BODY)
23
+ CUSTOM_FOOTER = '' if !defined?(CUSTOM_FOOTER)
24
+
25
+ CONTENT_TYPE = "text/html; charset=utf-8"
26
+ DIR = File::expand_path(DOCUMENT_ROOT, '/')
27
+
28
+ class HTMLwithSyntaxHighlighter < Redcarpet::Render::XHTML
29
+ def block_code(code, lang)
30
+ code = HTMLEntities.new.encode(code)
31
+ lang ||= "plain"
32
+ return "<pre class='brush: #{lang}'>#{code}</pre>"
33
+ end
34
+ end
35
+
36
+ class Mamemose::Server
37
+ def initialize
38
+ @server = WEBrick::HTTPServer.new({ :Port => PORT })
39
+ @server.mount_proc('/') do |req, res|
40
+ res['Cache-Control'] = 'no-cache, no-store, must-revalidate'
41
+ res['Pragma'] = 'no-cache'
42
+ res['Expires'] = '0'
43
+ if req.path =~ /^\/search/
44
+ query = req.query
45
+ path = path(query["path"])
46
+ q = URI.decode(query["q"])
47
+ q = q.force_encoding('utf-8') if q.respond_to?(:force_encoding)
48
+
49
+ found = {}
50
+ Find.find(path) do |file|
51
+ Find.prune if ignore?(file)
52
+ dir = File::dirname(file)
53
+ found[dir] = [] if !found[dir]
54
+ if markdown?(file)
55
+ open(file) do |f|
56
+ c = f.read + "\n" + file
57
+ found[dir] << [get_title(file,c), uri(file)] if !q.split(' ').map{|s| /#{s}/mi =~ c }.include?(nil)
58
+ end
59
+ elsif !q.split(' ').map{|s| /#{s}/ =~ File.basename(file)}.include?(nil)
60
+ found[dir] << [get_title(file),uri(file)]
61
+ end
62
+ end
63
+
64
+ title = "Search #{q} in #{docpath(query['path'])}"
65
+ title = title.force_encoding('utf-8') if title.respond_to?(:force_encoding)
66
+ body = title + "\n====\n"
67
+ found.reject{|key, value| value == []}.sort.each do |key, value|
68
+ body += "\n### in <a href='#{uri(key)}'>#{uri(key)}\n"
69
+ value.each do |v|
70
+ body += link_list(v[0], v[1])
71
+ end
72
+ end
73
+
74
+ res.body = header_html(title, uri(path), q) + markdown(body) + footer_html
75
+ res.content_type = CONTENT_TYPE
76
+
77
+ else
78
+
79
+ filename = path(req.path)
80
+
81
+ if File.directory?(filename) then
82
+ title = "Index of #{docpath(req.path)}"
83
+ body = title + "\n====\n"
84
+
85
+ recent = []
86
+ dirs = []
87
+ markdowns = []
88
+ files = []
89
+
90
+ if RECENT_NUM > 0 then
91
+ Find.find(filename) do |file|
92
+ Find.prune if ignore?(file)
93
+ recent << file if File.file?(file) && file =~ RECENT_PATTERN
94
+ end
95
+ recent = recent.sort_by{|file| File.mtime(file)}.reverse.slice(0,RECENT_NUM)
96
+ recent = recent.map{|file|
97
+ if markdown?(file) then
98
+ [get_title(file, open(file).read), uri(file)]
99
+ else [File::basename(file), uri(file)]
100
+ end
101
+ }
102
+ else
103
+ recent = []
104
+ end
105
+
106
+ Dir.entries(filename).each do |i|
107
+ next if ignore?(i)
108
+ link = uri(File.join(filename, i))
109
+ if File.directory?(path(link)) then
110
+ dirs << [File.basename(link) + File::SEPARATOR, link]
111
+ elsif markdown?(link)
112
+ File.open(path(link)) do |f|
113
+ markdowns << [get_title(link, f.read), link]
114
+ end
115
+ else
116
+ files << [File::basename(link), link]
117
+ end
118
+ end
119
+
120
+ body += "\nRecent:\n---\n" if RECENT_NUM > 0
121
+ recent.each {|i| body += link_list(i[0], i[1])}
122
+
123
+ body += "\nDirectories:\n----\n"
124
+ dirs.each {|i| body += link_list(i[0], i[1])}
125
+
126
+ body += "\nMarkdown documents:\n----\n"
127
+ markdowns.each {|i| body += link_list(i[0], i[1])}
128
+
129
+ body += "\nOther files:\n----\n"
130
+ files.each {|i| body += link_list(i[0], i[1])}
131
+
132
+ res.body = header_html(title, req.path) + markdown(body) + footer_html
133
+ res.content_type = CONTENT_TYPE
134
+
135
+ elsif File.exists?(filename)
136
+ open(filename) do |file|
137
+ if markdown?(req.path)
138
+ str = file.read
139
+ title = get_title(filename, str)
140
+ res.body = header_html(title, req.path) + markdown(str) + footer_html
141
+ res.content_type = CONTENT_TYPE
142
+ else
143
+ res.body = file.read
144
+ res.content_type = WEBrick::HTTPUtils.mime_type(req.path, WEBrick::HTTPUtils::DefaultMimeTypes)
145
+ res.content_length = File.stat(filename).size
146
+ end
147
+ end
148
+
149
+ else
150
+ res.status = WEBrick::HTTPStatus::RC_NOT_FOUND
151
+ end
152
+
153
+ end
154
+ end
155
+
156
+ trap(:INT){@server.shutdown}
157
+ trap(:TERM){@server.shutdown}
158
+ end
159
+
160
+ def start
161
+ @server.start
162
+ end
163
+
164
+ private
165
+
166
+ def header_html(title, path, q="")
167
+ html = <<HTML
168
+ <!DOCTYPE HTML>
169
+ <html>
170
+ <head>
171
+ <meta http-equiv="Content-Type" content="#{CONTENT_TYPE}" />
172
+ <title>#{title}</title>
173
+ <style type="text/css"><!--
174
+ body {
175
+ margin: auto;
176
+ padding: 0 2em;
177
+ max-width: 80%;
178
+ border-left: 1px solid black;
179
+ border-right: 1px solid black;
180
+ font-size: 100%;
181
+ line-height: 140%;
182
+ }
183
+ pre {
184
+ border: 1px solid #090909;
185
+ background-color: #f8f8f8;
186
+ padding: 0.5em;
187
+ margin: 0.5em 1em;
188
+ }
189
+ code {
190
+ border: 1px solid #cccccc;
191
+ background-color: #f8f8f8;
192
+ padding: 2px 0.5em;
193
+ margin: 0 0.5em;
194
+ }
195
+ a {
196
+ text-decoration: none;
197
+ }
198
+ a:link, a:visited, a:hover {
199
+ color: #4444cc;
200
+ }
201
+ a:hover {
202
+ text-decoration: underline;
203
+ }
204
+ h1, h2, h3 {
205
+ font-weight: bold;
206
+ color: #2f4f4f;
207
+ }
208
+ h1 {
209
+ font-size: 200%;
210
+ line-height: 100%;
211
+ margin: 1em 0;
212
+ border-bottom: 1px solid #2f4f4f;
213
+ }
214
+ h2 {
215
+ font-size: 175%;
216
+ line-height: 100%;
217
+ margin: 1em 0;
218
+ padding-left: 0.5em;
219
+ border-left: 0.5em solid #2f4f4f;
220
+ }
221
+ h3 {
222
+ font-size: 150%;
223
+ line-height: 100%;
224
+ margin: 1em 0;
225
+ }
226
+ h4, h5 {
227
+ font-weight: bold;
228
+ color: #000000;
229
+ margin: 1em 0 0.5em;
230
+ }
231
+ h4 { font-size: 125% }
232
+ h5 { font-size: 100% }
233
+ p {
234
+ margin: 0.7em 1em;
235
+ text-indent: 1em;
236
+ }
237
+ div.footnotes {
238
+ padding-top: 1em;
239
+ color: #090909;
240
+ }
241
+ div#header {
242
+ margin-top: 1em;
243
+ padding-bottom: 1em;
244
+ border-bottom: 1px dotted black;
245
+ }
246
+ div#header > form {
247
+ display: float;
248
+ float: right;
249
+ text-align: right;
250
+ }
251
+ a.filename {
252
+ color: #666666;
253
+ }
254
+ footer {
255
+ border-top: 1px dotted black;
256
+ padding: 0.5em;
257
+ font-size: 80%;
258
+ text-align: right;
259
+ margin: 5em 0 1em;
260
+ }
261
+ --></style>
262
+ <script>
263
+ function copy(text) {
264
+ prompt("Copy filepath below:", text);
265
+ }
266
+ </script>
267
+ #{CUSTOM_HEADER}
268
+ </head>
269
+ <body>
270
+ #{CUSTOM_BODY}
271
+ HTML
272
+ link_str = ""
273
+ uri = ""
274
+ path.split('/').each do |s|
275
+ next if s == ''
276
+ uri += "/" + s
277
+ link_str += File::SEPARATOR + "<a href='#{uri}'>#{s}</a>"
278
+ end
279
+ link_str += " <a class='filename' href=\"javascript:copy('#{docpath(uri)}');\">[copy]</a>"
280
+ uri.gsub!('/'+File::basename(uri), "") if File.file?(path(uri))
281
+ link_str = "<a href='/'>#{DOCUMENT_ROOT}</a>" + link_str
282
+ search_form = <<HTML
283
+ <form action="/search" method="get">
284
+ <input name="path" type="hidden" value="#{uri}" />
285
+ <input name="q" type="text" value="#{q}" size="24" />
286
+ <input type="submit" value="search" />
287
+ </form>
288
+ HTML
289
+ return html + "<div id=\"header\">#{link_str}#{search_form}</div>"
290
+ end
291
+
292
+ def footer_html
293
+ html = <<HTML
294
+ #{CUSTOM_FOOTER}
295
+ <footer>
296
+ <a href="https://github.com/daimatz/mamemose">mamemose: Markdown memo server</a>
297
+ </footer>
298
+ </body>
299
+ </html>
300
+ HTML
301
+ return html
302
+ end
303
+
304
+ def uri(path)
305
+ s = File::expand_path(path).gsub(DIR, "").gsub(File::SEPARATOR, '/')
306
+ return s == '' ? '/' : s
307
+ end
308
+
309
+ def path(uri)
310
+ return File.join(DIR, uri.gsub('/', File::SEPARATOR))
311
+ end
312
+
313
+ def docpath(uri)
314
+ return File.join(DOCUMENT_ROOT, uri.gsub('/', File::SEPARATOR)).gsub(/#{File::SEPARATOR}$/, "")
315
+ end
316
+
317
+ def link_list(title, link)
318
+ file = path(link)
319
+ str = File.file?(file) ? sprintf("%.1fKB", File.size(file) / 1024.0) : "dir"
320
+ return "- [#{title}](#{link}) <a class='filename' href=\"javascript:copy('#{docpath(link)}');\">[#{File.basename(link)}, #{str}]</a>\n"
321
+ end
322
+
323
+ def markdown?(file)
324
+ return file =~ MARKDOWN_PATTERN
325
+ end
326
+
327
+ def ignore?(file)
328
+ file = File::basename(file)
329
+ IGNORE_FILES.each do |s|
330
+ return true if s.class == String && s == file
331
+ return true if s.class == Regexp && s =~ file
332
+ end
333
+ return false
334
+ end
335
+
336
+ def get_title(filename, str="")
337
+ return File::basename(filename) if !markdown?(filename)
338
+ title = str.split(/$/)[0]
339
+ return title =~ /^\s*$/ ? File::basename(filename) : title
340
+ end
341
+
342
+ def markdown(text)
343
+ markdown = Redcarpet::Markdown.new(HTMLwithSyntaxHighlighter,
344
+ {:strikethrough => true,
345
+ :autolink => true,
346
+ :fenced_code_blocks => true})
347
+ markdown.render(text)
348
+ end
349
+ end
data/mamemose.gemspec ADDED
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/mamemose/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["daimatz"]
6
+ gem.email = ["dai@daimatz.net"]
7
+ gem.description = %q{Markdown memo server}
8
+ gem.summary = %q{Markdown memo server}
9
+ gem.homepage = "https://github.com/daimatz/mamemose"
10
+
11
+ gem.files = `git ls-files`.split($/)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "mamemose"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Mamemose::VERSION
17
+
18
+ gem.add_dependency "redcarpet", ">= 2.2.0"
19
+ gem.add_dependency "htmlentities", ">= 4.3.0"
20
+ gem.add_dependency 'thor', '>= 0.13.6'
21
+ end
data/sample.png ADDED
Binary file
metadata ADDED
@@ -0,0 +1,104 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mamemose
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - daimatz
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-11-30 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: redcarpet
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 2.2.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 2.2.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: htmlentities
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: 4.3.0
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: 4.3.0
46
+ - !ruby/object:Gem::Dependency
47
+ name: thor
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: 0.13.6
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: 0.13.6
62
+ description: Markdown memo server
63
+ email:
64
+ - dai@daimatz.net
65
+ executables:
66
+ - mamemose
67
+ extensions: []
68
+ extra_rdoc_files: []
69
+ files:
70
+ - .gitignore
71
+ - Gemfile
72
+ - LICENSE
73
+ - README.md
74
+ - Rakefile
75
+ - bin/mamemose
76
+ - lib/mamemose.rb
77
+ - lib/mamemose/version.rb
78
+ - mamemose.gemspec
79
+ - sample.png
80
+ homepage: https://github.com/daimatz/mamemose
81
+ licenses: []
82
+ post_install_message:
83
+ rdoc_options: []
84
+ require_paths:
85
+ - lib
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ! '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ none: false
94
+ requirements:
95
+ - - ! '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ requirements: []
99
+ rubyforge_project:
100
+ rubygems_version: 1.8.24
101
+ signing_key:
102
+ specification_version: 3
103
+ summary: Markdown memo server
104
+ test_files: []