legal_markdown 0.4.2 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/Rakefile +50 -0
  2. data/lib/legal_markdown.rb +4 -3
  3. data/lib/legal_markdown/legal_to_markdown.rb +7 -6
  4. data/lib/legal_markdown/legal_to_markdown/mixins.rb +48 -40
  5. data/lib/legal_markdown/make_yaml_frontmatter.rb +66 -69
  6. data/lib/legal_markdown/roman_numerals.rb +1 -9
  7. data/lib/legal_markdown/version.rb +1 -1
  8. data/libpeerconnection.log +0 -0
  9. data/test/test_legal_markdown_to_markdown.rb +19 -17
  10. data/test/tests/00.load_write_no_action.headers +5 -0
  11. data/test/tests/01.load_partial_no_action.headers +22 -0
  12. data/test/tests/02.load_partials_no_action.headers +24 -0
  13. data/test/tests/10.mixins_in_headers_and_text.headers +21 -0
  14. data/test/tests/12.opt_clauses_no_subs.headers +19 -0
  15. data/test/tests/13.opt_clauses_subs.headers +27 -0
  16. data/test/tests/14.opt_clauses_with_mixins.headers +24 -0
  17. data/test/tests/20.block_no_addons.headers +37 -0
  18. data/test/tests/21.block_no_indents.headers +37 -0
  19. data/test/tests/22.block_all_indents.headers +37 -0
  20. data/test/tests/23.block_part_indents.headers +37 -0
  21. data/test/tests/24.block_no_closing_ticks.headers +36 -0
  22. data/test/tests/25.block_no_resets.headers +37 -0
  23. data/test/tests/26.block_all_resets.headers +37 -0
  24. data/test/tests/27.block_part_resets.headers +44 -0
  25. data/test/tests/28.block_provs_multi_line_no_indent.headers +46 -0
  26. data/test/tests/29.block_provs_multi_line_indents.headers +46 -0
  27. data/test/tests/30.block_all_leader_types.headers +49 -0
  28. data/test/tests/31.block_complex_leader_types.headers +49 -0
  29. data/test/tests/32.block_new_leader_style.headers +49 -0
  30. data/test/tests/33.block_with_pre_simple.headers +37 -0
  31. data/test/tests/34.block_with_pre_complex.headers +37 -0
  32. data/test/tests/35.block_with_preval.headers +37 -0
  33. data/test/tests/36.block_with_crossrefs.headers +37 -0
  34. data/test/tests/37.block_with_diff_start_pt.headers +37 -0
  35. data/test/tests/40.block_with_mixins.headers +49 -0
  36. data/test/tests/41.block_with_opt_clauses.headers +52 -0
  37. data/test/tests/42.block_with_opt_clauses_and_mixins.headers +58 -0
  38. data/test/tests/45.all_features_speed_ratchet.headers +209 -0
  39. data/test/tests/45.all_features_speed_ratchet.json +1 -0
  40. data/test/tests/45.all_features_speed_ratchet.lmd +207 -0
  41. data/test/tests/45.all_features_speed_ratchet.md +164 -0
  42. metadata +69 -4
data/Rakefile CHANGED
@@ -7,4 +7,54 @@ Rake::TestTask.new do |t|
7
7
  t.verbose = true
8
8
  end
9
9
 
10
+ desc "Push the Gem & Update Sublime Package"
11
+ task :publish do
12
+ system "git push github master"
13
+ system "git push wsl master"
14
+ Dir.chdir(File.dirname(__FILE__))
15
+ pkg = ENV['HOME'] + "/.config/sublime-text-2/Packages/Legal Document Creator"
16
+ FileUtils.cp_r( File.dirname(__FILE__) + "/lib" , pkg )
17
+ Dir.chdir(pkg)
18
+ f = "lib/legal_markdown.rb"
19
+ c = File::read(f) + "\n\nLegalMarkdown::parse(ARGV)"
20
+ File.open(f, "w") { |f| f.write( c ); f.close }
21
+ message = "Package updated at #{Time.now.utc} to reflect changes in Gem."
22
+ system "git add -A"
23
+ system "git commit -m #{message.shellescape}"
24
+ system "git push github master"
25
+ system "git push wsl master"
26
+ Dir.chdir(File.dirname(__FILE__))
27
+ end
28
+
29
+ # call with rake site:publish
30
+ desc "Publish New Version of Gem"
31
+ task :pushit do
32
+ fail "Does not look like the Version file is updated!" unless `git status -s`.split("\n").include?(" M lib/legal_markdown/version.rb")
33
+ require Dir.pwd + "/lib/legal_markdown/version.rb"
34
+ tag = LegalMarkdown::VERSION
35
+ system "git checkout master"
36
+ system "git add -A"
37
+ system "git commit -m 'Version Bump of Gem to version #{tag}'"
38
+ system "git tag -a v" + tag
39
+ system "git push github master --tags"
40
+ system "git push wsl master --tags"
41
+ system "rake install"
42
+ system "gem push pkg/legal_markdown-#{tag}.gem"
43
+ Dir.chdir(File.dirname(__FILE__))
44
+ pkg = ENV['HOME'] + "/.config/sublime-text-2/Packages/Legal Document Creator"
45
+ FileUtils.cp_r( File.dirname(__FILE__) + "/lib" , pkg )
46
+ Dir.chdir(pkg)
47
+ f = "lib/legal_markdown.rb"
48
+ c = File::read(f) + "\n\nLegalMarkdown::parse(ARGV)"
49
+ File.open(f, "w") { |f| f.write( c ); f.close }
50
+ message = "Package updated at reflect changes in Gem to version #{tag}."
51
+ system "git add -A"
52
+ system "git commit -m #{message.shellescape}"
53
+ system "git push github master"
54
+ system "git push wsl master"
55
+ Dir.chdir(File.dirname(__FILE__))
56
+ system "google-chrome https://github.com/compleatang/legal-markdown/releases"
57
+ system "gl"
58
+ end
59
+
10
60
  task :default => [:test]
@@ -1,7 +1,8 @@
1
1
  #! ruby
2
- require File.dirname(__FILE__) + '/legal_markdown/version.rb'
3
- require File.dirname(__FILE__) + '/legal_markdown/make_yaml_frontmatter.rb'
4
- require File.dirname(__FILE__) + '/legal_markdown/legal_to_markdown.rb'
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'legal_markdown/version.rb'
4
+ require 'legal_markdown/make_yaml_frontmatter.rb'
5
+ require 'legal_markdown/legal_to_markdown.rb'
5
6
 
6
7
  module LegalMarkdown
7
8
 
@@ -1,9 +1,10 @@
1
- require File.dirname(__FILE__) + '/legal_to_markdown/load_source.rb'
2
- require File.dirname(__FILE__) + '/legal_to_markdown/mixins.rb'
3
- require File.dirname(__FILE__) + '/legal_to_markdown/leaders.rb'
4
- require File.dirname(__FILE__) + '/legal_to_markdown/json_builder.rb'
5
- require File.dirname(__FILE__) + '/legal_to_markdown/writer.rb'
6
- require File.dirname(__FILE__) + '/roman_numerals'
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ require 'legal_to_markdown/load_source.rb'
3
+ require 'legal_to_markdown/mixins.rb'
4
+ require 'legal_to_markdown/leaders.rb'
5
+ require 'legal_to_markdown/json_builder.rb'
6
+ require 'legal_to_markdown/writer.rb'
7
+ require 'roman_numerals'
7
8
 
8
9
  module LegalToMarkdown
9
10
 
@@ -11,47 +11,14 @@ module LegalToMarkdown
11
11
  end
12
12
 
13
13
  def clauses_mixins
14
- clauses_to_delete = []
15
- clauses_to_mixin = []
14
+ @clauses_to_delete = []
15
+ @clauses_to_mixin = []
16
+ set_up_opt_clauses
17
+ backup_opt_clauses
16
18
 
17
- @headers.each do | mixin, replacer |
18
- replacer = replacer.to_s.downcase
19
- clauses_to_delete << mixin if replacer == "false"
20
- clauses_to_mixin << mixin if replacer == "true"
21
- end
22
-
23
- clauses_to_delete.each { |m| @headers.delete(m) }
24
- clauses_to_mixin.each { |m| @headers.delete(m) }
25
-
26
- until clauses_to_delete.size == 0
27
- clauses_to_delete.each do | mixin |
28
- pattern = /(\[\{\{#{mixin}\}\}\s*?)(.*?\n*?)(\])/m
29
- sub_pattern = /\[\{\{(\S+?)\}\}\s*?/
30
- @content[pattern]
31
- get_it_all = $& || ""
32
- sub_clause = $2 || ""
33
- if sub_clause[sub_pattern] && clauses_to_delete.include?($1)
34
- next
35
- elsif sub_clause[sub_pattern]
36
- pattern = /\[\{\{#{mixin}\}\}\s*?.*?\n*?\].*?\n*?\]/m
37
- @content[pattern]; get_it_all = $& || ""
38
- end
39
- @content = @content.gsub( get_it_all, "" )
40
- clauses_to_delete.delete( mixin ) unless @content[pattern]
41
- end
42
- end
43
-
44
- until clauses_to_mixin.size == 0
45
- clauses_to_mixin.each do | mixin |
46
- pattern = /(\[\{\{#{mixin}\}\}\s*?)(.*?\n*?)(\])/m
47
- sub_pattern = /\[\{\{(\S+?)\}\}\s*?/
48
- @content[pattern]
49
- get_it_all = $& || ""
50
- sub_clause = $2 || ""
51
- next if sub_clause[sub_pattern] && clauses_to_mixin.include?($1)
52
- @content = @content.gsub( get_it_all, sub_clause.lstrip )
53
- clauses_to_mixin.delete( mixin ) unless @content[pattern]
54
- end
19
+ until @clauses_added.size == 0 && @clauses_deleted.size == 0
20
+ clauses_churn_add
21
+ clauses_churn_delete
55
22
  end
56
23
  end
57
24
 
@@ -71,5 +38,46 @@ module LegalToMarkdown
71
38
  @content.squeeze!(" ")
72
39
  @headers = nil if @headers.empty?
73
40
  end
41
+
42
+ def set_up_opt_clauses
43
+ @headers.each do | mixin, replacer |
44
+ replacer = replacer.to_s.downcase
45
+ @clauses_to_delete << mixin if replacer == "false"
46
+ @clauses_to_mixin << mixin if replacer == "true"
47
+ end
48
+ end
49
+
50
+ def backup_opt_clauses
51
+ @clauses_to_delete.each { |m| @headers.delete(m) }
52
+ @clauses_to_mixin.each { |m| @headers.delete(m) }
53
+ @clauses_deleted = @clauses_to_delete.dup
54
+ @clauses_added = @clauses_to_mixin.dup
55
+ end
56
+
57
+ def clauses_churn_add
58
+ @clauses_added.each do | mixin |
59
+ pattern = /(\[\{\{#{mixin}\}\}\s*?)(.*?\n*?)(\])/m
60
+ sub_pattern = /\[\{\{(\S+?)\}\}\s*?/
61
+ @content[pattern]
62
+ get_it_all = $& || ""
63
+ sub_clause = $2 || ""
64
+ next if sub_clause[sub_pattern] && ( @clauses_to_mixin.include?($1) || @clauses_to_delete.include?($1) )
65
+ @content = @content.gsub( get_it_all, sub_clause.lstrip )
66
+ @clauses_added.delete( mixin ) unless @content[pattern]
67
+ end
68
+ end
69
+
70
+ def clauses_churn_delete
71
+ @clauses_deleted.each do | mixin |
72
+ pattern = /(\[\{\{#{mixin}\}\}\s*?)(.*?\n*?)(\])/m
73
+ sub_pattern = /\[\{\{(\S+?)\}\}\s*?/
74
+ @content[pattern]
75
+ get_it_all = $& || ""
76
+ sub_clause = $2 || ""
77
+ next if sub_clause[sub_pattern] && ( @clauses_to_mixin.include?($1) || @clauses_to_delete.include?($1) )
78
+ @content = @content.gsub( get_it_all, "" )
79
+ @clauses_deleted.delete( mixin ) unless @content[pattern]
80
+ end
81
+ end
74
82
  end
75
83
  end
@@ -3,17 +3,16 @@ require 'yaml'
3
3
 
4
4
  class MakeYamlFrontMatter
5
5
 
6
- def initialize(*args)
7
- data = load(*args)
8
- parsed_file = find_yaml_if_yaml(data)
9
- new_yaml_as_array = scan_and_filter_yaml(parsed_file[0], parsed_file[1])
10
- new_yaml = build_new_yaml_frontmatter(new_yaml_as_array)
11
- write_it( new_yaml + parsed_file[1] )
6
+ def initialize(args)
7
+ find_yaml_if_yaml(load(args))
8
+ scan_and_filter_yaml
9
+ build_new_yaml_frontmatter unless @yaml_data_as_array == [{},{},{},{}]
10
+ write_it
12
11
  end
13
12
 
14
- def load(*args)
13
+ def load(args)
15
14
  begin
16
- @file = ARGV[-1]
15
+ @file = args[-1]
17
16
  if @file != "-"
18
17
  source_file = File::read(@file) if File::exists?(@file) && File::readable?(@file)
19
18
  else
@@ -33,83 +32,81 @@ class MakeYamlFrontMatter
33
32
  end
34
33
 
35
34
  def find_yaml_if_yaml( source )
36
- begin
37
- yaml_pattern = /\A(---\s*\n.*?\n?)^(---\s*$\n?)/m
38
- parts = source.partition( yaml_pattern )
39
- if parts[1] != ""
40
- headers = YAML.load(parts[1])
41
- content = parts[2]
42
- else
43
- headers = {}
44
- content = source
45
- end
46
- rescue => e
47
- puts "Sorry, something went wrong when I was loading the YAML front matter: #{e.message}."
35
+ yaml_pattern = /\A(---\s*\n.*?\n?)^(---\s*$\n?)/m
36
+ parts = source.partition( yaml_pattern )
37
+ if parts[1] != ""
38
+ @headers = YAML.load(parts[1])
39
+ @content = parts[2]
40
+ else
41
+ @headers = {}
42
+ @content = source
48
43
  end
49
- return [headers, content]
50
44
  end
51
45
 
52
- def scan_doc(content, pattern)
53
- headers = content.scan(pattern).uniq.sort.flatten
54
- if pattern == @structured_headers_pattern
55
- headers = convert_ll_to_level_two(headers)
46
+ def scan_and_filter_yaml
47
+ mixin_pattern = /[^\[]{{(\S+)}}/
48
+ opt_clauses_pattern = /\[{{(\S+)}}/
49
+ @structured_headers_pattern = /(^l+.|^l\d+.)/
50
+ @yaml_data_as_array = []
51
+ @yaml_data_as_array << ( filter_yaml(scan_doc(mixin_pattern)) || {} )
52
+ @yaml_data_as_array << ( filter_yaml(scan_doc(opt_clauses_pattern)) || {} )
53
+ @yaml_data_as_array << ( filter_yaml(scan_doc(@structured_headers_pattern)) || {} )
54
+ @yaml_data_as_array << ( @yaml_data_as_array.last.empty? ? {} : filter_yaml(%w{no-indent no-reset level-style}) )
55
+ end
56
+
57
+ def build_new_yaml_frontmatter
58
+ @content = "\n---\n\n" + @content
59
+ replacers = {0=>"Mixins", 1=>"Optional Clauses", 2=>"Structured Headers", 3=>"Properties"}
60
+ stringy = @yaml_data_as_array.inject("") do |string, section|
61
+ unless section.empty?
62
+ string << "\n\# " + replacers[@yaml_data_as_array.index(section)] + "\n"
63
+ string << sink_it(section)
64
+ end
65
+ string
56
66
  end
57
- return headers
67
+ @content = stringy + @content
68
+ @content = "---\n" + @content
58
69
  end
59
70
 
60
- def convert_ll_to_level_two(levels)
61
- # receives an array in form ["l.", "ll.", "lll."] returns array in form ["level-1", "level-2"]
62
- levels.inject([]){|arr, level| level[/(l+)./]; arr << "level-" + $1.length.to_s}
71
+ def write_it
72
+ @content.scan(/(\[PARTIALSTART\].*?\[PARTIALENDS\]\[(.*?)\])/m).each do |set|
73
+ replacer = set[1]
74
+ to_replace = set[0]
75
+ @content.gsub!(to_replace, replacer)
76
+ end
77
+ if @file != "-"
78
+ File.open(@file, "w") {|f| f.write( @content ); f.close }
79
+ else
80
+ STDOUT.write @content
81
+ end
63
82
  end
64
83
 
65
- def filter_yaml(yaml_data, stuff)
66
- # yaml_data will be a hash, stuff is an array, returns a filtered hash
67
- stuff_in_yaml = stuff.inject({}) do |hash, elem|
68
- yaml_data.has_key?(elem) ? hash.merge({elem => yaml_data[elem]}) : hash.merge({elem => ""})
84
+ def scan_doc(pattern)
85
+ found = @content.scan(pattern).uniq.sort.flatten
86
+ if pattern == @structured_headers_pattern
87
+ found = convert_ll_to_level_two found
69
88
  end
89
+ found
70
90
  end
71
91
 
72
- def scan_and_filter_yaml(yaml_data, content)
73
- mixin_pattern = /[^\[]{{(\S+)}}/
74
- opt_clauses_pattern = /\[{{(\S+)}}/
75
- @structured_headers_pattern = /(^l+.)/
76
- mixins = filter_yaml(yaml_data, scan_doc(content, mixin_pattern))
77
- opt_clauses = filter_yaml(yaml_data, scan_doc(content, opt_clauses_pattern))
78
- levels = filter_yaml(yaml_data, scan_doc(content, @structured_headers_pattern))
79
- extras = filter_yaml(yaml_data, %w{no-indent no-reset level-style})
80
- return [mixins, opt_clauses, levels, extras]
92
+ def convert_ll_to_level_two(levels)
93
+ # receives an array in form ["l.", "ll.", "lll."] returns array in form ["level-1", "level-2"]
94
+ levels.inject([]){|arr, level| level[/((l+)\.)|(l(\d+)\.*)/]; $2 ? arr << "level-" + $2.length.to_s : arr << "level-" + $&.delete("l")}
81
95
  end
82
96
 
83
- def build_new_yaml_frontmatter(yaml_data_as_array)
84
- front = "---\n\n"
85
- if yaml_data_as_array[0]
86
- front << "\# Mixins\n"
87
- yaml_data_as_array[0].each{ |head, val| front << head + ": " + val.to_s + "\n" }
88
- end
89
- if yaml_data_as_array[1]
90
- front << "\n\# Optional Clauses\n"
91
- yaml_data_as_array[1].each{ |head, val| front << head + ": " + val.to_s + "\n" }
92
- end
93
- if yaml_data_as_array[2]
94
- front << "\n\# Structured Headers\n"
95
- yaml_data_as_array[2].each{ |head, val| front << head + ": \"" + val.to_s + "\"\n" }
96
- end
97
- if yaml_data_as_array[3]
98
- yaml_data_as_array[3].each{ |head, val| front << head + ": " + val.to_s + "\n" }
97
+ def filter_yaml(stuff)
98
+ # @headers will be a hash, stuff is an array, returns a filtered hash
99
+ if stuff
100
+ stuff_in_yaml = stuff.inject({}) do |hash, elem|
101
+ @headers.has_key?(elem) ? hash.merge({elem => @headers[elem]}) : hash.merge({elem => ""})
102
+ end
99
103
  end
100
- front << "\n---\n\n"
101
104
  end
102
105
 
103
- def write_it( final_content )
104
- final_content.scan(/(\[PARTIALSTART\].*?\[PARTIALENDS\]\[(.*?)\])/m).each do |set|
105
- replacer = set[1]
106
- to_replace = set[0]
107
- final_content.gsub!(to_replace, replacer)
108
- end
109
- if @file != "-"
110
- File.open(@file, "w") {|f| f.write( final_content ) }
111
- else
112
- STDOUT.write final_content
106
+ def sink_it(section)
107
+ section.inject("") do |string, head|
108
+ string << head[0] + ": \"" + ( head[1].to_s.gsub("\"", "\\\"") || "" ) + "\"\n"
109
+ string
113
110
  end
114
111
  end
115
112
  end
@@ -52,15 +52,7 @@ module RomanNumerals
52
52
  end
53
53
 
54
54
  def self.to_roman_lower(value)
55
- value = value.to_i
56
- result = ''
57
- @base_digits.keys.reverse.each do |decimal|
58
- while value >= decimal
59
- value -= decimal
60
- result += @base_digits[decimal]
61
- end
62
- end
63
- result.downcase
55
+ self.to_roman_upper(value).downcase
64
56
  end
65
57
 
66
58
  def self.to_decimal_string(value)
@@ -1,3 +1,3 @@
1
1
  module LegalMarkdown
2
- VERSION = "0.4.2"
2
+ VERSION = "0.4.3"
3
3
  end
File without changes
@@ -1,6 +1,6 @@
1
1
  #! ruby
2
2
  require 'test/unit'
3
- require 'tempfile'
3
+ require 'securerandom'
4
4
  require 'json'
5
5
  require 'legal_markdown'
6
6
 
@@ -18,22 +18,12 @@ class TestLegalMarkdownToMarkdown < Test::Unit::TestCase
18
18
  end
19
19
 
20
20
  def get_file ( filename )
21
- begin
22
- contents = File::read( filename ) if File::exists?(filename) && File::readable?(filename)
23
- rescue => e
24
- raise "Could not find file #{filename}: #{e.message}."
25
- contents = ""
26
- end
27
- if contents && contents != ""
28
- return contents.rstrip
29
- else
30
- return ""
31
- end
21
+ contents = IO.read(filename)
22
+ contents.rstrip
32
23
  end
33
24
 
34
25
  def create_temp
35
- temp_file = Tempfile.new('lmd_tests')
36
- return temp_file.path
26
+ temp_file = "/tmp/lmdtests-" + SecureRandom.hex
37
27
  end
38
28
 
39
29
  def destroy_temp ( temp_file )
@@ -45,7 +35,7 @@ class TestLegalMarkdownToMarkdown < Test::Unit::TestCase
45
35
  end
46
36
 
47
37
  def test_markdown_files
48
- puts "\n\nTesting lmd to markdown files.\n\n"
38
+ puts "Testing lmd to markdown files.\n\n"
49
39
  @lmdfiles.each do | lmd_file |
50
40
  puts "Testing => #{lmd_file}"
51
41
  temp_file = create_temp
@@ -56,8 +46,8 @@ class TestLegalMarkdownToMarkdown < Test::Unit::TestCase
56
46
  end
57
47
  end
58
48
 
59
- def test_json_files
60
- puts "Testing lmd to json files.\n\n"
49
+ def test_the_json_files
50
+ puts "\n\nTesting lmd to json files.\n\n"
61
51
  @lmdfiles.each do | lmd_file |
62
52
  puts "Testing => #{lmd_file}"
63
53
  temp_file = create_temp
@@ -73,4 +63,16 @@ class TestLegalMarkdownToMarkdown < Test::Unit::TestCase
73
63
  destroy_temp temp_file
74
64
  end
75
65
  end
66
+
67
+ def test_yaml_headers
68
+ puts "\n\nTesting Make YAML Frontmatter.\n\n"
69
+ @lmdfiles.each do | lmd_file |
70
+ puts "Testing => #{lmd_file}"
71
+ temp_file = create_temp
72
+ benchmark_file = File.basename(lmd_file, ".lmd") + ".headers"
73
+ `cat #{lmd_file} | legal2md --headers - > #{temp_file}`
74
+ assert_equal(get_file(benchmark_file), get_file(temp_file), "This file threw an exception => #{lmd_file}")
75
+ destroy_temp temp_file
76
+ end
77
+ end
76
78
  end