legal_markdown 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ test.md
2
+ *.gem
3
+ *.rbc
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in legal_markdown.gemspec
4
+ gemspec
5
+
6
+ gem "rake"
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Watershed Legal Services, PLLC
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.
data/README.md ADDED
@@ -0,0 +1,189 @@
1
+ # Introduction
2
+
3
+ This gem will parse YAML Front Matter of Markdown Documents. Typically, this gem would be called with a md renderer, such as [Pandoc](http://johnmacfarlane.net/pandoc/), that would turn the md into a document such as a .pdf file or a .docx file. By combining this pre-processing with a markdown renderer, you can ensure that both the structured content and the structured styles necessary for your firm or organization are more strictly enforced. Plus you won't have to deal with Word any longer, and every lawyer should welcome that. Why? Because Word is awful.
4
+
5
+ Gitlaw is markdown agnostic at this point and needs to be called independently of any markdown renderer. It is easy enough to build it into your work flow by editing the way that your markdown renderer is called. For instance you can call this file just before pandoc builds it. I use Sublime Text 2 with the Pandown plugin to build my Pandoc files. So what I would do is [..TODO..].
6
+
7
+ ## What Does the Gem Allow For?
8
+
9
+ This gem was built specifically to empower the creation of structured legal documents using markdown, and a markdown renderer. This gem acts as a middle layer by providing the user with structured headers and mixins that will greatly empower the use of md to create and maintain structured legal documents.
10
+
11
+ ## How to Install This Gem?
12
+
13
+ It is very simple. But first you must have ruby installed on your system. (Google it) Once you have ruby installed then you simply go to your terminal and type: `$> gem install legal_markdown`.
14
+
15
+ ## How to Use This Gem?
16
+
17
+ After the gem has finished its installation on your system then you can simply type `$> legalmd [filename]` where the filename is the file (in whatever flavor of markdown you use). The gem will parse the file and output the same filename. If you prefer to output as a different filename (which will allow you to keep the YAML front-matter), then you simply type `$> legalmd [input-filename] [output-filename]`.
18
+
19
+ # YAML Front-Matter
20
+
21
+ [YAML](http://www.yaml.org/spec/1.2/spec.html) is about the easiest thing to create. At the top of your file (it MUST be at the top of the file) you simply put in three or more hyphens like so: `---` on a single line. Then on the next line you simply put in the `field` followed by a `:` (colon) followed by the `value`. For each line you put the `[field]: [value]` until you have filled everything in that you need. After you have put in all your YAML front-matter then you simply put in a single line with three more hyphens `---` to signal to the gem that it is the end of the fields. So this would look like this:
22
+
23
+ ```yaml
24
+ ---
25
+ title: My Perfect Contract
26
+ author: Watershed Legal Services
27
+ date: 2013-01-01
28
+ ---
29
+ ```
30
+
31
+ ## A Few Signals to the Parser
32
+
33
+ ### Leaving the YAML Front-Matter
34
+
35
+ The gem will normally strip out the YAML front-matter as most markdown renderers will not be sure what to do with such content. Indeed, pandoc will end up drawing a table with the data still there. However, because some could potentially want to use this gem in combination with something like [Jekyll](https://github.com/mojombo/jekyll/) or any other system that could use the YAML front-matter there is a special trigger that tells legal_markdown to leave the YAML front-matter in the file. Legal_markdown will still make the necessary changes to the text of the file but it will not strip out the YAML front-matter in the process of making those changes.
36
+
37
+ To leave the YAML front-matter there simply pass the `value` of `true` to the `field` called `leave_yaml_front_matter`; this is how it would look in the above example.
38
+
39
+ ```yaml
40
+ ---
41
+ title: My Perfect Contract
42
+ author: Watershed Legal Services
43
+ date: 2013-01-01
44
+ leave_yaml_front_matter: true
45
+ ---
46
+ ```
47
+
48
+ If you do not add the `true` value to the field then the default which is set to false will be triggered and the YAML Front-Matter will be stripped.
49
+
50
+ ### Some Pandoc-Specific Fields
51
+
52
+ There are a few fields that will be treated uniquely. The three fields in the example above (title: , author: , and date: ) will be replaced with the Pandoc fields as appropriate. Perhaps later we can (as a community) build out this functionality for other renderers but for now I've only built it to use Pandoc. If you don't use Pandoc then you can simply omit these fields and there will be no problem.
53
+
54
+ # Mixins
55
+
56
+ Mixins are straight-forward they are simple markers that can be used throughout the text to identify certain things (Court) or (Company) or (Client) to identify a few. This allows for the creation and utilization of templates that can be reused by simply updating the YAML front-matter.
57
+
58
+ Mixins are structured in the form of **double curly** brackets (this was taken from IFTTT). So, for a `{{court}}` mixin, the YAML front-matter would look like this:
59
+
60
+ ```yaml
61
+ {{court}}: Regional Court of Hargeisa
62
+ ```
63
+
64
+ Mixins can also be used to set up clauses in the alternative in your templates which can be turned on or off within a specific document simply by updating the YAML mixin to false. Example of a `{{provision12a}}{{provision12b}}` alternative structuring for a contract template. Within the template the YAML front-matter would be structured something like this:
65
+
66
+ ```yaml
67
+ {{provision12a}}: "For the purposes of this Agreement"
68
+ {{provision12b}}: "This Agreement shall"
69
+ ```
70
+
71
+ Then to chose one of the two provisions you would would simply change the line to "false" but without the quotes. Example:
72
+
73
+ ```yaml
74
+ {{provision12a}}: false
75
+ ```
76
+
77
+ # Structured Headers
78
+
79
+ When creating many legal documents, but especially laws and contracts, we find ourselves constantly repeating structured headers. This gets utterly maddening when working collaboratively with various word processors because each word processor has its own sytles and limitations for working with ordered lists and each user of even the same word processor has different defaults. This presents a mess for those that have to clean up these lists. We waste an inordinate amount of time with "Format Painter" and other hacks that do not really allow us to focus on the text.
80
+
81
+ In order to address this problem, I have built functionality into legal_markdown that gets around this. Here is how structured headers work in the gem. At the beginning of the line you simply type the level in which the provision resides by the number of lowercase "l" followed by a period and then a space. So a top level provision (perhaps a Chapter, or Article depending on your document) will begin with `l. The provision ...` A second level provision (a Section or whatnot) will begin with `ll. Both parties agree ...` A third level provision will begin with `lll. Yaddy Yadda ...` And so on. These will reside in the body of the text.
82
+
83
+ Then you can describe the functionality that you require in the YAML front-matter. In the YAML front-matter you will simply add the following fields: `level-1` and then the `: ` followed by what the format you would like it to be in. Currently there are a few possible options at this time (for those using pandoc at least):
84
+
85
+ 1. `level-1: 1.` will format that level of the list as 1. 2. 3. etc.; This is the default functionality;
86
+ 2. `level-1: (1)` will provide for the same numbering only within parenteticals rather than followed by a period;
87
+ 3. `level-1: A.` will format with capital letters followed by a period (e.g, A., B., C., etc.);
88
+ 4. `level-1: (A)` will format the same as the above only with the capital letters in a parentetical;
89
+ 5. `level-1: a.` will format with lowercase letters followed by a period;
90
+ 6. `level-1: (a)` will format with lowercase letters within a parentethical;
91
+ 7. `level-1: I.` will format with Roman numerals followed by a period;
92
+ 8. `level-1: (I)` will format with Roman numerals within a parententical.
93
+
94
+ Obviously you will replace `level-1` with `level-2`, etc. Although this functionality was built into the gem, it is generally not the best practice. A better practice is to let the gem make the replacements and reformat the markdown and then use your rendering system and its default reference documents to set the styles you need.
95
+
96
+ ## Example
97
+
98
+ If you use a system like Pandoc you can establish a system wherein the styles that you establish in the reference.docx or reference.odt or the latex style references can make up for the lack of granular fuctionality. When you build your reference.odt for example and you want to have a contract look like this:
99
+
100
+ Article 1. Provision for Article 1.
101
+
102
+ Section 1.1. Provision for Section 1.1.
103
+
104
+ 1.1.1 Provision for 1.1.1.
105
+
106
+ 1.1.2 Provision for 1.1.2.
107
+
108
+ Section 1.2. Provision for Section 1.2.
109
+
110
+ 1.2.1 Provision for 1.2.1.
111
+
112
+ 1.2.2 Provision for 1.2.2.
113
+
114
+ ...
115
+
116
+ You can easily to that by doing the following steps.
117
+
118
+ ### Step 1: Type the body
119
+
120
+ ```
121
+ l. Provision for Article 1.
122
+ ll. Provision for Section 1.1.
123
+ lll. Provision for 1.1.1.
124
+ lll. Provision for 1.1.2.
125
+ ll. Provision for Section 1.2.
126
+ lll. Provision for 1.2.1.
127
+ lll. Provision for 1.2.2.
128
+ ```
129
+
130
+ ### Step 2: (Optional) Fill out the YAML Front-Matter
131
+
132
+ ```yaml
133
+ ---
134
+ title: Wonderful Contract
135
+ author: Your Name
136
+ date: today
137
+ level-1: 1.
138
+ level-2: A.
139
+ level-3: a.
140
+ ---
141
+ ```
142
+
143
+ ### Step 3: Modify your reference.odt or reference.docx
144
+
145
+ In Libreoffice you would modify your template reference.odt as you need it. You would go to Format -> Bullets and Numbering -> Options.
146
+
147
+ 1. First you would select Level 1 (on the left). In the Before field you would add "Article " (without the quotes, but not the space). In the After field you would add a period. In the Numbering field you would select 1, 2, 3, .... And in the Show sublevels field you would choose 1
148
+ 2. Second you would select Level 2 (on the left). In the Before field you would add "Section " (without the quotes, but with the space). In the After field you would add a period. In the Numbering field you would select 1, 2, 3, .... And in the Show sublevels field you would choose 2.
149
+ 3. Third you would select Level 3 (on the left). In the Before field you would add nothing (to accomplish the above desired output). In the After field you would add a period. in the Show sublevels field you would choose 3.
150
+ 4. Lastly you would make sure that Consecutive Numbering (field at the bottom) was turned off.
151
+ 5. You can make sure that all the indenting is as desired in the Position Tab.
152
+
153
+ Then you would save the reference.odt as a new name perhaps contract-reference.odt in your Pandoc reference folder.
154
+
155
+ ### Step 4: Run Legal-Markdown and Pandoc
156
+
157
+ Make sure when you run Pandoc you use the new reference document that you created as the basis.
158
+
159
+ I do not use latex to create pdfs nor do I use Word, but the functionality will be similar with Word, and if you're using latex then you can figure out how to mirror this workflow.
160
+
161
+ ## A Few Gotchas
162
+
163
+ You cannot begin the block of structured headers with a second level header. The gem searches the markdown to find a line that begins with `l.` where there is a blank line above it. This is made to be fairly precise so as to ensure that the gem does not strip out some other functionality that you want to build.
164
+
165
+ When you are using structured headers of legal_markdown you should make the lists tight. Do not add blank lines in between the list levels or the gem will think you are creating a new list. If you are trying to create a new list then by all means go ahead as the blank lines will break the parsing.
166
+
167
+ Also, if you use the reference.odt or reference.docx to override the default formating of the list then you do not need to add any level-1 or level-2 fields to the YAML front-matter. The best way to do it is to simply use the defaults that pandoc or your renderer will use and then use the reference styles to build the functionality that you would like.
168
+
169
+ # TODO
170
+
171
+ [ ] - Definitions. For now these can be used as mixins but that functionality needs to improve.
172
+
173
+ [ ] - Parsing. At this point legal_markdown cannot take a markdown document and parse it to build structured headers. Legal_markdown only works with a renderer to *create* documents but not to *import* documents. I want to build this functionality out at a later date.
174
+
175
+ # Contributing
176
+
177
+ 1. Fork it
178
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
179
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
180
+ 4. Push to the branch (`git push origin my-new-feature`)
181
+ 5. Create new Pull Request
182
+
183
+ # License
184
+
185
+ MIT License - (c) 2012 - Watershed Legal Services, PLLC. All copyrights are owned by [Watershed Legal Services, PLLC](http://watershedlegal.com). See License file.
186
+
187
+ This software is provided as is and specifically disclaims any implied warranties of fitness for any purpose whatsoever. By using this software you agree to hold harmless Watershed Legal Services and its Members for any perceived harm that using this software may have caused you.
188
+
189
+ In other words, don't be a jerk.
data/Rakefile ADDED
@@ -0,0 +1,34 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ # begin
4
+ # require "mg"
5
+ # MG.new("legal_markdown.gemspec")
6
+ # rescue LoadError
7
+ # nil
8
+ # end
9
+
10
+ # desc "Build standalone script"
11
+ # task :build => [ :standalone ]
12
+
13
+ # desc "Build standalone script"
14
+ # task :standalone => :load_legal_markdown do
15
+ # require 'legal_markdown/standalone'
16
+ # LegalMarkdown::Standalone.save('legalmd')
17
+ # end
18
+
19
+ # Rake::TaskManager.class_eval do
20
+ # def remove_task(task_name)
21
+ # @tasks.delete(task_name.to_s)
22
+ # end
23
+ # end
24
+
25
+ # # Remove mg's install task
26
+ # Rake.application.remove_task(:install)
27
+
28
+ # desc "Install standalone script"
29
+ # task :install => :standalone do
30
+ # prefix = ENV['PREFIX'] || ENV['prefix'] || '/usr/local'
31
+
32
+ # FileUtils.mkdir_p "#{prefix}/bin"
33
+ # FileUtils.cp "legalmd", "#{prefix}/bin"
34
+ # end
data/bin/legalmd ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # == USAGE
4
+ # legalmd file.md
5
+
6
+ require 'legal_markdown'
7
+ LegalMarkdown.execute(ARGV)
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'legal_markdown/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "legal_markdown"
8
+ s.version = LegalMarkdown::VERSION
9
+ s.date = Time.now.strftime('%Y-%m-%d')
10
+ s.summary = "Gem for parsing legal documents written in markdown for processing with legal specific requirements."
11
+ s.homepage = "http://github.com/compleatang/legal-markdown"
12
+ s.email = "caseykuhlman@watershedlegal"
13
+ s.authors = [ "Casey Kuhlman" ]
14
+ s.has_rdoc = false
15
+
16
+ s.files = `git ls-files`.split($/)
17
+ s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
19
+ s.require_paths = ["lib"]
20
+
21
+ #s.add_dependency ""
22
+
23
+ s.description = <<desc
24
+ This gem will parse YAML Front Matter of Markdown Documents. Typically, this gem would be called with a md renderer, such as Pandoc, that would turn the md into a document such as a .pdf file or a .docx file. By combining this pre-processing with a markdown renderer, you can ensure that both the structured content and the structured styles necessary for your firm or organization are more strictly enforced. Plus you won't have to deal with Word any longer, and every lawyer should welcome that. Why? Because Word is awful.
25
+ desc
26
+ end
@@ -0,0 +1,3 @@
1
+ module LegalMarkdown
2
+ VERSION = "0.1.1"
3
+ end
@@ -0,0 +1,135 @@
1
+ #! ruby
2
+ require 'yaml'
3
+ require 'English'
4
+ require "legal_markdown/version"
5
+
6
+ module LegalMarkdown
7
+ extend self
8
+ def execute(*args)
9
+ # Get the Content & Yaml Data
10
+ data = load(*args)
11
+ parsed_content = parse_file(data[0])
12
+ # Run the Mixins
13
+ mixed_content = mixing_in(parsed_content[0], parsed_content[1])
14
+ #REMOVE THESE LATER
15
+ content = mixed_content[0]
16
+ yaml_data = mixed_content[1]
17
+ puts content
18
+ puts "What's left"
19
+ yaml_data.each{|k,v| puts "#{k}: #{v}"}
20
+ end
21
+
22
+ private
23
+ # ----------------------
24
+ # | Step 1 |
25
+ # ----------------------
26
+ # Parse Options & Load File
27
+ def load(*args)
28
+
29
+ # OPTIONS
30
+ # OPTS = {}
31
+ # op = OptionParser.new do |x|
32
+ # x.banner = 'cat <options> <file>'
33
+ # x.separator ''
34
+
35
+ # x.on("-A", "--show-all", "Equivalent to -vET")
36
+ # { OPTS[:showall] = true }
37
+
38
+ # x.on("-b", "--number-nonblank", "number nonempty output lines")
39
+ # { OPTS[:number_nonblank] = true }
40
+
41
+ # x.on("-x", "--start-from NUM", Integer, "Start numbering from NUM")
42
+ # { |n| OPTS[:start_num] = n }
43
+
44
+ # x.on("-h", "--help", "Show this message")
45
+ # { puts op; exit }
46
+ # end
47
+ # op.parse!(ARGV)
48
+
49
+ # # Example code for dealing with multiple filenames -- but don't think we want to do this.
50
+ # ARGV.each{ |fn| output_file(OPTS, fn) }
51
+
52
+ # Load Source File
53
+ source_file = File::read(ARGV[-1]) if File::exists?(ARGV[-1])
54
+ return[source_file, '']
55
+ end
56
+
57
+ # ----------------------
58
+ # | Step 2 |
59
+ # ----------------------
60
+ # Load YAML Front-matter
61
+
62
+ def parse_file(source)
63
+ begin
64
+ yaml_pattern = /\A(---\s*\n.*?\n?)^(---\s*$\n?)/m
65
+ if source =~ yaml_pattern
66
+ data = YAML.load($1)
67
+ content = $POSTMATCH
68
+ else
69
+ data = {}
70
+ content = source
71
+ end
72
+ rescue => e
73
+ puts "Error reading file #{File.join(ARGV[0])}: #{e.message}"
74
+ end
75
+ return[data, content]
76
+ end
77
+
78
+ # ----------------------
79
+ # | Step 3 |
80
+ # ----------------------
81
+ # Mixins
82
+
83
+ def mixing_in( mixins, content )
84
+ mixins.each do | mixin, replacer |
85
+ replacer = replacer.to_s
86
+ safe_words = [ "title", "author", "date" ]
87
+ if replacer != "false"
88
+ pattern = /{{#{mixin}}}/
89
+ if content =~ pattern
90
+ content = content.gsub( pattern, replacer )
91
+ # delete the mixin so that later parsing of special mixins & headers is easier and faster
92
+ mixins.delete( mixin ) unless safe_words.any?{ |s| s.casecmp(mixin) == 0 }
93
+ end
94
+ end
95
+ end
96
+ return[content, mixins]
97
+ end
98
+
99
+ # ----------------------
100
+ # | Step 4 |
101
+ # ----------------------
102
+ # Headers
103
+
104
+
105
+ # Step 4a: Find the block starting and finishing lines
106
+
107
+
108
+ # Step 4b: Set the alignment and the nesting structure
109
+
110
+
111
+ # Step 4c: Set the requested list styling per the YAML front-matter
112
+
113
+
114
+ # Step 4d: Pull out the ll. tags & strip the leading whitespace
115
+ # but keep the proper nesting alignment.
116
+
117
+
118
+ # ----------------------
119
+ # | Step 5 |
120
+ # ----------------------
121
+ # Special YAML fields
122
+
123
+
124
+ # Step 6: Strip the YAML front-matter
125
+
126
+
127
+ # Step 7: Write the file
128
+
129
+
130
+ # Step 7a: Where an output file was specified
131
+
132
+
133
+ # Step 7b: Where an output file was not specified
134
+
135
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: legal_markdown
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Casey Kuhlman
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-18 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: ! " This gem will parse YAML Front Matter of Markdown Documents. Typically,
15
+ this gem would be called with a md renderer, such as Pandoc, that would turn the
16
+ md into a document such as a .pdf file or a .docx file. By combining this pre-processing
17
+ with a markdown renderer, you can ensure that both the structured content and the
18
+ structured styles necessary for your firm or organization are more strictly enforced.
19
+ Plus you won't have to deal with Word any longer, and every lawyer should welcome
20
+ that. Why? Because Word is awful. \n"
21
+ email: caseykuhlman@watershedlegal
22
+ executables:
23
+ - legalmd
24
+ extensions: []
25
+ extra_rdoc_files: []
26
+ files:
27
+ - .gitignore
28
+ - Gemfile
29
+ - LICENSE
30
+ - README.md
31
+ - Rakefile
32
+ - bin/legalmd
33
+ - legal_markdown.gemspec
34
+ - lib/legal_markdown.rb
35
+ - lib/legal_markdown/version.rb
36
+ homepage: http://github.com/compleatang/legal-markdown
37
+ licenses: []
38
+ post_install_message:
39
+ rdoc_options: []
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ segments:
49
+ - 0
50
+ hash: 1250125497917414480
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ! '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ segments:
58
+ - 0
59
+ hash: 1250125497917414480
60
+ requirements: []
61
+ rubyforge_project:
62
+ rubygems_version: 1.8.25
63
+ signing_key:
64
+ specification_version: 3
65
+ summary: Gem for parsing legal documents written in markdown for processing with legal
66
+ specific requirements.
67
+ test_files: []