legal_markdown 0.4.3 → 0.4.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +4 -1
- data/Gemfile +1 -2
- data/README.md +99 -78
- data/Rakefile +10 -3
- data/lib/legal_markdown.rb +73 -9
- data/lib/legal_markdown/make_yaml_frontmatter.rb +7 -6
- data/lib/legal_markdown/version.rb +1 -1
- data/test/{test_legal_markdown_to_markdown.rb → legal_markdown_test.rb} +19 -15
- metadata +6 -7
- data/libpeerconnection.log +0 -0
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -4,33 +4,49 @@
|
|
4
4
|
|
5
5
|
# Introduction
|
6
6
|
|
7
|
-
This gem will parse YAML Front Matter of Markdown
|
7
|
+
This gem will parse YAML Front Matter of Markdown and other Text Based Documents. **It will work with more than only markdown**.
|
8
8
|
|
9
|
-
|
9
|
+
Typically, this gem would be called as a preprocessor to a primary renderer, such as [Pandoc](http://johnmacfarlane.net/pandoc/), that would turn the document outputed by `legal_markdown` into a document such as a .pdf file, an .html file for web display, or a .docx file.
|
10
10
|
|
11
|
-
|
11
|
+
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.
|
12
12
|
|
13
|
-
|
13
|
+
Legal Markdown is not actually markdown linked. It is agnostic in this regard. Indeed, it probably does not depend on markdown, or any of its flavors at all and *should* work with ASCII or other text based documents. It is easy enough to build the gem 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.
|
14
|
+
|
15
|
+
## Motivation
|
16
|
+
|
17
|
+
This gem was built specifically to empower the creation of structured legal documents using simple text based documents along with a primary renderer. This gem acts as a middle layer by providing the user with structured headers and mixins that will greatly empower the use of text based documents to create and maintain structured legal documents.
|
18
|
+
|
19
|
+
*Note*, in the coming versions, the gem will be able to output to specific legal versions of various structured documents which will not require a post-processor. See the milestones in the [Github Issues Tracker](https://github.com/compleatang/legal-markdown/issues) for more information.
|
14
20
|
|
15
21
|
## How to Install This Gem?
|
16
22
|
|
17
|
-
It is very simple. But first you must have ruby installed on your system.
|
23
|
+
It is very simple. But first you must have `ruby` installed on your system. Don't worry, it is not that difficult.
|
24
|
+
|
25
|
+
* If you are on OS X then it comes standard on your machine and you do not need to do anything.
|
26
|
+
* If you are on Windows then the easiest way to install ruby is install 1.9.3 or higher from [rubyinstaller](http://rubyinstaller.org/).
|
27
|
+
* If you are on Linux, then you don't need help. Once you have ruby installed then you simply go to your terminal and type: `$> gem install legal_markdown`.
|
18
28
|
|
19
|
-
If you are looking to try out the gem, and you use [Sublime Text](http://www.sublimetext.com/) as your text editor, then you can easily install my `legal_markdown` package by visiting the repo [here](https://github.com/compleatang/Legal-Markdown-Sublime).
|
29
|
+
If you are looking to try out the gem, and you use [Sublime Text](http://www.sublimetext.com/) as your text editor, then you can easily install my `legal_markdown` package by visiting the repo [here](https://github.com/compleatang/Legal-Markdown-Sublime).
|
30
|
+
|
31
|
+
If you install the package there is no need to install the gem, but you will still have to install ruby.
|
20
32
|
|
21
33
|
## How to Use This Gem?
|
22
34
|
|
23
|
-
After the gem has finished its installation on your system then you can simply type `$> legal2md [filename]` where the filename is the
|
35
|
+
After the gem has finished its installation on your system then you can simply type `$> legal2md [filename]` where the filename is the fileyou want the gem to parse. Legal Markdown will parse the file and output the same filename.
|
24
36
|
|
25
37
|
If you prefer to output as a different filename (which will allow you to keep the YAML front-matter), then you simply type `$> legal2md [input-filename] [output-filename]`.
|
26
38
|
|
27
39
|
If you have been working on a template or document and would like the gem to build the YAML Front-Matter (see below) automatically for you, then simply type `$> legal2md --headers [filename]`.
|
28
40
|
|
41
|
+
If you would like to output to `json` format (the only structured system currently supported, but more are coming), then you type `$> legal2md --to-json [input-filename] [output-filename]` into the command line. You do not have to put the `--to-json` switch if the output file ends in `*.json`.
|
42
|
+
|
43
|
+
All these commands are available from within ruby as well if you would prefer to call them programmatically. The headers command is called with `LegalMarkdown.parse(:headers, input_file, optional_output_file)`. The normal parsing is called with `LegalMarkdown.parse(:to_markdown, input_file, optional_output_file)`. And the json output is called with `LegalMarkdown.parse(:to_json, input_file, mandatory_output_file)`, again :to_json is optional if the output file ends with *.json.
|
44
|
+
|
29
45
|
# YAML Front-Matter
|
30
46
|
|
31
47
|
[YAML](http://www.yaml.org/spec/1.2/spec.html) is easy thing to create. At the top of your file (it MUST be at the top of the file) you simply put in three 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:
|
32
48
|
|
33
|
-
```
|
49
|
+
```yaml
|
34
50
|
---
|
35
51
|
party1_address: "Muj Axmed Jimcaale Road, Hargeisa, Republic of Somaliland"
|
36
52
|
party1_full: "Watershed Legal Services, Ltd."
|
@@ -45,39 +61,43 @@ party1_type: private company limited by shares
|
|
45
61
|
|
46
62
|
# Mixins
|
47
63
|
|
48
|
-
Mixins are straight-forward
|
64
|
+
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. The example above is the YAML Front Matter for mixins. This allows for the creation and utilization of templates that can be reused by simply updating the YAML front-matter and leaving the main text of the template largely untouched.
|
49
65
|
|
50
66
|
Mixins are structured in the form of **double curly** brackets. So, for a `{{court}}` mixin within the body of your document, the YAML front-matter would look like this:
|
51
67
|
|
52
|
-
```
|
68
|
+
```yaml
|
53
69
|
court: Regional Court of Hargeisa
|
54
70
|
```
|
55
71
|
|
56
|
-
If you do not want a mixin turned on for a particular document just add the mixin in the YAML Frontmatter and then leave it blank
|
72
|
+
If you do not want a mixin turned on for a particular document just add the mixin in the YAML Frontmatter and then leave it blank, the gem will take it out of the text along with any extraneous spaces.
|
57
73
|
|
58
74
|
## Optional Clauses Function
|
59
75
|
|
60
76
|
When building templates for contracts, you often build in optional clauses or you build clauses that are mutually exclusive to one another. This functionality is supported by legal_markdown. Here is how to build an optional clause.
|
61
77
|
|
62
|
-
In the body of your document you put the entire clause in square-brackets (as you likely normally would) and at the beginning of the square bracket you put a mixin
|
78
|
+
In the body of your document you put the entire clause in square-brackets (as you likely normally would) and at the beginning of the square bracket you put a mixin title for the optional clause.
|
79
|
+
|
80
|
+
In the YAML Front-Matter you simply add "true" or "false" to turn that entire clause on or off. **Note**, if you do not add the mixin to your header, legal_markdown is just going to leave it as is, which is very unlikely to be what you want to see in your output file.
|
63
81
|
|
64
|
-
You are able to nest
|
82
|
+
You are able to nest optional clauses inside of other optional clauses. However, if you do so, make sure that you include all of the sub-provisions of the master provision in the YAML matter, else the gem will think that you closed your square brackets too early (which it was probably the closure of a nested clause. If you use the automatic YAML population feature either from the command line (see above) or by using the Sublime package, it will simplify this process for you greatly.
|
83
|
+
|
84
|
+
Another thing to note, if you include nested provisions, you can turn off an inside provision and leave an outside provision on, but if you turn off an outside provision the entire portion will not be produced, even if you turned an inner portion on. Usually, as long as you keep this rule in mind you can draft around it, and it is generally the case that that will be the result that you will want any way.
|
65
85
|
|
66
86
|
So, this is how the body of the text would look.
|
67
87
|
|
68
|
-
```
|
88
|
+
```md
|
69
89
|
[{{my_optional_clause}}Both parties agree that upon material breach of this agreement by either party they will both commit suicide in homage to Kurt Cobain.]
|
70
90
|
```
|
71
91
|
|
72
92
|
Then the YAML Front Matter would look like this
|
73
93
|
|
74
|
-
```
|
94
|
+
```yaml
|
75
95
|
my_optional_clause: true
|
76
96
|
```
|
77
97
|
|
78
98
|
or
|
79
99
|
|
80
|
-
```
|
100
|
+
```yaml
|
81
101
|
my_optional_clause: false
|
82
102
|
```
|
83
103
|
|
@@ -85,17 +105,17 @@ I don't know why you would ever write such a clause, but that is why the functio
|
|
85
105
|
|
86
106
|
# Structured Headers
|
87
107
|
|
88
|
-
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 styles and limitations for working with ordered lists and each user of even the same word processor has different defaults.
|
108
|
+
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 styles and limitations for working with ordered lists and each user of even the same word processor has different defaults. We waste an inordinate amount of time with "Format Painter" and other hacks trying to clean these up and make them presentable; all the while we are not focus on the text -- which is what our clients want from us.
|
89
109
|
|
90
110
|
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.
|
91
111
|
|
92
|
-
Wherever you wish to start
|
112
|
+
Wherever you wish to start a block of structured headers just put in ````` Three backticks (~ without the shift on US keyboards) at the beginning of the line. Then start the block of structured headers on the next line. When you are done with the block just put the same three backticks at the beginning of the line and continue your document. If the structured headers run to the end of the document, you do not need to close the backticks if you do not want to.
|
93
113
|
|
94
114
|
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.
|
95
115
|
|
96
116
|
When the gem parses the document it will automatically add and reset each level in the tree that you set up based on the criteria you establish.
|
97
117
|
|
98
|
-
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
|
118
|
+
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 these are the options:
|
99
119
|
|
100
120
|
1. `level-1: 1.` will format that level of the list as 1. 2. 3. etc.; This is the default functionality;
|
101
121
|
2. `level-1: (1)` will provide for the same numbering only within parenteticals rather than followed by a period;
|
@@ -112,7 +132,7 @@ Obviously you will replace `level-1` with `level-2`, etc.
|
|
112
132
|
|
113
133
|
In addition to the reference portion of the structured header, you can add in whatever text you wish. For example, if you want the top level to be articles with a number and then a period, the next level down to be sections with a number in parentheses, and the next level down to be a letter in parentheses then this is what the YAML front matter would look like.
|
114
134
|
|
115
|
-
```
|
135
|
+
```yaml
|
116
136
|
---
|
117
137
|
level-1: Article 1.
|
118
138
|
level-2: Section (1)
|
@@ -120,15 +140,15 @@ level-3: (a)
|
|
120
140
|
---
|
121
141
|
```
|
122
142
|
|
123
|
-
|
143
|
+
Also, you can start on any number or letter you wish. So if you want the first Article to be Article 100. instead of Article 1. there is no problem with that. One thing to be careful of if you do not start with the default numbering/lettering is that you should likely turn off the reset function for that level (see below) or else when the gem is parsing the document it will reset the level based on the default numbering/lettering rather than the initial numbering/lettering you established. Also, be careful if you want to start with letters that also match with Roman Numerals (I, V, X, L, C, D, M) whether upper or lower case as the gem parses Roman's first and if you want a sequence similar to (a), (b) but you put in (c) as the starting point the gem will default to the lowercase version of the Roman Numeral C (100).
|
124
144
|
|
125
145
|
## No Reset Function
|
126
146
|
|
127
|
-
Sometimes in legal documents (particularly in laws) you want to build multiple structured header levels, but you do not want to reset all of the headers when going up the tree. For example, in some laws you will have Chapters, Parts, Sections, ... and you will want to track Chapters, Parts and Sections but when you go up to Parts you will not want to reset the Sections to one.
|
147
|
+
Sometimes in legal documents (particularly in laws) you want to build multiple structured header levels, but you do not want to reset all of the headers when you are going up the tree. For example, in some laws you will have Chapters, Parts, Sections, ... and you will want to track Chapters, Parts and Sections but when you go up to Parts you will not want to reset the Sections to one.
|
128
148
|
|
129
149
|
This functionality is built in with a `no-reset` function. You simply add a `no-reset` field to your YAML header and note the headers that you do not want to reset by their l., ll. notation. Separate those levels you do not want reset with commas. Example YAML line:
|
130
150
|
|
131
|
-
```
|
151
|
+
```yaml
|
132
152
|
no-reset: l., ll., lll.
|
133
153
|
```
|
134
154
|
|
@@ -138,35 +158,37 @@ This will not reset level-1, level-2, or level-3 when it is parsing the document
|
|
138
158
|
|
139
159
|
If you are outputting to .pdf, .odt, .doc(x) you may want to keep some of the header levels tight to the margins. This functionality is built into legal_markdown with a `no-indent` function. You simply add a `no-indent` field to your YAML header and not the headers you do not want to indent by their l., ll. notation. Separate those levels you do not want to reset with commas as with the `no-reset` function. Any levels *below* the last level in the `no-indent` function will be indented four spaces for each level.
|
140
160
|
|
141
|
-
##
|
161
|
+
## Titles and Text or Provisions
|
142
162
|
|
143
|
-
|
163
|
+
Sometimes you want to have a title on one line and then some text on the next line all referencing the same provision. This is simple, you type your header and the title after that as you normally would, and then you just start the 'text' portion (meaning not the title) of the provision on the next line. Legal Markdown will figure out that you are separating text from title and parse it accordingly.
|
144
164
|
|
145
|
-
|
165
|
+
## Examples
|
146
166
|
|
147
|
-
|
148
|
-
Article 1. Provision for Article 1.
|
167
|
+
The syntax should be straight-forward. If you learn by seeing rather than by reading, take a look at the Watershed `lmd` [repos](https://github.com/watershedlegal/commercial-documents) where we keep our contract templates for more examples. That link is for some commercial documents, but we have more on the Watershed Github page.
|
149
168
|
|
150
|
-
|
169
|
+
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 functionality. When you build your reference.odt for example and you want to have a contract look like this:
|
151
170
|
|
152
|
-
|
171
|
+
```md
|
172
|
+
# Article 1. Provision for Article 1.
|
153
173
|
|
154
|
-
|
174
|
+
Section 1.1. Provision for Section 1.1.
|
155
175
|
|
156
|
-
|
176
|
+
1.1.1 Provision for 1.1.1.
|
157
177
|
|
158
|
-
|
178
|
+
1.1.2 Provision for 1.1.2.
|
159
179
|
|
160
|
-
|
180
|
+
Section 1.2. Provision for Section 1.2.
|
161
181
|
|
162
|
-
|
182
|
+
1.2.1 Provision for 1.2.1.
|
183
|
+
|
184
|
+
1.2.2 Provision for 1.2.2.
|
163
185
|
```
|
164
186
|
|
165
187
|
You can easily to that by doing the following steps.
|
166
188
|
|
167
189
|
### Step 1: Type the body
|
168
190
|
|
169
|
-
```
|
191
|
+
```md
|
170
192
|
l. Provision for Article 1.
|
171
193
|
ll. Provision for Section 1.1.
|
172
194
|
lll. Provision for 1.1.1.
|
@@ -176,9 +198,9 @@ lll. Provision for 1.2.1.
|
|
176
198
|
lll. Provision for 1.2.2.
|
177
199
|
```
|
178
200
|
|
179
|
-
### Step 2:
|
201
|
+
### Step 2: Fill out the YAML Front-Matter
|
180
202
|
|
181
|
-
```
|
203
|
+
```yaml
|
182
204
|
---
|
183
205
|
level-1: 1.
|
184
206
|
level-2: A.
|
@@ -186,23 +208,11 @@ level-3: a.
|
|
186
208
|
---
|
187
209
|
```
|
188
210
|
|
189
|
-
### Step 3:
|
190
|
-
|
191
|
-
In Libreoffice you would modify your template reference.odt as you need it. You would go to Format -> Bullets and Numbering -> Options.
|
192
|
-
|
193
|
-
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
|
194
|
-
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.
|
195
|
-
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.
|
196
|
-
4. Lastly you would make sure that Consecutive Numbering (field at the bottom) was turned off.
|
197
|
-
5. You can make sure that all the indenting is as desired in the Position Tab.
|
198
|
-
|
199
|
-
Then you would save the reference.odt as a new name perhaps contract-reference.odt in your Pandoc reference folder.
|
200
|
-
|
201
|
-
### Step 3(a): Add Precursors to Headers
|
211
|
+
### Step 3(a): (Optional) Add Precursors to Headers
|
202
212
|
|
203
213
|
Within the text of the document nothing changes. In the YAML front matter you will leave it as it was before. All you need to do is add any word or other marker before the trigger. If you want to reference the preceding level (like 1.1.1 in the example above) then simply put in `pre`.So, your YAML front matter will look like this:
|
204
214
|
|
205
|
-
```
|
215
|
+
```yaml
|
206
216
|
---
|
207
217
|
level-1: Article 1.
|
208
218
|
level-2: Section pre 1.
|
@@ -212,11 +222,11 @@ level-3: pre 1.
|
|
212
222
|
|
213
223
|
This is how I build most of my contracts.
|
214
224
|
|
215
|
-
### Step 3(b) Add Another Type of Precursors to Headers
|
225
|
+
### Step 3(b) (Optional) Add Another Type of Precursors to Headers
|
216
226
|
|
217
|
-
Sometimes, particularly in laws, the structure is something akin to Chapter 1 and then Section 101, Section 102, ... Chapter 9, Section 901, Section 902, etc.
|
227
|
+
Sometimes, particularly in laws, the structure is something akin to Chapter 1 and then Section 101, Section 102, ... Chapter 9, Section 901, Section 902, etc. You can easily adopt this structure to your document by using the `preval` feature within the YAML front matter. If you combined this structure by also using markdown headers the YAML front matter would look something like this:
|
218
228
|
|
219
|
-
```
|
229
|
+
```yaml
|
220
230
|
---
|
221
231
|
level-1: "# Chapter 1."
|
222
232
|
level-2: "## Section preval 1."
|
@@ -227,7 +237,7 @@ no-indent: l., ll.
|
|
227
237
|
|
228
238
|
This would output (using the same text from the body of the document typed in step 1) as:
|
229
239
|
|
230
|
-
```
|
240
|
+
```md
|
231
241
|
# Chapter 1. Provision for Article 1.
|
232
242
|
|
233
243
|
## Section 101. Provision for Section 1.1.
|
@@ -241,15 +251,23 @@ This would output (using the same text from the body of the document typed in st
|
|
241
251
|
102(a) Provision for 1.2.1.
|
242
252
|
|
243
253
|
103(b) Provision for 1.2.2.
|
244
|
-
|
245
|
-
...
|
246
254
|
```
|
247
255
|
|
248
|
-
### Step 4:
|
256
|
+
### Step 4: Modify your reference.odt or reference.docx
|
249
257
|
|
250
|
-
|
258
|
+
In Libreoffice you would modify your template reference.odt as you need it. If you wanted to use fancy bullets and lists operated by Libreoffice, you would go to Format -> Bullets and Numbering -> Options.
|
251
259
|
|
252
|
-
|
260
|
+
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
|
261
|
+
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.
|
262
|
+
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.
|
263
|
+
4. Lastly you would make sure that Consecutive Numbering (field at the bottom) was turned off.
|
264
|
+
5. You can make sure that all the indenting is as desired in the Position Tab.
|
265
|
+
|
266
|
+
Then you would save the reference.odt as a new name perhaps contract-reference.odt in your Pandoc reference folder. That would accomplish the same thing as sticking `pre` into the YAML Front Matter. Your choice.
|
267
|
+
|
268
|
+
### Step 4: Run Legal-Markdown and Pandoc (or other text processor)
|
269
|
+
|
270
|
+
Make sure when you run Pandoc you use the new reference document that you created as the basis. 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.
|
253
271
|
|
254
272
|
## A Few Other Features
|
255
273
|
|
@@ -257,13 +275,13 @@ I find, particularly when I'm working with contracts and templates that I needed
|
|
257
275
|
|
258
276
|
### Working with Cross Reference Provisions.
|
259
277
|
|
260
|
-
One thing I needed was the ability to cross reference between provisions where the text of Section 16 refers back to Section 12. When you're working with templates you may turn on or off provisions after reviewing a draft with a client. Also when you're working in a `lmd` file you do not see what the Section reference is within the document (that's the whole point). So
|
278
|
+
One thing I needed was the ability to cross reference between provisions where the text of Section 16 refers back to Section 12. When you're working with templates you may turn on or off provisions after reviewing a draft with a client. Also when you're working in a `lmd` file you do not see what the Section reference is within the document (that's the whole point). So there is a cross referencing feature to `legal_markdown`.
|
261
279
|
|
262
|
-
In order to try to make the gem interoperable with as many finishing renders as possible I've tried to keep the switches and symbols unique to the gem to a very few
|
280
|
+
In order to try to make the gem interoperable with as many finishing renders as possible I've tried to keep the switches and symbols unique to the gem to a very few. But there is only so much one can do with those symbols. So I have had to add one more symbol to get the cross-referencing right and unambiguous to the parser. Within your structured headers block simply place a reference (which you can make up and remember, it can contain letters, numbers, or symbols) within pipes "|" (the key above the enter key on US keyboards). First stake the piped reference to the provision which you want to reference to. Then other provisions can refer to it (either before or after the reference point within the document).
|
263
281
|
|
264
282
|
For example, if the YAML front matter looked like this:
|
265
283
|
|
266
|
-
```
|
284
|
+
```yaml
|
267
285
|
---
|
268
286
|
level-1: "# Article 1."
|
269
287
|
level-2: "Section 1."
|
@@ -274,7 +292,7 @@ no-indent: l., ll.
|
|
274
292
|
|
275
293
|
and the body of the text looked like this:
|
276
294
|
|
277
|
-
```
|
295
|
+
```md
|
278
296
|
...
|
279
297
|
ll. |123| This provision will need to be referenced later.
|
280
298
|
ll. Provision
|
@@ -284,7 +302,7 @@ lll. As stated in |123|, whatever you need to say.
|
|
284
302
|
|
285
303
|
would output to this:
|
286
304
|
|
287
|
-
```
|
305
|
+
```md
|
288
306
|
Section 7. This provision will need to be referenced later.
|
289
307
|
|
290
308
|
Section 8. Provision
|
@@ -292,17 +310,21 @@ Section 8. Provision
|
|
292
310
|
(a) As stated in Section 7, whatever you need to say.
|
293
311
|
```
|
294
312
|
|
295
|
-
|
313
|
+
### Working with Partials
|
296
314
|
|
297
315
|
In particular when I work with templates, I was realizing that it would be nice to be a bit more DRY (don't repeat yourself) in my contract building. In order to help with this, I wanted to build a partials feature. Probably not a lot of people will use this, but here is how you do it. Let's say you put your standard interpretation, notice, severance, boilerplate typically at the end of the contract just before the signature block. Let's also assume that you have multiple contract templates and they all mostly use the same boilerplate final provisions.
|
298
316
|
|
299
317
|
If you were lawyering like coders think then you would abstract these provisions into their own file within your contracts templates folder. Then you would change all of your templates to reference back to that partial. Later, if there is some change in the law you just go into the partial, make the necessary change to adopt to the change in law or interpretation, and then all of your templates which refer to that partial are automatically updated. A bit more simple then updating each and every one of your templates, eh?
|
300
318
|
|
301
|
-
Partials are simple. They use the `@import [filename]` syntax. So if your final provisions are kept in a file in the same folder called final_provisions.lmd you would put `@import final_provisions.lmd` on its own line (either within a structured headers block or outside of it) and the gem will import the contents of the partial before chewing on the whole contract. If your partial was located in another directory you just type that in just like you would on the command line `@import
|
319
|
+
Partials are simple. They use the `@import [filename]` syntax on a line by itself. So if your final provisions are kept in a file in the same folder called final_provisions.lmd you would put `@import final_provisions.lmd` on its own line (either within a structured headers block or outside of it) and the gem will import the contents of the partial before chewing on the whole contract. If your partial was located in another directory you just type that in just like you would on the command line `@import gitlaw/contracts/commercial/partials/final_provisions.lmd` or wherever your partial is.
|
302
320
|
|
303
|
-
|
321
|
+
### Date
|
304
322
|
|
305
|
-
When you are building documents sometime you simply want to put `
|
323
|
+
When you are building documents sometime you simply want to put `date: @today`. Try it! At this point it formats dates according to standard formating outside of the US. But if you want to change that, then simply add the date manually.
|
324
|
+
|
325
|
+
### Citations
|
326
|
+
|
327
|
+
At this point legal_markdown does not have a native citation handling ability. For now, I've outsourced that to the primary processor. If you look at pandoc, it has excellent bibtex and citation support that will bluebook up everything for you. Legal Markdown does not get in the way if how pandoc does citations so it is fully compatible.
|
306
328
|
|
307
329
|
## A Few Gotchas
|
308
330
|
|
@@ -311,14 +333,13 @@ When you are building documents sometime you simply want to put `effective_date:
|
|
311
333
|
|
312
334
|
## Roadmap / TODO
|
313
335
|
|
314
|
-
|
315
|
-
|
316
|
-
- [
|
317
|
-
- [
|
318
|
-
- [
|
319
|
-
- [
|
320
|
-
- [
|
321
|
-
- [ ] md2lmd functionality. At this point legal_markdown cannot take a markdown document and parse it to build a structured legal document. Legal_markdown only works with a renderer to *create* documents but not to *parse* legal documents to create markdown.
|
336
|
+
Integration is my next big area to focus on for the package:
|
337
|
+
|
338
|
+
- [ ] lmd2xml functionality.
|
339
|
+
- [ ] lmd2mobi functionality.
|
340
|
+
- [ ] json2lmd functionality.
|
341
|
+
- [ ] xml2lmd functionality.
|
342
|
+
- [ ] pdf2lmd functionality.
|
322
343
|
|
323
344
|
If you have needs that you think other people may have, feel free to put them up in the Github issues.
|
324
345
|
|
data/Rakefile
CHANGED
@@ -1,9 +1,17 @@
|
|
1
|
-
require
|
1
|
+
require 'bundler'
|
2
|
+
require 'bundler/gem_tasks'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
2
10
|
require 'rake/testtask'
|
3
11
|
|
4
12
|
Rake::TestTask.new do |t|
|
5
13
|
t.libs << "test"
|
6
|
-
t.test_files = FileList['test
|
14
|
+
t.test_files = FileList['test/*test*.rb']
|
7
15
|
t.verbose = true
|
8
16
|
end
|
9
17
|
|
@@ -54,7 +62,6 @@ task :pushit do
|
|
54
62
|
system "git push wsl master"
|
55
63
|
Dir.chdir(File.dirname(__FILE__))
|
56
64
|
system "google-chrome https://github.com/compleatang/legal-markdown/releases"
|
57
|
-
system "gl"
|
58
65
|
end
|
59
66
|
|
60
67
|
task :default => [:test]
|
data/lib/legal_markdown.rb
CHANGED
@@ -1,22 +1,86 @@
|
|
1
|
-
|
1
|
+
#!/usr/bin/env ruby
|
2
2
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
3
|
require 'legal_markdown/version.rb'
|
4
4
|
require 'legal_markdown/make_yaml_frontmatter.rb'
|
5
5
|
require 'legal_markdown/legal_to_markdown.rb'
|
6
|
+
require 'optparse'
|
6
7
|
|
7
8
|
module LegalMarkdown
|
8
9
|
|
9
10
|
def self.parse(*args)
|
10
|
-
args
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
args ||= ARGV.dup
|
12
|
+
|
13
|
+
config={}
|
14
|
+
config[:input] = {}
|
15
|
+
config[:output] = {}
|
16
|
+
|
17
|
+
opt_parser = OptionParser.new do |opt|
|
18
|
+
opt.banner = "Usage: legal2md [commands] [input_file] [output_file]"
|
19
|
+
opt.separator ""
|
20
|
+
opt.separator "[input_file] can be a file, or use \"-\" for STDIN"
|
21
|
+
opt.separator "[output_file] can be a file, or use \"-\" for STDOUT"
|
22
|
+
opt.separator ""
|
23
|
+
opt.separator "Specific Commands:"
|
24
|
+
|
25
|
+
config[:output][:markdown] = false
|
26
|
+
opt.on( '-m', '--to-markdown', 'Parse the Legal Markdown file and produce a Text document (md, rst, txt, etc.).' ) do
|
27
|
+
config[:output][:markdown] = true
|
28
|
+
end
|
29
|
+
|
30
|
+
config[:output][:jason] = false
|
31
|
+
opt.on( '-j', '--to-json', 'Parse the Legal Markdown file and produce a JSON document.' ) do
|
32
|
+
config[:output][:jason] = true
|
33
|
+
end
|
34
|
+
|
35
|
+
config[:headers] = false
|
36
|
+
opt.on( '-d', '--headers', 'Make the YAML Frontmatter automatically.' ) do
|
37
|
+
config[:headers] = true
|
38
|
+
end
|
39
|
+
|
40
|
+
if args.include? :headers
|
41
|
+
config[:headers] = true
|
42
|
+
args.delete :headers
|
43
|
+
end
|
44
|
+
|
45
|
+
if args.include?( :to_json ) || (begin args[-1][/\.json/]; rescue; end;)
|
46
|
+
config[:output][:jason] = true
|
47
|
+
args.delete(:to_json) if args.include?( :to_json )
|
48
|
+
end
|
49
|
+
|
50
|
+
if args.include? :to_markdown
|
51
|
+
config[:output][:markdown] = true
|
52
|
+
args.delete :markdown
|
53
|
+
end
|
54
|
+
|
55
|
+
opt.on( '-v', '--version', 'Display the gem\'s current version that you are using.' ) do
|
56
|
+
puts 'Legal Markdown version ' + LegalMarkdown::VERSION
|
57
|
+
exit
|
58
|
+
end
|
59
|
+
|
60
|
+
opt.on( '-h', '--help', 'Display this screen at any time.' ) do
|
61
|
+
puts opt_parser
|
62
|
+
exit
|
63
|
+
end
|
64
|
+
|
65
|
+
opt.separator ""
|
66
|
+
opt.separator "Notes:"
|
67
|
+
opt.separator "If the command is --headers or with --to-markdown you can enter one file to be parsed if you wish."
|
68
|
+
opt.separator "When these commands are called with only one file I will set the input_file and the output_file to be the same."
|
69
|
+
opt.separator "The other commands will require the original legal_markdown file and the output format."
|
70
|
+
opt.separator "There is no need to explicitly enter the --to-json if your output_file is *.json I can handle it."
|
71
|
+
opt.separator ""
|
72
|
+
end
|
73
|
+
opt_parser.parse!(args)
|
74
|
+
|
75
|
+
if config[:headers]
|
15
76
|
MakeYamlFrontMatter.new(args)
|
16
|
-
elsif
|
77
|
+
elsif config[:output][:jason]
|
17
78
|
LegalToMarkdown.parse_jason(args)
|
18
|
-
|
79
|
+
elsif config[:output][:markdown] || args.size <= 2
|
19
80
|
LegalToMarkdown.parse_markdown(args)
|
81
|
+
else
|
82
|
+
puts opt_parser
|
20
83
|
end
|
21
84
|
end
|
22
|
-
end
|
85
|
+
end
|
86
|
+
|
@@ -12,9 +12,10 @@ class MakeYamlFrontMatter
|
|
12
12
|
|
13
13
|
def load(args)
|
14
14
|
begin
|
15
|
-
@
|
16
|
-
|
17
|
-
|
15
|
+
@input_file = args[-2] ? args[-2] : args[-1]
|
16
|
+
@output_file = args[-1]
|
17
|
+
if @input_file != "-"
|
18
|
+
source_file = File::read(@input_file) if File::exists?(@input_file) && File::readable?(@input_file)
|
18
19
|
else
|
19
20
|
source_file = STDIN.read
|
20
21
|
end
|
@@ -26,7 +27,7 @@ class MakeYamlFrontMatter
|
|
26
27
|
end
|
27
28
|
return source_file
|
28
29
|
rescue => e
|
29
|
-
puts "Sorry, I could not read the input file #{@
|
30
|
+
puts "Sorry, I could not read the input file #{@input_file}: #{e.message}."
|
30
31
|
exit 0
|
31
32
|
end
|
32
33
|
end
|
@@ -74,8 +75,8 @@ class MakeYamlFrontMatter
|
|
74
75
|
to_replace = set[0]
|
75
76
|
@content.gsub!(to_replace, replacer)
|
76
77
|
end
|
77
|
-
if @
|
78
|
-
File.open(@
|
78
|
+
if @output_file && @output_file != "-"
|
79
|
+
File.open(@output_file, "w") {|f| f.write( @content ); f.close }
|
79
80
|
else
|
80
81
|
STDOUT.write @content
|
81
82
|
end
|
@@ -17,13 +17,17 @@ class TestLegalMarkdownToMarkdown < Test::Unit::TestCase
|
|
17
17
|
@lmdfiles.sort!
|
18
18
|
end
|
19
19
|
|
20
|
+
def teardown
|
21
|
+
puts "\nAll Done!\n\n"
|
22
|
+
end
|
23
|
+
|
20
24
|
def get_file ( filename )
|
21
25
|
contents = IO.read(filename)
|
22
26
|
contents.rstrip
|
23
27
|
end
|
24
28
|
|
25
|
-
def create_temp
|
26
|
-
temp_file = "/tmp/lmdtests-" + SecureRandom.hex
|
29
|
+
def create_temp(ending)
|
30
|
+
temp_file = "/tmp/lmdtests-" + SecureRandom.hex + ending
|
27
31
|
end
|
28
32
|
|
29
33
|
def destroy_temp ( temp_file )
|
@@ -38,9 +42,9 @@ class TestLegalMarkdownToMarkdown < Test::Unit::TestCase
|
|
38
42
|
puts "Testing lmd to markdown files.\n\n"
|
39
43
|
@lmdfiles.each do | lmd_file |
|
40
44
|
puts "Testing => #{lmd_file}"
|
41
|
-
temp_file = create_temp
|
45
|
+
temp_file = create_temp('.md')
|
42
46
|
benchmark_file = File.basename(lmd_file, ".lmd") + ".md"
|
43
|
-
|
47
|
+
LegalMarkdown.parse( :to_markdown, lmd_file, temp_file )
|
44
48
|
assert_equal(get_file(benchmark_file), get_file(temp_file), "This file threw an exception => #{lmd_file}")
|
45
49
|
destroy_temp temp_file
|
46
50
|
end
|
@@ -50,9 +54,9 @@ class TestLegalMarkdownToMarkdown < Test::Unit::TestCase
|
|
50
54
|
puts "\n\nTesting lmd to json files.\n\n"
|
51
55
|
@lmdfiles.each do | lmd_file |
|
52
56
|
puts "Testing => #{lmd_file}"
|
53
|
-
temp_file = create_temp
|
57
|
+
temp_file = create_temp('.json')
|
54
58
|
benchmark_file = File.basename(lmd_file, ".lmd") + ".json"
|
55
|
-
|
59
|
+
LegalMarkdown.parse( :to_json, lmd_file, temp_file )
|
56
60
|
benchmark = JSON.parse(IO.read(benchmark_file))
|
57
61
|
temp = JSON.parse(IO.read(temp_file))
|
58
62
|
assert_not_equal(benchmark["id"], temp["id"])
|
@@ -65,14 +69,14 @@ class TestLegalMarkdownToMarkdown < Test::Unit::TestCase
|
|
65
69
|
end
|
66
70
|
|
67
71
|
def test_yaml_headers
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
end
|
72
|
+
puts "\n\nTesting Make YAML Frontmatter.\n\n"
|
73
|
+
@lmdfiles.each do | lmd_file |
|
74
|
+
puts "Testing => #{lmd_file}"
|
75
|
+
temp_file = create_temp('.lmd')
|
76
|
+
benchmark_file = File.basename(lmd_file, ".lmd") + ".headers"
|
77
|
+
LegalMarkdown.parse( :headers, lmd_file, temp_file )
|
78
|
+
assert_equal(get_file(benchmark_file), get_file(temp_file), "This file threw an exception => #{lmd_file}")
|
79
|
+
destroy_temp temp_file
|
77
80
|
end
|
81
|
+
end
|
78
82
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: legal_markdown
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-07-
|
12
|
+
date: 2013-07-30 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: ! ' This gem will parse YAML Front Matter of Markdown Documents. Typically,
|
15
15
|
this gem would be called with a md renderer, such as Pandoc, that would turn the
|
@@ -44,8 +44,7 @@ files:
|
|
44
44
|
- lib/legal_markdown/make_yaml_frontmatter.rb
|
45
45
|
- lib/legal_markdown/roman_numerals.rb
|
46
46
|
- lib/legal_markdown/version.rb
|
47
|
-
-
|
48
|
-
- test/test_legal_markdown_to_markdown.rb
|
47
|
+
- test/legal_markdown_test.rb
|
49
48
|
- test/tests/00.load_write_no_action.headers
|
50
49
|
- test/tests/00.load_write_no_action.json
|
51
50
|
- test/tests/00.load_write_no_action.lmd
|
@@ -179,7 +178,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
179
178
|
version: '0'
|
180
179
|
segments:
|
181
180
|
- 0
|
182
|
-
hash:
|
181
|
+
hash: 2539326547040470176
|
183
182
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
184
183
|
none: false
|
185
184
|
requirements:
|
@@ -188,7 +187,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
188
187
|
version: '0'
|
189
188
|
segments:
|
190
189
|
- 0
|
191
|
-
hash:
|
190
|
+
hash: 2539326547040470176
|
192
191
|
requirements: []
|
193
192
|
rubyforge_project:
|
194
193
|
rubygems_version: 1.8.25
|
@@ -197,7 +196,7 @@ specification_version: 3
|
|
197
196
|
summary: Gem for parsing legal documents written in markdown for processing with legal
|
198
197
|
specific requirements.
|
199
198
|
test_files:
|
200
|
-
- test/
|
199
|
+
- test/legal_markdown_test.rb
|
201
200
|
- test/tests/00.load_write_no_action.headers
|
202
201
|
- test/tests/00.load_write_no_action.json
|
203
202
|
- test/tests/00.load_write_no_action.lmd
|
data/libpeerconnection.log
DELETED
File without changes
|