law_doc 0.1.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -0,0 +1,16 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
13
+ /GPATH
14
+ /GRTAGS
15
+ /GTAGS
16
+ /spec/law_doc/sample_macros.out.tex
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.3
5
+ before_install: gem install bundler -v 1.14.6
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in law_doc.gemspec
4
+ gemspec
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
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'law_doc'
5
+
6
+ require 'pry'
7
+ Pry.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
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