law_doc 0.1.15
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +16 -0
- data/.rspec +3 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/README.org +82 -0
- data/Rakefile +6 -0
- data/bin/console +7 -0
- data/bin/setup +8 -0
- data/law_doc.gemspec +34 -0
- data/lib/blankable_date.rb +239 -0
- data/lib/law_doc/address.rb +49 -0
- data/lib/law_doc/case.rb +318 -0
- data/lib/law_doc/core_ext/array.rb +51 -0
- data/lib/law_doc/core_ext/nil.rb +9 -0
- data/lib/law_doc/core_ext/numeric.rb +34 -0
- data/lib/law_doc/core_ext/string.rb +3 -0
- data/lib/law_doc/core_ext.rb +4 -0
- data/lib/law_doc/court.rb +48 -0
- data/lib/law_doc/document.rb +452 -0
- data/lib/law_doc/error.rb +2 -0
- data/lib/law_doc/init_types.rb +182 -0
- data/lib/law_doc/judge.rb +28 -0
- data/lib/law_doc/lawyer.rb +111 -0
- data/lib/law_doc/party.rb +40 -0
- data/lib/law_doc/person.rb +291 -0
- data/lib/law_doc/phone.rb +62 -0
- data/lib/law_doc/version.rb +3 -0
- data/lib/law_doc.rb +73 -0
- metadata +173 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: dfdd33df5942fb08182facdb203f53b222844f0f3be50132ede38383a155fade
|
4
|
+
data.tar.gz: cf991c3177a676c3c91a533eb6ef4318054533c048cc43c659e6789457443fef
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4bfd6a7b2bbfa183cb37ca7bb82f0a06a2c39b4bbc5db5bcfc521fbdb5cf16980e43ec8878f5176bb112158caf47e01ac574c5551d4c8732696f301760aaec17
|
7
|
+
data.tar.gz: 67c7cfa6dbe9857806c84f47fdb8dd0b634c887157ed08c961602bf9683485361cff0a2a9d4e64fc31ca489c582a72fe8885cdacc3308008d8122ba6c961e313
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.org
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
* LawDoc
|
2
|
+
|
3
|
+
The ~law_doc~ gem provides classes meant to provide the glue between the ~ydl~
|
4
|
+
data language and the ~lawdoc.cls~ LaTeX document class and the ~legal~ style
|
5
|
+
files for composing legal documents. Getting ruby code executed as part of LaTeX
|
6
|
+
pre-processing is the job of ~erbtex~, itself a ruby command-line that executes
|
7
|
+
ruby code embedded in the LaTeX file between delimiters ~{:~ and ~:}~ before
|
8
|
+
handing the resulting text off to LaTeX. The ~law_doc~ gem provides objects for
|
9
|
+
such things as Person, Lawyer, Party, Court, Case, and Document, as well as
|
10
|
+
other lower-level supporting classes such as Email and Phone. These classes know
|
11
|
+
how to spit out LaTeX macros suitable for use in a ~lawdoc.cls~ document class.
|
12
|
+
The classes can be constructed from the ~YAML~-like ~ydl~ files found in the
|
13
|
+
file system simply
|
14
|
+
|
15
|
+
All that is needed is a LaTeX document such as the following
|
16
|
+
#+BEGIN_EXAMPLE
|
17
|
+
\documentclass{lawdoc}
|
18
|
+
|
19
|
+
{:=
|
20
|
+
require 'law_doc'
|
21
|
+
LawDoc.document do
|
22
|
+
title 'Brief in Support of Plaintiff\'s Motion for Summary Judgment'
|
23
|
+
kase Ydl[:cases][:erickson]
|
24
|
+
on_behalf_of 'plaintiffs'
|
25
|
+
signers Ydl[:lawyers][:ded], Ydl[:lawyers][:cjh]
|
26
|
+
sig_date '2015-11-20'
|
27
|
+
server signer
|
28
|
+
service_date sig_date
|
29
|
+
end
|
30
|
+
:}
|
31
|
+
|
32
|
+
\begin{document}
|
33
|
+
\makecaption
|
34
|
+
|
35
|
+
\makefullsignature
|
36
|
+
|
37
|
+
\newpage
|
38
|
+
\makecertificateofservice
|
39
|
+
\end{document}
|
40
|
+
#+END_EXAMPLE
|
41
|
+
|
42
|
+
to activate macros such as ~\makecaption~ that perform the tiresome parts of a
|
43
|
+
legal document.
|
44
|
+
|
45
|
+
The call to ~LawDoc.document~ defines the current document by reference to a
|
46
|
+
Hash called ~Ydl~ of items defined in the ~.ydl~ files found in the file system.
|
47
|
+
|
48
|
+
** Installation
|
49
|
+
|
50
|
+
Add this line to your application's Gemfile:
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
gem 'law_doc'
|
54
|
+
```
|
55
|
+
|
56
|
+
And then execute:
|
57
|
+
|
58
|
+
$ bundle
|
59
|
+
|
60
|
+
Or install it yourself as:
|
61
|
+
|
62
|
+
$ gem install law_doc
|
63
|
+
|
64
|
+
** Usage
|
65
|
+
|
66
|
+
TODO: Write usage instructions here
|
67
|
+
|
68
|
+
** Development
|
69
|
+
|
70
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
71
|
+
`rake spec` to run the tests. You can also run `bin/console` for an interactive
|
72
|
+
prompt that will allow you to experiment.
|
73
|
+
|
74
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To
|
75
|
+
release a new version, update the version number in `version.rb`, and then run
|
76
|
+
`bundle exec rake release`, which will create a git tag for the version, push
|
77
|
+
git commits and tags, and push the `.gem` file to
|
78
|
+
[rubygems.org](https://rubygems.org).
|
79
|
+
|
80
|
+
** Contributing
|
81
|
+
|
82
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/ddoherty03/law_doc.
|
data/Rakefile
ADDED
data/bin/console
ADDED
data/bin/setup
ADDED
data/law_doc.gemspec
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'law_doc/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'law_doc'
|
8
|
+
spec.version = LawDoc::VERSION
|
9
|
+
spec.authors = ['Daniel E. Doherty']
|
10
|
+
spec.email = ['ded@ddoherty.net']
|
11
|
+
spec.summary = %q{Ruby classes to assist in writing LaTeX legal documents.}
|
12
|
+
spec.description = <<~DESC
|
13
|
+
|
14
|
+
A set of classes for legal document elements such as Document, Case, Lawyer, Party, Court, Judge, etc. Made to play
|
15
|
+
well with the ydl and erbtex gems.
|
16
|
+
|
17
|
+
DESC
|
18
|
+
|
19
|
+
spec.homepage = 'https://github.com/ddoherty03/law_doc'
|
20
|
+
|
21
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
22
|
+
f.match(%r{^(test|spec|features)/})
|
23
|
+
end
|
24
|
+
spec.require_paths = ['lib']
|
25
|
+
|
26
|
+
spec.add_dependency 'fat_core'
|
27
|
+
spec.add_dependency 'activesupport', '~>6.0'
|
28
|
+
|
29
|
+
spec.add_development_dependency 'rake'
|
30
|
+
spec.add_development_dependency 'rspec', '>= 3.0'
|
31
|
+
spec.add_development_dependency 'pry'
|
32
|
+
spec.add_development_dependency 'pry-doc'
|
33
|
+
spec.add_development_dependency 'debug', '>= 1.0.0'
|
34
|
+
end
|
@@ -0,0 +1,239 @@
|
|
1
|
+
# Allow dates to blankify day, month, or year component
|
2
|
+
class BlankableDate < Date
|
3
|
+
cattr_accessor :blanks, :valid_styles, :default_style
|
4
|
+
|
5
|
+
self.default_style = :tex_dots
|
6
|
+
self.valid_styles = []
|
7
|
+
|
8
|
+
self.blanks = {}
|
9
|
+
blanks[:tex_dots] = {}
|
10
|
+
blanks[:tex_rules] = {}
|
11
|
+
blanks[:ascii_dots] = {}
|
12
|
+
blanks[:ascii_rules] = {}
|
13
|
+
|
14
|
+
#######################################################################
|
15
|
+
# Set blank styles
|
16
|
+
#######################################################################
|
17
|
+
|
18
|
+
class << self
|
19
|
+
# Use TeX \dotfill macro to represent blanks
|
20
|
+
def set_tex_dots
|
21
|
+
style = :tex_dots
|
22
|
+
valid_styles.push(style)
|
23
|
+
blanks[style][:long] = '\\leavevmode\\hbox to 9em{\\dotfill}}'
|
24
|
+
blanks[style][:medium] = '\\leavevmode\\hbox to 4em{\\dotfill}}'
|
25
|
+
blanks[style][:short] = '\\leavevmode\\hbox to 2em{\\dotfill}}'
|
26
|
+
end
|
27
|
+
|
28
|
+
# Use TeX \hrulefill macro to represent blanks
|
29
|
+
def set_tex_rules
|
30
|
+
style = :tex_rules
|
31
|
+
valid_styles.push(style)
|
32
|
+
blanks[style][:long] = '\\leavevmode\\hbox to 9em{\\hrulefill}}'
|
33
|
+
blanks[style][:medium] = '\\leavevmode\\hbox to 4em{\\hrulefill}}'
|
34
|
+
blanks[style][:short] = '\\leavevmode\\hbox to 2em{\\hrulefill}}'
|
35
|
+
end
|
36
|
+
|
37
|
+
# Use a series of acsii '.' to represent blanks
|
38
|
+
def set_ascii_dots
|
39
|
+
style = :ascii_dots
|
40
|
+
valid_styles.push(style)
|
41
|
+
blanks[style][:long] = '.........'
|
42
|
+
blanks[style][:medium] = '....'
|
43
|
+
blanks[style][:short] = '..'
|
44
|
+
end
|
45
|
+
|
46
|
+
# Use a series of acsii '_' to represent blanks
|
47
|
+
def set_ascii_rules
|
48
|
+
style = :ascii_rules
|
49
|
+
valid_styles.push(style)
|
50
|
+
blanks[style][:long] = '_________'
|
51
|
+
blanks[style][:medium] = '____'
|
52
|
+
blanks[style][:short] = '__'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
set_tex_dots
|
57
|
+
set_tex_rules
|
58
|
+
set_ascii_dots
|
59
|
+
set_ascii_rules
|
60
|
+
end
|
61
|
+
|
62
|
+
class BlankableDate < Date
|
63
|
+
attr_reader :style
|
64
|
+
|
65
|
+
# Initialize a BlankableDate in the same way as Date.new but allow blank
|
66
|
+
# components to be declared with keyword arguments ~blank_day~, ~blank_month~,
|
67
|
+
# and ~blank_year~. By default, none of the components is blank, so a
|
68
|
+
# BlankableDate acts just like a Date. However, when converted to a string
|
69
|
+
# with #strftime, the blank components are replaced with strings representing
|
70
|
+
# blanks.
|
71
|
+
def self.new(year, month, day,
|
72
|
+
blank_day: false,
|
73
|
+
blank_month: false,
|
74
|
+
blank_year: false)
|
75
|
+
obj = super(year, month, day)
|
76
|
+
obj.instance_variable_set(:@day_blank, blank_day)
|
77
|
+
obj.instance_variable_set(:@month_blank, blank_month)
|
78
|
+
obj.instance_variable_set(:@year_blank, blank_year)
|
79
|
+
obj.instance_variable_set(:@style, default_style)
|
80
|
+
obj
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.parse(str)
|
84
|
+
dt = super
|
85
|
+
new(dt.year, dt.month, dt.day)
|
86
|
+
end
|
87
|
+
|
88
|
+
##########################################################################
|
89
|
+
# Constructors
|
90
|
+
##########################################################################
|
91
|
+
|
92
|
+
# Return today as a BlankableDate
|
93
|
+
def self.today
|
94
|
+
today = Date.today
|
95
|
+
new(today.year, today.month, today.day)
|
96
|
+
end
|
97
|
+
|
98
|
+
# A date this month with the day blank
|
99
|
+
def self.this_month
|
100
|
+
day = Date.today
|
101
|
+
new(day.year, day.month, day.day).blank_day
|
102
|
+
end
|
103
|
+
|
104
|
+
# A date this year with the month and day blank
|
105
|
+
def self.this_year
|
106
|
+
day = Date.today
|
107
|
+
new(day.year, day.month, day.day)
|
108
|
+
.blank_month
|
109
|
+
.blank_day
|
110
|
+
end
|
111
|
+
|
112
|
+
# A date last month with the day blank
|
113
|
+
def self.last_month
|
114
|
+
day = Date.today - 1.month
|
115
|
+
new(day.year, day.month, day.day).blank_day
|
116
|
+
end
|
117
|
+
|
118
|
+
# A date last year with the month and day blank
|
119
|
+
def self.last_year
|
120
|
+
day = Date.today
|
121
|
+
new(day.year - 1, day.month, day.day)
|
122
|
+
.blank_month
|
123
|
+
.blank_day
|
124
|
+
end
|
125
|
+
|
126
|
+
# A date next month with the day blank
|
127
|
+
def self.next_month
|
128
|
+
day = Date.today + 1.month
|
129
|
+
new(day.year, day.month, day.day)
|
130
|
+
.blank_day
|
131
|
+
end
|
132
|
+
|
133
|
+
# A date next year with the month and day blank
|
134
|
+
def self.next_year
|
135
|
+
day = Date.today
|
136
|
+
new(day.year + 1, day.month, day.day)
|
137
|
+
.blank_month
|
138
|
+
.blank_day
|
139
|
+
end
|
140
|
+
|
141
|
+
#######################################################################
|
142
|
+
# Blanking commands
|
143
|
+
#######################################################################
|
144
|
+
|
145
|
+
# Set the blank style for this BlankableDate.
|
146
|
+
def styled(style)
|
147
|
+
style = style.to_sym
|
148
|
+
unless self.class.valid_styles.include?(style)
|
149
|
+
raise ArgumentError, "invalid style: '#{style}'"
|
150
|
+
end
|
151
|
+
@style = style
|
152
|
+
self
|
153
|
+
end
|
154
|
+
|
155
|
+
# Set the day component blank
|
156
|
+
def blank_day
|
157
|
+
@day_blank = true
|
158
|
+
self
|
159
|
+
end
|
160
|
+
|
161
|
+
# Set the month component blank
|
162
|
+
def blank_month
|
163
|
+
@month_blank = true
|
164
|
+
self
|
165
|
+
end
|
166
|
+
|
167
|
+
# Set the year component blank
|
168
|
+
def blank_year
|
169
|
+
@year_blank = true
|
170
|
+
self
|
171
|
+
end
|
172
|
+
|
173
|
+
#######################################################################
|
174
|
+
# Query blank components
|
175
|
+
#######################################################################
|
176
|
+
|
177
|
+
# Return true if the day is blank
|
178
|
+
def day_blank?
|
179
|
+
@day_blank
|
180
|
+
end
|
181
|
+
|
182
|
+
# Return true if the month is blank
|
183
|
+
def month_blank?
|
184
|
+
@month_blank
|
185
|
+
end
|
186
|
+
|
187
|
+
# Return true if the year is blank
|
188
|
+
def year_blank?
|
189
|
+
@year_blank
|
190
|
+
end
|
191
|
+
|
192
|
+
def any_blank?
|
193
|
+
day_blank? || month_blank? || year_blank?
|
194
|
+
end
|
195
|
+
|
196
|
+
#######################################################################
|
197
|
+
# Formatting
|
198
|
+
#######################################################################
|
199
|
+
|
200
|
+
def strftime(fmt = '%F')
|
201
|
+
# Preserve literal percents
|
202
|
+
fmt = fmt.gsub(/%%/, '<++++>')
|
203
|
+
# Expand combinations
|
204
|
+
fmt = fmt.gsub(/%F/, '%Y-%m-%d') if fmt =~ /%F/
|
205
|
+
fmt = fmt.gsub(/%c/, '%a %b %e %T %Y') if fmt =~ /%c/
|
206
|
+
fmt = fmt.gsub(/%[Dx]/, '%m/%d/%y') if fmt =~ /%[Dx]/
|
207
|
+
fmt = fmt.gsub(/%v/, '%e-%b-%Y') if fmt =~ /%v/
|
208
|
+
fmt = fmt.gsub(/%\+/, '%a %b %e %H:%M:%S %Z %Y') if fmt =~ /%\+/
|
209
|
+
# Replace individual components
|
210
|
+
fmt = fmt.gsub(/%-?[ed]/, short_blank) if day_blank?
|
211
|
+
fmt = fmt.gsub(/%[-_]?m/, short_blank) if month_blank?
|
212
|
+
fmt = fmt.gsub(/%[y]/, short_blank) if year_blank?
|
213
|
+
fmt = fmt.gsub(/%^?[bh]/, medium_blank) if month_blank?
|
214
|
+
fmt = fmt.gsub(/%j/, medium_blank) if day_blank? || month_blank?
|
215
|
+
fmt = fmt.gsub(/%[Y]/, medium_blank) if year_blank?
|
216
|
+
fmt = fmt.gsub(/%^?B/, long_blank) if month_blank?
|
217
|
+
fmt = fmt.gsub(/%^?A/, long_blank) if any_blank?
|
218
|
+
fmt = fmt.gsub(/%^?a/, medium_blank) if any_blank?
|
219
|
+
fmt = fmt.gsub(/%[uw]/, short_blank) if any_blank?
|
220
|
+
fmt = fmt.gsub(/%C/, "#{(year / 100).floor}#{short_blank}") if year_blank?
|
221
|
+
# Restore literal percents
|
222
|
+
fmt = fmt.gsub('<++++>', '%%')
|
223
|
+
super(fmt)
|
224
|
+
end
|
225
|
+
|
226
|
+
private
|
227
|
+
|
228
|
+
def short_blank
|
229
|
+
self.class.blanks[@style][:short]
|
230
|
+
end
|
231
|
+
|
232
|
+
def medium_blank
|
233
|
+
self.class.blanks[@style][:medium]
|
234
|
+
end
|
235
|
+
|
236
|
+
def long_blank
|
237
|
+
self.class.blanks[@style][:long]
|
238
|
+
end
|
239
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module LawDoc
|
2
|
+
class Address
|
3
|
+
attr_reader :street, :city, :state, :zip, :country
|
4
|
+
|
5
|
+
include Comparable
|
6
|
+
|
7
|
+
def initialize(street: nil, streets: nil, city: nil,
|
8
|
+
state: nil, zip: nil, country: 'United States')
|
9
|
+
street ||= streets
|
10
|
+
case street
|
11
|
+
when String
|
12
|
+
@street = [street.to_s]
|
13
|
+
when Array
|
14
|
+
@street = street.map(&:to_s)
|
15
|
+
end
|
16
|
+
@city = city
|
17
|
+
@state = state
|
18
|
+
@zip = zip.to_s
|
19
|
+
@country = country
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_h
|
23
|
+
{ street: street, city: city, state: state, zip: zip, country: country }
|
24
|
+
end
|
25
|
+
|
26
|
+
def <=>(other)
|
27
|
+
to_h <=> other.to_h
|
28
|
+
end
|
29
|
+
|
30
|
+
# Return a TeX string with components separated by sep.
|
31
|
+
def tex_info(sep = ' ')
|
32
|
+
st = nil
|
33
|
+
st = street.map(&:tex_quote) if street && !street.empty?
|
34
|
+
[st, "#{@city.tex_quote}, #{@state.tex_quote} #{@zip.tex_quote}"]
|
35
|
+
.join(sep)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Return a multi-line TeX string
|
39
|
+
def tex_block
|
40
|
+
tex_info("\\\\\n")
|
41
|
+
end
|
42
|
+
|
43
|
+
# Return an in-line TeX string
|
44
|
+
def tex_inline
|
45
|
+
tex_info(', ')
|
46
|
+
end
|
47
|
+
alias to_s tex_inline
|
48
|
+
end
|
49
|
+
end
|