tdiary-style-markdown 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md ADDED
@@ -0,0 +1,41 @@
1
+ # TDiary::Style::Markdown
2
+
3
+ "Markdown" style for tDiary 2.x format.
4
+
5
+ This is based on tdiary-style-gfm gem.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'tdiary-style-markdown'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install tdiary-style-markdown
20
+
21
+ ## Usage
22
+
23
+ if you want to use this style, add @style into tdiary.conf below:
24
+
25
+ @style = 'Markdown'
26
+
27
+ ## Contributing
28
+
29
+ 1. Fork it
30
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
31
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
32
+ 4. Push to the branch (`git push origin my-new-feature`)
33
+ 5. Create new Pull Request
34
+
35
+ ## Copyright
36
+
37
+ * Copyright (C) 2003, TADA Tadashi <sho@spc.gr.jp>
38
+ * Copyright (C) 2004, MoonWolf <moonwolf@moonwolf.com>
39
+ * Copyright (C) 2012, kdmsnr <kdmsnr@gmail.com>
40
+ * Copyright (C) 2013, hsbt <shibata.hiroshi@gmail.com>
41
+ * Copyright (C) 2015, Kenji Okimoto <okimoto@clear-code.com>
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,7 @@
1
+ module TDiary
2
+ module Style
3
+ module Markdown
4
+ VERSION = "0.1.0"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,208 @@
1
+ require 'redcarpet'
2
+ require 'pygments'
3
+ require 'twitter-text'
4
+
5
+ module TDiary
6
+ module Style
7
+ class MarkdownSection
8
+ def initialize(fragment, author = nil)
9
+ @author = author
10
+ @subtitle, @body = fragment.split(/\n/, 2)
11
+ @subtitle.sub!(/^\#\s*/,'')
12
+ @body ||= ''
13
+
14
+ @categories = get_categories
15
+ @stripped_subtitle = strip_subtitle
16
+
17
+ @subtitle_to_html = @subtitle ? to_html('# ' + @subtitle).gsub(/\A<h\d>|<\/h\d>\z/io, '') : nil
18
+ @stripped_subtitle_to_html = @stripped_subtitle ? to_html('# ' + @stripped_subtitle).gsub(/\A<h\d>|<\/h\d>\z/io, '') : nil
19
+ @body_to_html = to_html(@body)
20
+ end
21
+
22
+ def subtitle=(subtitle)
23
+ @subtitle = (subtitle || '').sub(/^# /,"\##{categories_to_string} ")
24
+ @strip_subtitle = strip_subtitle
25
+ end
26
+
27
+ def categories=(categories)
28
+ @subtitle = "#{categories_to_string} " + (strip_subtitle || '')
29
+ @strip_subtitle = strip_subtitle
30
+ end
31
+
32
+ def to_src
33
+ r = ''
34
+ r << "\# #{@subtitle}\n" if @subtitle
35
+ r << @body
36
+ end
37
+
38
+ def do_html4(date, idx, opt)
39
+ subtitle = to_html('# ' + @subtitle)
40
+ subtitle.sub!( %r!<h3>(.+?)</h3>!m ) do
41
+ "<h3><%= subtitle_proc( Time.at( #{date.to_i} ), #{$1.dump.gsub( /%/, '\\\\045' )} ) %></h3>"
42
+ end
43
+ if opt['multi_user'] and @author then
44
+ subtitle.sub!(/<\/h3>/,%Q|[#{@author}]</h3>|)
45
+ end
46
+ r = subtitle
47
+ r << @body_to_html
48
+ end
49
+
50
+ private
51
+
52
+ def to_html(string)
53
+ r = string.dup
54
+
55
+ # 1. Stash plugin calls
56
+ plugin_stashes = []
57
+ r.gsub!(/\{\{(.*?)\}\}/) do |matched|
58
+ # Convert `{{ }}' to erb tags
59
+ plugin_stashes.push([matched, "<%=#{$1}%>"])
60
+ "@@tdiary-style-markdown-plugin#{plugin_stashes.length - 1}@@"
61
+ end
62
+
63
+ # 2. Apply markdown conversion
64
+ renderer = Redcarpet::Markdown.new(HTMLwithPygments,
65
+ fenced_code_blocks: true,
66
+ tables: true,
67
+ autolink: true,
68
+ footnotes: true)
69
+ r = renderer.render(r)
70
+
71
+ # 3. Stash <pre> and <code> tags
72
+ pre_tag_stashes = []
73
+ r.gsub!(/<pre(.*?)<\/pre>/m) do |matched|
74
+ pre_tag_stashes.push(matched)
75
+ "@@tdiary-style-markdown-pre_tag#{pre_tag_stashes.length - 1}@@"
76
+ end
77
+
78
+ code_tag_stashes = []
79
+ r.gsub!(/<code(.*?)<\/code>/m) do |matched|
80
+ code_tag_stashes.push(matched)
81
+ "@@tdiary-style-markdown-code_tag#{code_tag_stashes.length - 1}@@"
82
+ end
83
+
84
+ # 4. Convert miscellaneous
85
+ if pre_tag_stashes.none? && code_tag_stashes.none?
86
+ r = Twitter::Autolink.auto_link_usernames_or_lists(r)
87
+ end
88
+
89
+ r = r.emojify
90
+
91
+ # diary anchor
92
+ r.gsub!(/<h(\d)/) { "<h#{$1.to_i + 2}" }
93
+ r.gsub!(/<\/h(\d)/) { "</h#{$1.to_i + 2}" }
94
+
95
+ # my syntax
96
+ r.gsub!(/<a href="(\d{4}|\d{6}|\d{8}|\d{8}-\d+)[^\d]*?#?([pct]\d+)?">(.*?)<\/a>/) {
97
+ unless $3.empty?
98
+ %Q|<%=my "#{$1}#{$2}", "#{$3}" %>|
99
+ else
100
+ %Q|<%=my "#{$1}#{$2}", "#{$1}#{$2}" %>|
101
+ end
102
+ }
103
+
104
+ # 5. Unstash <pre>, <code> and plugin call
105
+ pre_tag_stashes.each.with_index do |str, i|
106
+ plugin_stashes.each.with_index do |(p_str, p_erb), j|
107
+ if str["@@tdiary-style-markdown-plugin#{j}@@"]
108
+ str["@@tdiary-style-markdown-plugin#{j}@@"] = CGI.escapeHTML(p_str)
109
+ end
110
+ end
111
+ r["@@tdiary-style-markdown-pre_tag#{i}@@"] = str
112
+ end
113
+ code_tag_stashes.each.with_index do |str, i|
114
+ plugin_stashes.each.with_index do |(p_str, p_erb), j|
115
+ if str["@@tdiary-style-markdown-plugin#{j}@@"]
116
+ str["@@tdiary-style-markdown-plugin#{j}@@"] = CGI.escapeHTML(p_str)
117
+ end
118
+ end
119
+ r["@@tdiary-style-markdown-code_tag#{i}@@"] = str
120
+ end
121
+ plugin_stashes.each.with_index do |(str, erb), i|
122
+ if r["@@tdiary-style-markdown-plugin#{i}@@"]
123
+ r["@@tdiary-style-markdown-plugin#{i}@@"] = erb
124
+ end
125
+ end
126
+
127
+ r
128
+ end
129
+
130
+ def get_categories
131
+ return [] unless @subtitle
132
+ cat = /(\\?\[([^\[]+?)\\?\])+/.match(@subtitle).to_a[0]
133
+ return [] unless cat
134
+ cat.scan(/\\?\[(.*?)\\?\]/).collect do |c|
135
+ c[0].split(/,/)
136
+ end.flatten
137
+ end
138
+
139
+ def strip_subtitle
140
+ return nil unless @subtitle
141
+ r = @subtitle.sub(/^((\\?\[[^\[]+?\]\\?)+\s+)?/, '')
142
+ if r.empty?
143
+ nil
144
+ else
145
+ r
146
+ end
147
+ end
148
+ end
149
+
150
+ class MarkdownDiary
151
+ def initialize(date, title, body, modified = Time.now)
152
+ init_diary
153
+ replace( date, title, body )
154
+ @last_modified = modified
155
+ end
156
+
157
+ def style
158
+ 'Markdown'
159
+ end
160
+
161
+ def append(body, author = nil)
162
+ in_code_block = false
163
+ section = nil
164
+ body.each_line do |l|
165
+ case l
166
+ when /^\#[^\#]/
167
+ if in_code_block
168
+ section << l
169
+ else
170
+ @sections << MarkdownSection.new(section, author) if section
171
+ section = l
172
+ end
173
+ when /^```/
174
+ in_code_block = !in_code_block
175
+ section << l
176
+ else
177
+ section = '' unless section
178
+ section << l
179
+ end
180
+ end
181
+ if section
182
+ section << "\n" unless section =~ /\n\n\z/
183
+ @sections << MarkdownSection.new(section, author)
184
+ end
185
+ @last_modified = Time.now
186
+ self
187
+ end
188
+
189
+ def add_section(subtitle, body)
190
+ @sections = MarkdownSection.new("\# #{subtitle}\n\n#{body}")
191
+ @sections.size
192
+ end
193
+ end
194
+
195
+ class HTMLwithPygments < Redcarpet::Render::HTML
196
+ def block_code(code, language)
197
+ Pygments.highlight(code, lexer: language)
198
+ end
199
+ end
200
+ end
201
+ end
202
+
203
+ # Local Variables:
204
+ # mode: ruby
205
+ # indent-tabs-mode: t
206
+ # tab-width: 3
207
+ # ruby-indent-level: 3
208
+ # End:
@@ -0,0 +1 @@
1
+ require "tdiary/style/markdown"
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'tdiary/style/markdown/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "tdiary-style-markdown"
8
+ spec.version = TDiary::Style::Markdown::VERSION
9
+ spec.authors = ["Kenji Okimoto"]
10
+ spec.email = ["okimoto@clear-code.com"]
11
+ spec.description = %q{Markdown Style for tDiary}
12
+ spec.summary = %q{Markdown Style for tDiary}
13
+ spec.homepage = "https://github.com/clear-code/tdiary-style-markdown"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency 'redcarpet'
22
+ spec.add_dependency 'pygments.rb'
23
+ spec.add_dependency 'twitter-text'
24
+ spec.add_dependency 'gemoji'
25
+
26
+ spec.add_development_dependency "bundler", "~> 1.3"
27
+ spec.add_development_dependency "rake"
28
+ spec.add_development_dependency "test-unit"
29
+ end
data/test/run-test.rb ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
3
+ #
4
+ # Copyright (C) 2013 Kouhei Sutou <kou@clear-code.com>
5
+ #
6
+ # This program is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
18
+
19
+ $VERBOSE = true
20
+
21
+ top_dir = File.expand_path(File.join(File.dirname(__FILE__), ".."))
22
+ lib_dir = File.join(top_dir, "lib")
23
+ test_dir = File.dirname(__FILE__)
24
+
25
+ require "test-unit"
26
+
27
+ $LOAD_PATH.unshift(lib_dir)
28
+
29
+ exit Test::Unit::AutoRunner.run(true, test_dir)