Skip to content

Instantly share code, notes, and snippets.

@tamoot
Created August 17, 2017 08:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tamoot/bd68c061f2b8d07392bfd7912135995a to your computer and use it in GitHub Desktop.
Save tamoot/bd68c061f2b8d07392bfd7912135995a to your computer and use it in GitHub Desktop.
tDiary GFMスタイルのプラグイン記法において、ヒアドキュメントをサポート
diff --git a/lib/tdiary/style/gfm.rb b/lib/tdiary/style/gfm.rb
index 1782294..466c18d 100644
--- a/lib/tdiary/style/gfm.rb
+++ b/lib/tdiary/style/gfm.rb
@@ -3,6 +3,7 @@
require 'github/markdown'
require 'rouge'
require 'twitter-text'
+require 'pp'
module TDiary
module Style
@@ -13,12 +14,15 @@ module TDiary
@subtitle.sub!(/^\#\s*/,'')
@body ||= ''
+ @plugin_syntax = method(:valid_plugin_syntax?)
+
@categories = get_categories
@stripped_subtitle = strip_subtitle
@subtitle_to_html = @subtitle ? to_html('# ' + @subtitle).gsub(/\A<h\d>|<\/h\d>\z/io, '') : nil
@stripped_subtitle_to_html = @stripped_subtitle ? to_html('# ' + @stripped_subtitle).gsub(/\A<h\d>|<\/h\d>\z/io, '') : nil
@body_to_html = to_html(@body)
+
end
def subtitle=(subtitle)
@@ -51,16 +55,64 @@ module TDiary
private
+ def valid_plugin_syntax?(code)
+ /['"]/ !~ code.gsub(/\\\\/, "").gsub(/\\['"]/,"").gsub(/'[^']*'|"[^"]*"/m, "")
+ end
+
+ def extract_and_replace_plugin_blocks(text)
+ s = StringScanner.new(text)
+
+ extract_list = []
+ count = 0
+ replaced_text = ""
+
+ while chunk = s.scan_until(/\{\{/)
+ chunk[-2, 2] = ""
+ replaced_text << chunk
+
+ if plugin_str = extract_plugin_block(s)
+ replaced_text << "@@tdiary_style_gfm_plugin#{count}@@"
+ count += 1
+
+ part_erb = "<%="
+ part_erb << plugin_str
+ part_erb << " %>"
+
+ extract_list << [ plugin_str, part_erb ]
+ end
+ end
+
+ replaced_text << s.rest
+
+ return extract_list, replaced_text
+ end
+
+ def extract_plugin_block(s)
+ pos = s.pos
+ buf = ""
+ while chunk = s.scan_until(/\}\}/)
+ buf << chunk
+ buf.chomp!("}}")
+ if @plugin_syntax.call(buf)
+ return buf
+ end
+ end
+ s.pos = pos
+ nil
+ end
+
def to_html(string)
r = string.dup
# 1. Stash plugin calls
plugin_stashes = []
- r.gsub!(/\{\{(.*?)\}\}/) do |matched|
- # Convert `{{ }}' to erb tags
- plugin_stashes.push([matched, "<%=#{$1}%>"])
- "@@tdiary_style_gfm_plugin#{plugin_stashes.length - 1}@@"
+ # Convert `{{ }}' to erb tags
+ plugin_raw_and_erb_list, replaced_text = extract_and_replace_plugin_blocks(r)
+ plugin_raw_and_erb_list.each do |plugin_str, erb_str|
+ plugin_stashes.push([ plugin_str, erb_str ])
end
+ r = replaced_text
# 2. Apply markdown conversion
r = GitHub::Markdown.to_html(r, :gfm) do |code, lang|
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment