Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
source 'https://rubygems.org'

gemspec

gem 'pry'; require 'pry'
gem 'clipboard'; require 'clipboard'
46 changes: 46 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
PATH
remote: .
specs:
html2confluence (1.3.23)
nokogiri

GEM
remote: https://rubygems.org/
specs:
clipboard (1.1.1)
coderay (1.1.1)
diff-lcs (1.3)
method_source (0.8.2)
mini_portile2 (2.2.0)
nokogiri (1.8.0)
mini_portile2 (~> 2.2.0)
pry (0.10.4)
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
rspec (3.6.0)
rspec-core (~> 3.6.0)
rspec-expectations (~> 3.6.0)
rspec-mocks (~> 3.6.0)
rspec-core (3.6.0)
rspec-support (~> 3.6.0)
rspec-expectations (3.6.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.6.0)
rspec-mocks (3.6.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.6.0)
rspec-support (3.6.0)
slop (3.6.0)

PLATFORMS
ruby

DEPENDENCIES
clipboard
html2confluence!
pry
rspec

BUNDLED WITH
1.13.7
23 changes: 23 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
require 'bundler/gem_tasks'
require 'rake/testtask'

Rake::TestTask.new do |t|
t.libs << 'test'
t.test_files = Dir['test/**/*_test.rb']
end
task default: :test

desc "Open a pry console preloaded with this library"
task console: 'console:pry'

namespace :console do

task :pry do
sh "bundle exec pry -I lib -r html2confluence.rb"
end

task :irb do
sh "bundle exec irb -I lib -r html2confluence.rb"
end

end
5 changes: 3 additions & 2 deletions html2confluence.gemspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Gem::Specification.new do |s|
s.platform = Gem::Platform::RUBY
s.name = 'html2confluence'
s.version = "1.3.22"
s.version = "1.3.23"
s.summary = 'Converter from HTML to Confluence Wiki Markup'
s.description = 'Provides an SGML parser to convert HTML into the Wiki Markup format'

Expand All @@ -13,6 +13,7 @@ Gem::Specification.new do |s|

s.require_path = 'lib'
s.files = Dir.glob("{lib,spec}/**/*") + %w(example.rb README.mdown)

s.add_dependency "nokogiri"
s.add_development_dependency "rspec"
end
69 changes: 49 additions & 20 deletions lib/html2confluence.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
require 'rexml/document'

require 'walker'

require 'nokogiri' # For validating html from our editor

# A class to convert HTML to confluence markup. Based on the python parser
Expand Down Expand Up @@ -74,7 +76,6 @@ def make_quicktag_start_pair(tag, wrapchar, attributes)

def make_quicktag_end_pair(wrapchar)
content = stop_capture

# Don't make quicktags with empty content.
if content.join("").strip.empty?
write(content)
Expand All @@ -85,15 +86,25 @@ def make_quicktag_end_pair(wrapchar)
unless in_nested_quicktag?
#write([" "])
end
write(["#{wrapchar}"])
write_quicktag_wrapchar(wrapchar)
end
write(content.collect(&:strip))
write([wrapchar]) unless @skip_quicktag
write(content)
write_quicktag_wrapchar(wrapchar) unless @skip_quicktag
unless in_nested_quicktag?
#write([" "])
end
end

def write_quicktag_wrapchar(wrapchar)
write([
if @last_write[-1] =~ /\s/
"#{wrapchar}"
else
"{#{wrapchar}}"
end
])
end

def in_nested_quicktag?
@quicktags ||= QUICKTAGS.keys
@stack.size > 1 && @quicktags.include?(@stack[@stack.size-1]) && @quicktags.include?(@stack[@stack.size-2])
Expand Down Expand Up @@ -147,25 +158,25 @@ def handle_data(data)
PAIRS = { 'bq' => 'bq', 'p' => 'p' }
QUICKTAGS = { 'b' => '*', 'strong' => '*', 'del' => '-', 'strike' => '-',
'i' => '_', 'ins' => '+', 'u' => '+', 'em' => '_', 'cite' => '??',
'sup' => '^', 'sub' => '~', 'code' => '@'}
'sup' => '^', 'sub' => '~'}

PAIRS.each do |key, value|
define_method "start_#{key}" do |attributes|
make_block_start_pair(value, attributes)
PAIRS.each do |node, markup|
define_method "start_#{node}" do |attributes|
make_block_start_pair(markup, attributes)
end

define_method "end_#{key}" do
define_method "end_#{node}" do
make_block_end_pair
end
end

QUICKTAGS.each do |key, value|
define_method "start_#{key}" do |attributes|
make_quicktag_start_pair(key, value, attributes)
QUICKTAGS.each do |node, wrapchar|
define_method "start_#{node}" do |attributes|
make_quicktag_start_pair(node, wrapchar, attributes)
end

define_method "end_#{key}" do
make_quicktag_end_pair(value)
define_method "end_#{node}" do
make_quicktag_end_pair(wrapchar)
end
end

Expand Down Expand Up @@ -363,6 +374,17 @@ def end_blockquote
write(s)
end
end

def start_code(attrs)
@preserveWhitespace = true
write("{code}")
end

def end_code
stop_capture_and_write
write("{code}")
@preserveWhitespace = false
end

def start_pre(attrs)
@preserveWhitespace = true
Expand Down Expand Up @@ -392,7 +414,7 @@ def preprocess(data)
data.gsub!(/&(mdash|#8212);/,'---')
data.gsub!(/&(ndash|#8211);/,'--')

# remove empty blockquotes and list items (other empty elements are easy enough to deal with)
# remove empty blockquotes (other empty elements are easy enough to deal with)
data.gsub!(/<blockquote>\s*(<br[^>]*>)?\s*<\/blockquote>/x,' ')

# Fix unclosed <br>
Expand Down Expand Up @@ -443,16 +465,15 @@ def preprocess(data)

# Return the textile after processing
def to_wiki_markup
fix_textile_whitespace!(result.join).gsub(/\n(\*|#)+\s*\n(\*|#)+/) do |match|
"\n#{match.split("\n").last.squeeze(' ')}"
end
fix_textile_whitespace!(result.join)
end

def fix_textile_whitespace!(output)
# fixes multiple blank lines, blockquote indicator followed by blank lines, and trailing whitespace after quicktags
# modifies input string and also returns it
# fixes multiple blank lines
output.gsub!(/(\n\s*){2,}/,"\n\n")
# fixes blockquote indicator followed by blank lines
output.gsub!(/bq. \n+(\w)/,'bq. \1')
# fixes trailing whitespace after quicktags
QUICKTAGS.values.uniq.each do |t|
output.gsub!(/ #{Regexp.escape(t)}[ \t]+#{Regexp.escape(t)} /,' ') # removes empty quicktags
#output.gsub!(/(\[?#{Regexp.escape(t)})(\w+)([^#{Regexp.escape(t)}]+)(\s+)(#{Regexp.escape(t)}\]?)/,'\1\2\3\5\4') # fixes trailing whitespace before closing quicktags
Expand All @@ -461,6 +482,14 @@ def fix_textile_whitespace!(output)
#output.gsub!(/^[ \t]/,'') # leading whitespace
#output.gsub!(/[ \t]$/,'') # trailing whitespace
output.strip!
# fixes extra bullets generated when nesting list items
output.gsub!(/\n([\*|#]+)\s*\n([\*|#]+)/) do |match|
if $1 == $2
match
else
"\n#{match.split("\n").last}"
end.squeeze(' ')
end
return output
end

Expand Down
Loading