yapra 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.
Files changed (104) hide show
  1. data/History.txt +4 -0
  2. data/LICENCE +22 -0
  3. data/License.txt +22 -0
  4. data/Manifest.txt +103 -0
  5. data/PostInstall.txt +7 -0
  6. data/README.txt +66 -0
  7. data/Rakefile +13 -0
  8. data/bin/yapra +52 -0
  9. data/config/hoe.rb +75 -0
  10. data/config/requirements.rb +15 -0
  11. data/legacy_plugins/Download/nicovideo.rb +45 -0
  12. data/legacy_plugins/Feed/custom_feed.rb +87 -0
  13. data/legacy_plugins/Feed/google_calendar.rb +51 -0
  14. data/legacy_plugins/Feed/google_search_history.rb +45 -0
  15. data/legacy_plugins/Feed/hatena_graph.rb +37 -0
  16. data/legacy_plugins/Feed/lirs.rb +36 -0
  17. data/legacy_plugins/Filter/Translations/yahoo.rb +40 -0
  18. data/legacy_plugins/Filter/apply_text_html.rb +26 -0
  19. data/legacy_plugins/Filter/average.rb +6 -0
  20. data/legacy_plugins/Filter/deduped.rb +51 -0
  21. data/legacy_plugins/Filter/find_num.rb +8 -0
  22. data/legacy_plugins/Filter/find_regex.rb +9 -0
  23. data/legacy_plugins/Filter/fresh.rb +9 -0
  24. data/legacy_plugins/Filter/get_html.rb +11 -0
  25. data/legacy_plugins/Filter/grep.rb +16 -0
  26. data/legacy_plugins/Filter/invert.rb +14 -0
  27. data/legacy_plugins/Filter/sort.rb +10 -0
  28. data/legacy_plugins/Filter/subs.rb +6 -0
  29. data/legacy_plugins/Filter/to_integer.rb +4 -0
  30. data/legacy_plugins/Publish/delicious.rb +91 -0
  31. data/legacy_plugins/Publish/google_calendar.rb +58 -0
  32. data/legacy_plugins/Publish/hatena_bookmark.rb +47 -0
  33. data/legacy_plugins/Publish/hatena_diary_writer.rb +53 -0
  34. data/legacy_plugins/Publish/hatena_graph.rb +39 -0
  35. data/legacy_plugins/Publish/lingr.rb +110 -0
  36. data/legacy_plugins/Publish/mixi_diary_writer.rb +104 -0
  37. data/legacy_plugins/Publish/scuttle.rb +92 -0
  38. data/legacy_plugins/Publish/twitter.rb +35 -0
  39. data/legacy_plugins/RSS/load.rb +38 -0
  40. data/legacy_plugins/RSS/save.rb +41 -0
  41. data/legacy_plugins/Yaml/load.rb +5 -0
  42. data/legacy_plugins/Yaml/save.rb +9 -0
  43. data/legacy_plugins/argv.rb +5 -0
  44. data/legacy_plugins/concat.rb +18 -0
  45. data/legacy_plugins/const_list.rb +15 -0
  46. data/legacy_plugins/first.rb +11 -0
  47. data/legacy_plugins/head.rb +14 -0
  48. data/legacy_plugins/load_path.rb +21 -0
  49. data/legacy_plugins/plagger.rb +94 -0
  50. data/legacy_plugins/plugin_from_uri.rb +31 -0
  51. data/legacy_plugins/pluginbase.rb +4 -0
  52. data/legacy_plugins/print.rb +15 -0
  53. data/legacy_plugins/reverse.rb +10 -0
  54. data/legacy_plugins/send_msg.rb +18 -0
  55. data/legacy_plugins/stdin.rb +6 -0
  56. data/legacy_plugins/stdout.rb +6 -0
  57. data/lib/yapra/config.rb +103 -0
  58. data/lib/yapra/inflector.rb +55 -0
  59. data/lib/yapra/legacy_plugin/advance_mode_registry.rb +38 -0
  60. data/lib/yapra/legacy_plugin/base.rb +26 -0
  61. data/lib/yapra/legacy_plugin/compatible_mode_registry.rb +34 -0
  62. data/lib/yapra/legacy_plugin/registry_factory.rb +21 -0
  63. data/lib/yapra/legacy_plugin.rb +5 -0
  64. data/lib/yapra/pipeline.rb +74 -0
  65. data/lib/yapra/plugin/base.rb +14 -0
  66. data/lib/yapra/plugin/context_aware.rb +14 -0
  67. data/lib/yapra/plugin/erb_applier.rb +15 -0
  68. data/lib/yapra/plugin/feed_item_operator.rb +21 -0
  69. data/lib/yapra/plugin/mechanize_base.rb +26 -0
  70. data/lib/yapra/plugin.rb +5 -0
  71. data/lib/yapra/runtime.rb +36 -0
  72. data/lib/yapra/version.rb +9 -0
  73. data/lib/yapra.rb +44 -0
  74. data/lib-plugins/yapra/plugin/config/agent.rb +34 -0
  75. data/lib-plugins/yapra/plugin/config/basic_auth.rb +19 -0
  76. data/lib-plugins/yapra/plugin/config/web_post.rb +21 -0
  77. data/lib-plugins/yapra/plugin/feed/custom.rb +41 -0
  78. data/lib-plugins/yapra/plugin/feed/load.rb +29 -0
  79. data/lib-plugins/yapra/plugin/filter/entry_full_text.rb +59 -0
  80. data/lib-plugins/yapra/plugin/publish/file_download.rb +109 -0
  81. data/lib-plugins/yapra/plugin/publish/gmail.rb +27 -0
  82. data/lib-plugins/yapra/plugin/publish/imap.rb +82 -0
  83. data/lib-plugins/yapra/plugin/test/append_entry.rb +25 -0
  84. data/plugins/Filter/deduped.rb +57 -0
  85. data/plugins/Filter/sort.rb +28 -0
  86. data/plugins/Filter/subs.rb +16 -0
  87. data/script/console +10 -0
  88. data/script/destroy +14 -0
  89. data/script/generate +14 -0
  90. data/script/txt2html +82 -0
  91. data/setup.rb +1585 -0
  92. data/spec/spec.opts +1 -0
  93. data/spec/spec_helper.rb +11 -0
  94. data/spec/yapra_spec.rb +11 -0
  95. data/tasks/deployment.rake +34 -0
  96. data/tasks/environment.rake +7 -0
  97. data/tasks/rspec.rake +21 -0
  98. data/tasks/website.rake +17 -0
  99. data/website/index.html +115 -0
  100. data/website/index.txt +57 -0
  101. data/website/javascripts/rounded_corners_lite.inc.js +285 -0
  102. data/website/stylesheets/screen.css +138 -0
  103. data/website/template.html.erb +48 -0
  104. metadata +170 -0
@@ -0,0 +1,29 @@
1
+ require 'yapra/plugin/mechanize_base'
2
+
3
+ module Yapra::Plugin::Feed
4
+ class Load < Yapra::Plugin::MechanizeBase
5
+ def run(data)
6
+ urls =
7
+ if config['url'].kind_of?(Array)
8
+ config['url']
9
+ else
10
+ [ config['url'] ]
11
+ end
12
+
13
+ urls.each.do |url|
14
+ source = agent.get(url).body
15
+ rss = nil
16
+ begin
17
+ rss = RSS::Parser.parse(cont)
18
+ rescue
19
+ rss = RSS::Parser.parse(cont, false)
20
+ end
21
+ rss.items.each do |item|
22
+ data << item
23
+ end
24
+ end
25
+
26
+ data
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,59 @@
1
+ ## Filter::EntryFullText -- Yuanying
2
+ ##
3
+ ## get the entry full text from page with WWW::Mechanize.
4
+ ##
5
+ ## - module: Filter::EntryFullText
6
+ ## config:
7
+ ## regexp: http://www\.pixiv\.net/*
8
+ ## extract_xpath:
9
+ ## title: '//title/text()'
10
+ ## dc_creator: "//div[@id='profile']/div/text()"
11
+ ## author: "//div[@id='profile']/div/text()"
12
+ ## description: "//div[@id='content2']"
13
+ ## apply_template_after_extracted:
14
+ ## content_encoded: '<div><%= title %></div>'
15
+ ##
16
+ require 'yapra/plugin/mechanize_base'
17
+
18
+ module Yapra::Plugin::Filter
19
+ class EntryFullText < Yapra::Plugin::MechanizeBase
20
+ def run(data)
21
+ regexp = nil
22
+ if config['regexp']
23
+ regexp = Regexp.new(config['regexp'])
24
+ else
25
+ regexp = /^(https?|ftp)(:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)$/
26
+ end
27
+
28
+ wait = config['wait'] || 1
29
+
30
+ data.map! do |item|
31
+ url = item
32
+ if item.respond_to?('link')
33
+ url = item.link
34
+ end
35
+
36
+ if regexp =~ url
37
+ page = agent.get(url)
38
+ sleep wait
39
+ logger.info "Process: #{url}"
40
+
41
+ unless(item.instance_of?(RSS::RDF::Item))
42
+ new_item = RSS::RDF::Item.new
43
+ new_item.title = item.title rescue item.to_s
44
+ new_item.date = item.date rescue Time.now
45
+ new_item.description = item.description rescue item.to_s
46
+ new_item.link = item.link rescue '#'
47
+ item = new_item
48
+ end
49
+
50
+ extract_attribute_from page.root, item
51
+
52
+ end
53
+ item
54
+ end
55
+
56
+ data
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,109 @@
1
+ ## Publish::FileDownload -- Yuanying
2
+ ##
3
+ ## download file with WWW::Mechanize.
4
+ ##
5
+ ## example:
6
+ ##
7
+ ## - module: Publish::FileDownload
8
+ ## config:
9
+ ## regexp: http://www\.yahoo\.co\.jp/*
10
+ ## dir: '/Users/yuanying/Downloads/'
11
+ ## auto_suffix: true
12
+ ## before_hook: "agent.get('http://www.yahoo.co.jp/'); sleep 1"
13
+ ## url:
14
+ ## attribute: link
15
+ ## replace: index(\d*?)\.html
16
+ ## to: file\1.zip
17
+ ## filename:
18
+ ## attribute: title
19
+ ## replace: 'Yahoo'
20
+ ## to: ''
21
+ ## referrer:
22
+ ## attribute: link
23
+ ## replace: 'zip'
24
+ ## to: 'html'
25
+ ##
26
+ require 'yapra/plugin/mechanize_base'
27
+
28
+ module Yapra::Plugin::Publish
29
+ class FileDownload < Yapra::Plugin::MechanizeBase
30
+ def run(data)
31
+ regexp = nil
32
+ if config['regexp']
33
+ regexp = Regexp.new(config['regexp'])
34
+ else
35
+ regexp = /^(https?|ftp)(:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)$/
36
+ end
37
+
38
+ wait = config['wait'] || 3
39
+
40
+ data.each do |item|
41
+ url = construct_data(config['url'], item, item.respond_to?('link') ? item.link : item)
42
+
43
+ if regexp =~ url
44
+ referrer = construct_data(config['referrer'], item)
45
+ download(item, url, referrer)
46
+ sleep wait
47
+ end
48
+ end
49
+
50
+ data
51
+ end
52
+
53
+ protected
54
+ def construct_data(config, item, original=nil)
55
+ if config && config['attribute']
56
+ if item.respond_to?(config['attribute'])
57
+ original = item.__send__(config['attribute'])
58
+ end
59
+ elsif config
60
+ original = item
61
+ end
62
+
63
+ if original && config && config['replace']
64
+ original = original.gsub(config['replace'], config['to'] || Time.now.to_s)
65
+ end
66
+
67
+ original
68
+ end
69
+
70
+ def discover_extensions page
71
+ require 'mime/types'
72
+ types = MIME::Types[page.content_type]
73
+ if types.size > 0 && types[0].extensions.size > 0
74
+ return type[0].extensions[0]
75
+ else
76
+ logger.info 'suitable extention is not found.'
77
+ return nil
78
+ end
79
+ rescue LoadError => ex
80
+ logger.warn 'require mime-types is failed.'
81
+ end
82
+
83
+ def download(item, url, referrer)
84
+ dir = config['dir']
85
+ filename = construct_data(config['filename'], item)
86
+
87
+ if config['before_hook']
88
+ eval(config['before_hook'])
89
+ end
90
+ page = agent.get(url, referrer)
91
+ logger.info "Download: #{url}"
92
+ if config['after_hook']
93
+ eval(config['after_hook'])
94
+ end
95
+
96
+ filename = page.filename unless filename
97
+
98
+ if config['auto_suffix']
99
+ ext = discover_extensions(page)
100
+ filename = "#{filename}.#{ext}" if ext
101
+ end
102
+
103
+ path = File.join(dir, filename)
104
+ open(path, 'w') do |io|
105
+ io.write page.body
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,27 @@
1
+ # module: Publish::Gmail -- Yuanying
2
+ #
3
+ # publish entry to imap mail.
4
+ #
5
+ # example:
6
+ #
7
+ # - module: Publish::Gmail
8
+ # config:
9
+ # username: username
10
+ # password: password
11
+ # wait: 1
12
+ # mail:
13
+ # subject_prefix: '[Yapra]'
14
+ # from: 'test@example.com'
15
+ # to: 'test2@example.com'
16
+ #
17
+ require 'net/imap'
18
+ require 'yapra/plugin/publish/imap'
19
+
20
+ module Yapra::Plugin::Publish
21
+ class Gmail < Yapra::Plugin::Publish::Imap
22
+ protected
23
+ def create_imap server, port, usessl
24
+ Net::IMAP.new('imap.gmail.com', 993, true)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,82 @@
1
+ # module: Publish::Imap -- Yuanying
2
+ #
3
+ # publish entry to imap mail.
4
+ #
5
+ # example:
6
+ #
7
+ # - module: Publish::Imap
8
+ # config:
9
+ # username: username
10
+ # password: password
11
+ # imap_server: imap.gmail.com
12
+ # port: 993
13
+ # ssl: on
14
+ # wait: 1
15
+ # mail:
16
+ # subject_prefix: '[Yapra]'
17
+ # from: 'test@example.com'
18
+ # to: 'test2@example.com'
19
+ #
20
+ require 'net/imap'
21
+ require 'yapra/plugin/base'
22
+
23
+ module Yapra::Plugin::Publish
24
+ class Imap < Yapra::Plugin::Base
25
+ def run(data)
26
+ username = config['username']
27
+ password = config['password']
28
+ server = config['imap_server'] || 'imap.gmail.com'
29
+ port = config['port'] || 993
30
+ usessl = ('off' != config['ssl'])
31
+ mailbox = config['mailbox'] || 'inbox'
32
+ wait = config['wait'] || 1
33
+
34
+ unless config['mail']
35
+ config['mail'] = {}
36
+ end
37
+ subject_prefix = config['mail']['subject_prefix'] || ''
38
+ from = config['mail']['from'] || 'yapra@localhost'
39
+ to = config['mail']['to'] || 'me@localhost'
40
+
41
+ imap = create_imap server, port, usessl
42
+ logger.info(imap.greeting)
43
+
44
+ imap.login(username, password)
45
+ imap.examine(mailbox)
46
+ data.each do |item|
47
+ date = item.date || item.dc_date || Time.now
48
+ content = item.content_encoded || item.description || 'from Yapra.'
49
+ content = [content].pack('m')
50
+ imap.append("inbox", <<EOF.gsub(/¥n/, "¥r¥n"), nil, date)
51
+ From: #{from}
52
+ To: #{to}
53
+ Date: #{date.rfc2822}
54
+ MIME-Version: 1.0
55
+ Content-type: text/html; charset=UTF-8
56
+ Content-transfer-encoding: base64
57
+ X-Mailer: Yapra 0.1
58
+ Subject: #{encode_field(subject_prefix + item.title)}
59
+
60
+ #{content}
61
+ EOF
62
+ sleep wait
63
+ end
64
+ imap.disconnect
65
+
66
+ data
67
+ end
68
+
69
+ protected
70
+ def create_imap server, port, usessl
71
+ logger.debug("server: #{server}:#{port}, usessl = #{usessl}")
72
+ Net::IMAP.new(server, port, usessl)
73
+ end
74
+ def encode_field field
75
+ #field.gsub(/[ -瑤]\S*\s*/) {|x|
76
+ field.scan(/.{1,10}/).map {|y|
77
+ "=?UTF-8?B?" + y.to_a.pack('m').chomp + "?="
78
+ }.join("\n ")
79
+ #}
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,25 @@
1
+ # module: Test::AppendEntry -- Yuanying
2
+ #
3
+ # append entry to data array.
4
+ #
5
+ # example:
6
+ #
7
+ # - module: Test::AppendEntry
8
+ # config:
9
+ # title: 'title'
10
+ # description: 'description.'
11
+ #
12
+ require 'yapra/plugin/base'
13
+
14
+ module Yapra::Plugin::Test
15
+ class AppendEntry < Yapra::Plugin::Base
16
+ def run(data)
17
+ item = RSS::RDF::Item.new
18
+ plugin_config.each do |k, v|
19
+ set_attribute_to item, k, v
20
+ end
21
+ data << item
22
+ data
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,57 @@
1
+ ## Filter::deduped - Plugin to get Deduped entries -- emergent
2
+ ##
3
+ ## Plugin to get Deduped entries
4
+ ## Cache path can be set.
5
+ ##
6
+ ## - module: Filter::deduped
7
+ ## config:
8
+ ## path: /tmp/cache/hoge
9
+ ##
10
+ require 'pathname'
11
+ require 'digest/md5'
12
+
13
+ def mkdir_p path
14
+ begin
15
+ Dir.mkdir(path)
16
+ rescue Errno::ENOENT
17
+ mkdir_p Pathname.new(path).parent
18
+ retry
19
+ rescue Errno::EACCES
20
+ raise
21
+ end
22
+ 0
23
+ end
24
+
25
+ def deduped config, data
26
+ cacheroot = Pathname(__FILE__).parent.parent.parent.realpath + 'cache'
27
+ cachepath = Pathname.new(config['path']) || root
28
+ if cachepath.relative?
29
+ cachepath = cacheroot + cachepath
30
+ end
31
+ #puts 'cache path: ' + cachepath
32
+
33
+ if !File.exists?(cachepath)
34
+ begin
35
+ mkdir_p cachepath
36
+ rescue
37
+ STDERR.puts "could'nt make cache directory"
38
+ return data
39
+ end
40
+ end
41
+
42
+ attribute = config['attribute']
43
+
44
+ deduped_data = data.select {|d|
45
+ v = d.link rescue d.to_s
46
+ if attribute && d.respond_to?(attribute)
47
+ v = d.__send__(attribute).to_s
48
+ end
49
+ hashpath = cachepath.to_s + '/' + Digest::MD5.hexdigest(v)
50
+ if File.exists?(hashpath)
51
+ false
52
+ else
53
+ File.open(hashpath, "wb").write(v) rescue false
54
+ end
55
+ }
56
+ return deduped_data
57
+ end
@@ -0,0 +1,28 @@
1
+ def create_compare_proc config
2
+ if(config==nil || config["method"] == nil)
3
+ return lambda do |a, b|
4
+ a <=> b
5
+ end
6
+ elsif config["method"].kind_of?(Hash)
7
+ return lambda do |a, b|
8
+ eval_pragger(config["method"],[a])[0] <=> eval_pragger(config["method"],[b])[0]
9
+ end
10
+ else
11
+ return lambda do |a, b|
12
+ method = config['method']
13
+ a = a.respond_to?(method) ? a.__send__(method) : nil
14
+ b = b.respond_to?(method) ? b.__send__(method) : nil
15
+ return a <=> b if a.respond_to?('<=>')
16
+ return b <=> a if b.respond_to?('<=>')
17
+ nil
18
+ end
19
+ end
20
+ end
21
+
22
+ def sort(config,data)
23
+ proc = create_compare_proc(config)
24
+ return data.sort do|a, b|
25
+ proc.call(a, b)
26
+ end
27
+ end
28
+
@@ -0,0 +1,16 @@
1
+ def subs(config,data)
2
+ reg = Regexp.new(config["regex"])
3
+ to = config["to"]
4
+ attribute = config['attribute']
5
+ data.map! do |i|
6
+ if attribute
7
+ if i.respond_to?(attribute) && i.respond_to?("#{attribute}=")
8
+ i.__send__("#{attribute}=", i.__send__("#{attribute}").gsub(reg, to))
9
+ end
10
+ else
11
+ i = i.gsub(reg,to)
12
+ end
13
+ i
14
+ end
15
+ return data
16
+ end
data/script/console ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/yapra.rb'}"
9
+ puts "Loading yapra gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
data/script/destroy ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
data/script/generate ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
data/script/txt2html ADDED
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ GEM_NAME = 'yapra' # what ppl will type to install your gem
4
+ RUBYFORGE_PROJECT = 'yapra'
5
+
6
+ require 'rubygems'
7
+ begin
8
+ require 'newgem'
9
+ require 'rubyforge'
10
+ rescue LoadError
11
+ puts "\n\nGenerating the website requires the newgem RubyGem"
12
+ puts "Install: gem install newgem\n\n"
13
+ exit(1)
14
+ end
15
+ require 'redcloth'
16
+ require 'syntax/convertors/html'
17
+ require 'erb'
18
+ require File.dirname(__FILE__) + "/../lib/#{GEM_NAME}/version.rb"
19
+
20
+ version = Yapra::VERSION::STRING
21
+ download = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
22
+
23
+ def rubyforge_project_id
24
+ RubyForge.new.autoconfig["group_ids"][RUBYFORGE_PROJECT]
25
+ end
26
+
27
+ class Fixnum
28
+ def ordinal
29
+ # teens
30
+ return 'th' if (10..19).include?(self % 100)
31
+ # others
32
+ case self % 10
33
+ when 1: return 'st'
34
+ when 2: return 'nd'
35
+ when 3: return 'rd'
36
+ else return 'th'
37
+ end
38
+ end
39
+ end
40
+
41
+ class Time
42
+ def pretty
43
+ return "#{mday}#{mday.ordinal} #{strftime('%B')} #{year}"
44
+ end
45
+ end
46
+
47
+ def convert_syntax(syntax, source)
48
+ return Syntax::Convertors::HTML.for_syntax(syntax).convert(source).gsub(%r!^<pre>|</pre>$!,'')
49
+ end
50
+
51
+ if ARGV.length >= 1
52
+ src, template = ARGV
53
+ template ||= File.join(File.dirname(__FILE__), '/../website/template.html.erb')
54
+ else
55
+ puts("Usage: #{File.split($0).last} source.txt [template.html.erb] > output.html")
56
+ exit!
57
+ end
58
+
59
+ template = ERB.new(File.open(template).read)
60
+
61
+ title = nil
62
+ body = nil
63
+ File.open(src) do |fsrc|
64
+ title_text = fsrc.readline
65
+ body_text_template = fsrc.read
66
+ body_text = ERB.new(body_text_template).result(binding)
67
+ syntax_items = []
68
+ body_text.gsub!(%r!<(pre|code)[^>]*?syntax=['"]([^'"]+)[^>]*>(.*?)</\1>!m){
69
+ ident = syntax_items.length
70
+ element, syntax, source = $1, $2, $3
71
+ syntax_items << "<#{element} class='syntax'>#{convert_syntax(syntax, source)}</#{element}>"
72
+ "syntax-temp-#{ident}"
73
+ }
74
+ title = RedCloth.new(title_text).to_html.gsub(%r!<.*?>!,'').strip
75
+ body = RedCloth.new(body_text).to_html
76
+ body.gsub!(%r!(?:<pre><code>)?syntax-temp-(\d+)(?:</code></pre>)?!){ syntax_items[$1.to_i] }
77
+ end
78
+ stat = File.stat(src)
79
+ created = stat.ctime
80
+ modified = stat.mtime
81
+
82
+ $stdout << template.result(binding)