wpconv 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2684b45959f0ac30ea37d84efdc9fbf89bb23ee0
4
+ data.tar.gz: dec75301a95d5e1d3363562e176924f8da6368c4
5
+ SHA512:
6
+ metadata.gz: 3cb60ddc4ed0257d241f7e1de61ba4ef5d083dc81fda0077144eab093bc4c1721f0d48f3c63046165d39eacd0ccad2bb6f8353edc8cff37d674d07b780094e8e
7
+ data.tar.gz: 9834b73a132f01730f8187d517da78eb72550cdb9eb32dc84e7a4da552a7ad76e574e63c05913b0388700e351f91bcfc4e06e639de3e92bec17537127574a422
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ .DS_Store
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in wpconv.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 akahige
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.
@@ -0,0 +1,103 @@
1
+ # Wpconv
2
+
3
+ Converting Wordpress export XML to Markdown(or other format).
4
+
5
+ ## Installation
6
+
7
+ $ gem install wpconv
8
+
9
+ ## Usage
10
+
11
+ wpconv convert WP_XML_PATH
12
+
13
+ Options:
14
+ -o, [--output-dir=/path/to/output_dir]
15
+ -t, [--template=/path/to/your_template.erb]
16
+ -n, [--filename-format=date-name(default), name or id]
17
+ -f, [--filter=markdown(default), none or /path/to/your_filter.rb]
18
+
19
+ example:
20
+
21
+ $ wpconv convert wordpress.2014-08-21.xml -o /tmp -n id
22
+
23
+ This example creates Markdown files from Wordpress export XML.
24
+ The output directory is /tmp and the output filenames are based on Wordpress post_id in this case.
25
+
26
+ `-o` is to specify the output direcoty.
27
+
28
+ `-n` is to specify the format of filename.
29
+
30
+ `-t` and `-f` are advanced options to customize output. If you would like to use these options, you should write an erb template or some ruby code.
31
+ See templating and filter sections for more details.
32
+
33
+ ## Templating
34
+
35
+ You can create a custom erb template to adjust outputs as you like.
36
+
37
+ template valiables `@item` and `@channel` are available.
38
+ These are Hash objects including wordpress items and channel data.
39
+
40
+ Specify `-t` option if you would like to use your template.
41
+
42
+ $ wpconv convert wordpress.2014-08-21.xml -o /tmp -t my_markdown.erb
43
+
44
+ This is the default template for your information.
45
+
46
+ ---
47
+ title: <%= @item[:title] %>
48
+ date: <%= @item[:post_date] %>
49
+ layout: <%= @item[:post_type] %>
50
+ categories: [<%= @item[:categories].join(',') %>]
51
+ tags: [<%= @item[:tags].join(',') %>]
52
+ ---
53
+
54
+ <%= @item[:content] %>
55
+
56
+ ## Filter
57
+
58
+ You can use a custom filter for a camplicate converting logic.
59
+ A filter affects @item[:content].
60
+
61
+ You should write some ruby code for creating a custom filter.
62
+
63
+ The example below is a built in filter 'none'.
64
+ All filter classes should be under `Wpconv::Filter` module. And the class name should be the camelized file name.
65
+
66
+ module Wpconv
67
+ module Filter
68
+ class None
69
+ def self.apply(source_content)
70
+ source_content
71
+ end
72
+ end
73
+ end
74
+ end
75
+
76
+ Another example, creating 'my_filter'.
77
+
78
+ module Wpconv
79
+ module Filter
80
+ class MyFilter
81
+ def self.apply(source_content)
82
+ source_content.tap do |content|
83
+ content.gsub!(/foo/, 'bar')
84
+
85
+ # write the filter logic here...
86
+
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+
93
+ Specify `-f` option if you would like to use your filter.
94
+
95
+ $ wpconv convert wordpress.2014-08-21.xml -o /tmp -f my_filter.rb
96
+
97
+ ## Contributing
98
+
99
+ 1. Fork it ( https://github.com/[my-github-username]/wpconv/fork )
100
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
101
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
102
+ 4. Push to the branch (`git push origin my-new-feature`)
103
+ 5. Create a new Pull Request
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ desc "Run all specs in spec directory"
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task :default => :spec
@@ -0,0 +1,12 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'thor'
5
+ require 'pathname'
6
+
7
+ lib = Pathname.new(__FILE__).dirname.join('..', 'lib').expand_path
8
+ $LOAD_PATH.unshift lib.to_s
9
+
10
+ require 'wpconv'
11
+
12
+ Wpconv::CLI.start
@@ -0,0 +1,6 @@
1
+ require "wpconv/version"
2
+ require "wpconv/converter"
3
+ require "wpconv/cli"
4
+
5
+ module Wpconv
6
+ end
@@ -0,0 +1,15 @@
1
+ require 'thor'
2
+ require 'readline'
3
+
4
+ module Wpconv
5
+ class CLI < Thor
6
+ desc "convert WP_XML_PATH", "convert wordpress export xml to markdown."
7
+ option :output_dir, :type => :string, :aliases => '-o', :banner => '/path/to/output_dir'
8
+ option :template, :type => :string, :aliases => '-t', :banner => '/path/to/your_template.erb'
9
+ option :filename_format, :type => :string, :aliases => '-n', :banner => 'date-name(default), name or id'
10
+ option :filter, :type => :string, :aliases => '-f', :banner => 'markdown(default), none or /path/to/your_filter.rb'
11
+ def convert(wp_xml_path)
12
+ Wpconv::Converter.new.run(wp_xml_path, options)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,133 @@
1
+ require 'nokogiri'
2
+ require 'erb'
3
+ require 'active_support/all'
4
+
5
+ require 'wpconv/filter/markdown'
6
+ require 'wpconv/filter/none'
7
+
8
+ require 'wpconv/wp_xml/channel'
9
+ require 'wpconv/wp_xml/item'
10
+
11
+ module Wpconv
12
+ class Converter
13
+ DEFAULT_OPTIONS = {
14
+ output_dir: Dir.pwd,
15
+ template: File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'template', 'markdown.erb')),
16
+ filename_format: 'date-name',
17
+ filter: 'markdown'
18
+ }
19
+ BUILT_IN_FILTERS = ['markdown', 'none']
20
+
21
+ def run(wp_xml_path, options = {})
22
+ @wp_xml_path = wp_xml_path
23
+
24
+ @template = options[:template] || DEFAULT_OPTIONS[:template]
25
+ erb = File.open(@template) {|f| ERB.new(f.read)}
26
+
27
+ @output_base_dir = options[:output_dir] || DEFAULT_OPTIONS[:output_dir]
28
+ setup_output_dirs
29
+
30
+ @filename_format = options[:filename_format] || DEFAULT_OPTIONS[:filename_format]
31
+
32
+ @filter = options[:filter] || DEFAULT_OPTIONS[:filter]
33
+
34
+ print "converting...\n"
35
+ print_convert_settings
36
+
37
+ doc = ::Nokogiri::XML(File.open(@wp_xml_path).read)
38
+ @channel = WpXML::Channel.parse(doc.at('channel'))
39
+
40
+ @convert_counts = {page: 0, post: 0, other: 0}
41
+
42
+ doc.search('item').each do |doc_item|
43
+ @item = WpXML::Item.parse(doc_item)
44
+
45
+ # filter
46
+ if not BUILT_IN_FILTERS.include?(@filter)
47
+ @filter = "./#{@filter}" if not @filter =~ /\//
48
+ require @filter
49
+ end
50
+ filter_class_name = File.basename(@filter).sub(/.rb$/, '').camelize
51
+ @item[:content] = eval("Filter::#{filter_class_name}.apply(@item[:content])")
52
+
53
+ # output
54
+ File.open(File.join(item_output_dir, item_filename), "w") do |f|
55
+ converted = erb.result(binding)
56
+ f.write(converted)
57
+ end
58
+
59
+ increase_convert_count
60
+
61
+ print "."
62
+ end
63
+
64
+ print "done.\n"
65
+ print "#{@convert_counts[:page]} pages, #{@convert_counts[:post]} posts and #{@convert_counts[:other]} something items are converted.\n"
66
+ end
67
+
68
+ def setup_output_dirs
69
+ @output_dirs = {
70
+ page: File.join(@output_base_dir, 'pages'),
71
+ post: File.join(@output_base_dir, 'posts'),
72
+ other: File.join(@output_base_dir, 'others')
73
+ }
74
+ @output_dirs.each do |k, output_dir|
75
+ FileUtils.mkdir_p(output_dir)
76
+ end
77
+ end
78
+
79
+ def increase_convert_count
80
+ if @convert_counts.has_key? @item[:post_type].to_sym
81
+ @convert_counts[@item[:post_type].to_sym] += 1
82
+ else
83
+ @convert_counts[:other] += 1
84
+ end
85
+ end
86
+
87
+ def item_filename
88
+ post_name = @item[:post_name] == '' ? @item[:post_id] : @item[:post_name]
89
+ case @filename_format
90
+ when 'date-name'
91
+ "#{@item[:post_date].split(' ').first}-#{post_name}.md"
92
+ when 'name'
93
+ "#{post_name}.md"
94
+ when 'id'
95
+ "#{@item[:post_id]}.md"
96
+ else
97
+ "#{@item[:post_id]}.md"
98
+ end
99
+ end
100
+
101
+ def item_output_dir
102
+ case @item[:post_type]
103
+ when 'post'
104
+ @output_dirs[:post]
105
+ when 'page'
106
+ @output_dirs[:page]
107
+ else
108
+ @output_dirs[:other]
109
+ end
110
+ end
111
+
112
+ def print_convert_settings
113
+ print " soruce: #{@wp_xml_path}\n"
114
+ print " template: #{@template}\n"
115
+ print " output_dir: #{@output_base_dir}\n"
116
+ print " filename_format: #{@filename_format}\n"
117
+ print " filter: #{@filter}\n"
118
+ end
119
+
120
+ def default_template
121
+ File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'template', 'markdown.erb'))
122
+ end
123
+
124
+ def default_filename_format
125
+ 'date-name'
126
+ end
127
+
128
+ def default_filter
129
+ 'markdown'
130
+ end
131
+ end
132
+
133
+ end
@@ -0,0 +1,79 @@
1
+ require 'nokogiri'
2
+
3
+ module Wpconv
4
+ module Filter
5
+ class Markdown
6
+ # see. http://daringfireball.net/projects/markdown/syntax
7
+
8
+ BackslashEscapedCharacters = %w(\\ ` * _ { } [ ] \( \) # + - . !)
9
+
10
+ def self.apply(source_content)
11
+ escaped_source_content = escape_literal(source_content)
12
+ convert_html_tags(escaped_source_content)
13
+ end
14
+
15
+ def self.escape_literal(source_content)
16
+ html = Nokogiri::HTML(source_content)
17
+ source_content.tap do |content|
18
+ BackslashEscapedCharacters.each do |char|
19
+ content.gsub!(char) { "\\#{char}" }
20
+ end
21
+ end
22
+ end
23
+
24
+ def self.convert_html_tags(escaped_source_content)
25
+ escaped_source_content.tap do |content|
26
+ # Heading
27
+ {
28
+ 'h1' => '#',
29
+ 'h2' => '##',
30
+ 'h3' => '###',
31
+ 'h4' => '####',
32
+ 'h5' => '#####',
33
+ 'h6' => '######'
34
+ }.each do |tag, md|
35
+ content.gsub!(/<#{tag}>(.+?)<\/#{tag}>/m) { "#{md} #{$1.gsub(/\n/, '')}" } # remove LF in the header string
36
+ end
37
+
38
+ # List 定義リストは未サポート
39
+ %w(ul ol).each do |tag|
40
+ content.gsub!(/<\/?#{tag}>[\n]?/, '') # remove LF after the tag
41
+ end
42
+ content.gsub!(/[ \t]*?<li.*?>(.+?)<\/li>[ \t]*?/m) { "* #{$1.strip}" } # 数値リストも未対応
43
+
44
+ # hr
45
+ content.gsub!(/<hr\s?\/?>/, "\n---\n")
46
+
47
+ # pre and code
48
+ content.gsub!(/<pre.*?><code.*?>(.*?)<\/code><\/pre>/m) { "#{decode_markup_symbol($1).gsub(/^/, ' ')}" }
49
+
50
+ # code
51
+ content.gsub!(/<code.*?>(.*?)<\/code>/m) { '`` ' + decode_markup_symbol($1) + ' ``' }
52
+
53
+ # brockquote
54
+ content.gsub!(/<blockquote>(.*?)<\/blockquote>/m) { "#{$1.gsub(/^/, '> ')}" }
55
+
56
+ # em
57
+ content.gsub!(/<em>(.*?)<\/em>/m) { "*#{$1}*" }
58
+
59
+ # strong, b
60
+ ["strong", "b"].each do |tag|
61
+ content.gsub!(/<#{tag}>(.*?)<\/#{tag}>/m) { "**#{$1}**" }
62
+ end
63
+
64
+ # Link
65
+ content.gsub!(/<a.*?href=("|')(.+?)("|').*?>(.+?)<\/a>/m) { "[#{$4}](#{$2})" }
66
+
67
+ # Image
68
+
69
+ # Table?
70
+ end
71
+
72
+ end
73
+
74
+ def self.decode_markup_symbol(code)
75
+ code.gsub('&lt;', '<').gsub('&gt;', '>').gsub('&amp;', '&')
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,9 @@
1
+ module Wpconv
2
+ module Filter
3
+ class None
4
+ def self.apply(source_content)
5
+ source_content
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ module Wpconv
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,57 @@
1
+ module Wpconv
2
+ module WpXML
3
+ class Channel
4
+ def self.parse(doc_channel)
5
+ {}.tap do |channel|
6
+ %w(title link description pubDate language).each do |key|
7
+ if node = doc_channel.at(key)
8
+ channel[key.to_sym] = node.text
9
+ end
10
+ end
11
+
12
+ %w(wxr_version base_site_url base_blog_url).each do |key|
13
+ if node = doc_channel.at("wp|#{key}")
14
+ channel[key.to_sym] = node.text
15
+ end
16
+ end
17
+
18
+ # author
19
+ channel[:authors] = [].tap do |authors|
20
+ doc_channel.search("wp|author").each do |author|
21
+ authors.push({
22
+ id: author.at("wp|author_id").text,
23
+ login: author.at("wp|author_login").text,
24
+ email: author.at("wp|author_email").text,
25
+ name: author.at("wp|author_display_name").text,
26
+ first_name: author.at("wp|author_first_name").text,
27
+ last_name: author.at("wp|author_last_name").text
28
+ })
29
+ end
30
+ end
31
+
32
+ # category and tag
33
+ channel[:categories] = [].tap do |categories|
34
+ doc_channel.search("wp|category").each do |cat|
35
+ categories.push({
36
+ id: cat.at("wp|term_id").text,
37
+ name: cat.at("wp|cat_name").text,
38
+ nickname: cat.at("wp|category_nicename").text,
39
+ parent: cat.at("wp|category_parent").text
40
+ })
41
+ end
42
+ end
43
+
44
+ channel[:tags] = [].tap do |tags|
45
+ doc_channel.search("wp|tag").each do |tag|
46
+ tags.push({
47
+ id: tag.at("wp|term_id").text,
48
+ name: tag.at("wp|tag_name").text,
49
+ slug: tag.at("wp|tag_slug").text
50
+ })
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,41 @@
1
+ module Wpconv
2
+ module WpXML
3
+ class Item
4
+ def self.parse(doc_item)
5
+ {}.tap do |item|
6
+ %w(title link pubDate guid description).each do |key|
7
+ if node = doc_item.at(key)
8
+ item[key.to_sym] = node.text
9
+ end
10
+ end
11
+
12
+ item[:creator] = doc_item.at('dc|creator').text
13
+ item[:content] = doc_item.at('content|encoded').text
14
+ item[:excerpt] = doc_item.at('excerpt|encoded').text
15
+
16
+ %w(post_id post_date post_date_gmt comment_status ping_status post_name status post_parent menu_order post_type post_password is_sticky).each do |key|
17
+ if node = doc_item.at("wp|#{key}")
18
+ item[key.to_sym] = node.text
19
+ end
20
+ end
21
+
22
+ item[:categories] = []
23
+ item[:tags] = []
24
+ doc_item.search('category').each do |cat|
25
+ case cat["domain"]
26
+ when 'category'
27
+ item[:categories].push cat.text
28
+ when 'post_tag'
29
+ item[:tags].push cat.text
30
+ end
31
+ end
32
+
33
+ item[:postmeta] = {}
34
+ doc_item.search('wp|postmeta').each do |meta|
35
+ item[:postmeta][meta.at('wp|meta_key').text.to_sym] = meta.at('wp|meta_value').text
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,16 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ $TESTING=true
4
+
5
+ require 'rubygems'
6
+ require 'rspec'
7
+ require 'wpconv'
8
+
9
+ Dir[File.join(File.dirname(__FILE__), "..", "lib", "**/*.rb")].each do |f|
10
+ require f
11
+ end
12
+
13
+ RSpec.configure do |config|
14
+ config.color_enabled = true
15
+ config.filter_run_excluding :skip => true
16
+ end
@@ -0,0 +1,8 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe Wpconv::Converter do
5
+ before do
6
+ # Wpconv::Converter.new.run(wp_xml_path, options)
7
+ end
8
+ end
@@ -0,0 +1,150 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe Wpconv::Filter::Markdown do
5
+ describe "converting HTML tags" do
6
+ describe "heading" do
7
+ it "h1" do
8
+ content = Wpconv::Filter::Markdown.apply("<h1>hoge</h1>")
9
+ expect(content).to eq "# hoge"
10
+ end
11
+
12
+ it "h6" do
13
+ content = Wpconv::Filter::Markdown.apply("<h6>hoge</h6>")
14
+ expect(content).to eq "###### hoge"
15
+ end
16
+
17
+ it "h3(multiline)" do
18
+ content = Wpconv::Filter::Markdown.apply("<h3>ho\nge</h3>")
19
+ expect(content).to eq "### hoge"
20
+ end
21
+ end
22
+
23
+ describe "list" do
24
+ it "ul" do
25
+ content = Wpconv::Filter::Markdown.apply("<ul>")
26
+ expect(content).to eq ""
27
+ end
28
+
29
+ it "/ul before LF" do
30
+ content = Wpconv::Filter::Markdown.apply("</ul>\n")
31
+ expect(content).to eq ""
32
+ end
33
+
34
+ it "ul > li*" do
35
+ content = Wpconv::Filter::Markdown.apply("<ul><li>hoge</li>\n<li>fuga</li></ul>")
36
+ expect(content).to eq "* hoge\n* fuga"
37
+ end
38
+
39
+ it "ul > li(multiline)" do
40
+ content = Wpconv::Filter::Markdown.apply("<ul><li>ho\nge</li>")
41
+ expect(content).to eq "* ho\nge"
42
+ end
43
+ end
44
+
45
+ describe "hr" do
46
+ it "hr" do
47
+ content = Wpconv::Filter::Markdown.apply("<hr>")
48
+ expect(content).to eq "\n---\n"
49
+ end
50
+
51
+ it "hr/" do
52
+ content = Wpconv::Filter::Markdown.apply("<hr/>")
53
+ expect(content).to eq "\n---\n"
54
+ end
55
+
56
+ it "hr /" do
57
+ content = Wpconv::Filter::Markdown.apply("<hr />")
58
+ expect(content).to eq "\n---\n"
59
+ end
60
+ end
61
+
62
+ describe "pre and code" do
63
+ it "pre and code" do
64
+ content = Wpconv::Filter::Markdown.apply("<pre><code>hoge\nfuga</code></pre>")
65
+ expect(content).to eq " hoge\n fuga"
66
+ end
67
+
68
+ it "pre and code with class" do
69
+ content = Wpconv::Filter::Markdown.apply("<pre><code class='text'>hoge\nfuga</code></pre>")
70
+ expect(content).to eq " hoge\n fuga"
71
+ end
72
+
73
+ it "pre and code < > &" do
74
+ content = Wpconv::Filter::Markdown.apply("<pre><code>&lt;hoge&gt; &amp; &lt;fuga&gt;</code></pre>")
75
+ expect(content).to eq " <hoge> & <fuga>"
76
+ end
77
+
78
+ it "only pre" do
79
+ content = Wpconv::Filter::Markdown.apply("<pre class='text'>hoge\nfuga</pre>")
80
+ expect(content).to eq "<pre class='text'>hoge\nfuga</pre>"
81
+ end
82
+
83
+ it "code" do
84
+ content = Wpconv::Filter::Markdown.apply("a <code class='text'>hoge\nfuga</code> z")
85
+ expect(content).to eq "a `` hoge\nfuga `` z"
86
+ end
87
+
88
+ it "decode < > &" do
89
+ content = Wpconv::Filter::Markdown.apply("<code class='text'>&lt;hoge&gt; &amp; &lt;fuga&gt;</code>")
90
+ expect(content).to eq "`` <hoge> & <fuga> ``"
91
+ end
92
+ end
93
+
94
+ describe "blockquote" do
95
+ it "blockquote" do
96
+ content = Wpconv::Filter::Markdown.apply("<blockquote>hoge\nfuga</blockquote>")
97
+ expect(content).to eq "> hoge\n> fuga"
98
+ end
99
+ end
100
+
101
+ describe "em/strong/b" do
102
+ it "em" do
103
+ content = Wpconv::Filter::Markdown.apply("<em>hoge</em>")
104
+ expect(content).to eq "*hoge*"
105
+ end
106
+
107
+ it "em(multiline)" do
108
+ content = Wpconv::Filter::Markdown.apply("<em>hoge\nfuga</em>")
109
+ expect(content).to eq "*hoge\nfuga*"
110
+ end
111
+
112
+ it "strong" do
113
+ content = Wpconv::Filter::Markdown.apply("<strong>hoge</strong>")
114
+ expect(content).to eq "**hoge**"
115
+ end
116
+
117
+ it "b" do
118
+ content = Wpconv::Filter::Markdown.apply("<b>hoge</b>")
119
+ expect(content).to eq "**hoge**"
120
+ end
121
+ end
122
+
123
+ describe "link" do
124
+ it "a" do
125
+ content = Wpconv::Filter::Markdown.apply("<a href='http://www.example.com/hoge/' target='_blank'>hoge</a>")
126
+ expect(content).to eq "[hoge](http://www\\.example\\.com/hoge/)"
127
+ end
128
+
129
+ it "LF in anchor text" do
130
+ content = Wpconv::Filter::Markdown.apply("<a href='http://www.example.com/hoge/' target='_blank'>ho\nge</a>")
131
+ expect(content).to eq "[ho\nge](http://www\\.example\\.com/hoge/)"
132
+ end
133
+ end
134
+ end
135
+
136
+ describe "escaping literal" do
137
+ # %w(\\ ` * _ { } [ ] \( \) # + - . !)
138
+ describe "for escaped character" do
139
+ it '*' do
140
+ content = Wpconv::Filter::Markdown.apply("h*ge")
141
+ expect(content).to eq 'h\*ge'
142
+ end
143
+
144
+ it '_' do
145
+ content = Wpconv::Filter::Markdown.apply("_hoge_")
146
+ expect(content).to eq '\_hoge\_'
147
+ end
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,5 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe Wpconv do
5
+ end
@@ -0,0 +1,9 @@
1
+ ---
2
+ title: <%= @item[:title] %>
3
+ date: <%= @item[:post_date] %>
4
+ layout: <%= @item[:post_type] %>
5
+ categories: [<%= @item[:categories].join(',') %>]
6
+ tags: [<%= @item[:tags].join(',') %>]
7
+ ---
8
+
9
+ <%= @item[:content] %>
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'wpconv/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "wpconv"
8
+ spec.version = Wpconv::VERSION
9
+ spec.authors = ["akahige"]
10
+ spec.email = ["akahigeg@gmail.com"]
11
+ spec.summary = %q{Converting Wordpress export XML to other format.}
12
+ spec.description = %q{Converting Wordpress export XML to other format.}
13
+ spec.homepage = "https://github.com/akahigeg/wpconv"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
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_development_dependency "bundler", "~> 1.6"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "rspec"
24
+ spec.add_dependency "thor"
25
+ spec.add_dependency "nokogiri"
26
+ spec.add_dependency "activesupport"
27
+ end
metadata ADDED
@@ -0,0 +1,154 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wpconv
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - akahige
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-08-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: thor
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: nokogiri
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: activesupport
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Converting Wordpress export XML to other format.
98
+ email:
99
+ - akahigeg@gmail.com
100
+ executables:
101
+ - wpconv
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - .gitignore
106
+ - Gemfile
107
+ - LICENSE.txt
108
+ - README.md
109
+ - Rakefile
110
+ - bin/wpconv
111
+ - lib/wpconv.rb
112
+ - lib/wpconv/cli.rb
113
+ - lib/wpconv/converter.rb
114
+ - lib/wpconv/filter/markdown.rb
115
+ - lib/wpconv/filter/none.rb
116
+ - lib/wpconv/version.rb
117
+ - lib/wpconv/wp_xml/channel.rb
118
+ - lib/wpconv/wp_xml/item.rb
119
+ - spec/spec_helper.rb
120
+ - spec/wpconv/converter_spec.rb
121
+ - spec/wpconv/filter/markdown_spec.rb
122
+ - spec/wpconv_spec.rb
123
+ - template/markdown.erb
124
+ - wpconv.gemspec
125
+ homepage: https://github.com/akahigeg/wpconv
126
+ licenses:
127
+ - MIT
128
+ metadata: {}
129
+ post_install_message:
130
+ rdoc_options: []
131
+ require_paths:
132
+ - lib
133
+ required_ruby_version: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - '>='
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ required_rubygems_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - '>='
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ requirements: []
144
+ rubyforge_project:
145
+ rubygems_version: 2.0.3
146
+ signing_key:
147
+ specification_version: 4
148
+ summary: Converting Wordpress export XML to other format.
149
+ test_files:
150
+ - spec/spec_helper.rb
151
+ - spec/wpconv/converter_spec.rb
152
+ - spec/wpconv/filter/markdown_spec.rb
153
+ - spec/wpconv_spec.rb
154
+ has_rdoc: