slaw 1.0.4 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -3
- data/README.md +18 -14
- data/bin/slaw +3 -15
- data/lib/slaw/extract/extractor.rb +3 -102
- data/lib/slaw/generator.rb +19 -6
- data/lib/slaw/parse/builder.rb +0 -17
- data/lib/slaw/version.rb +1 -1
- data/slaw.gemspec +0 -5
- data/spec/parse/builder_spec.rb +0 -38
- metadata +2 -45
- data/lib/slaw/extract/yomu_patch.rb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1639f10e008ddcdd149e040767d97476c9183ad3
|
4
|
+
data.tar.gz: 95cce3c38e35910731bfe8776974a40ba3be7c32
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 673521a6b0be293b57f7cd8279fb2df277d7c8263824fe5a007e69efaf81b76d8a2a3ef826589abe730d6ab4170f5d95ab42e915c30c44e18d7d15774715bdfa
|
7
|
+
data.tar.gz: c4e38899b280727459cbfd0982ceed856bbeb683b51e77839ba9c7f14b7cf7ff204f95eb2db52a015c1ffe8d116e0ca9bb87149d7f80168c65bf2965d051a196
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Slaw [![Build Status](https://travis-ci.org/longhotsummer/slaw.svg)](http://travis-ci.org/longhotsummer/slaw)
|
2
2
|
|
3
|
-
Slaw is a lightweight library for generating Akoma Ntoso 2.0 Act XML from plain text
|
3
|
+
Slaw is a lightweight library for generating Akoma Ntoso 2.0 Act XML from plain text documents.
|
4
4
|
It is used to power [Indigo](https://github.com/OpenUpSA/indigo) and uses grammars developed for the legal
|
5
5
|
traditions in these countries:
|
6
6
|
|
@@ -30,19 +30,9 @@ Or install it with:
|
|
30
30
|
|
31
31
|
$ gem install slaw
|
32
32
|
|
33
|
-
To run PDF extraction you will also need [poppler's pdftotext](https://poppler.freedesktop.org/).
|
34
|
-
If you're on a Mac, you can use:
|
35
|
-
|
36
|
-
$ brew install poppler
|
37
|
-
|
38
|
-
You may also need Ghostscript to remove password protection from PDF files. This is
|
39
|
-
installed by default on most systems (including Mac). On Ubuntu you can use:
|
40
|
-
|
41
|
-
$ sudo apt-get install ghostscript
|
42
|
-
|
43
33
|
The simplest way to use Slaw is via the commandline:
|
44
34
|
|
45
|
-
$ slaw parse myfile.
|
35
|
+
$ slaw parse myfile.text --grammar za
|
46
36
|
|
47
37
|
## Overview
|
48
38
|
|
@@ -50,8 +40,8 @@ Slaw generates Acts in the [Akoma Ntoso](http://www.akomantoso.org) 2.0 XML
|
|
50
40
|
standard for legislative documents. It first parses plain text using a grammar
|
51
41
|
and then generates XML from the resulting syntax tree.
|
52
42
|
|
53
|
-
Most by-laws in South Africa are available as PDF documents.
|
54
|
-
|
43
|
+
Most by-laws in South Africa are available as PDF documents. You will therefore
|
44
|
+
need to extract the text from the PDF first, using a tool like pdftotext.
|
55
45
|
PDFs can product oddities (such as oddly wrapped lines) and Slaw has a number of
|
56
46
|
rules-of-thumb for correcting these. These rules are based on South African
|
57
47
|
by-laws and may not be suitable for all regions.
|
@@ -73,6 +63,14 @@ tree, the nodes of which know how to serialize themselves in XML format.
|
|
73
63
|
Supporting formats from other country's legal traditions probably requires creating a new grammar
|
74
64
|
and parser.
|
75
65
|
|
66
|
+
## Adding your own grammar
|
67
|
+
|
68
|
+
Slaw can dynamically load your custom Treetop grammars. When called with ``--grammar xy``, Slaw
|
69
|
+
tries to require `slaw/grammars/xy/act` and instantiate the parser class ``Slaw::Grammars::XY::ActParser``.
|
70
|
+
Slaw always uses the rule `act` as the root of the parser.
|
71
|
+
|
72
|
+
You can create your own grammar by creating a gem that provides these files and classes.
|
73
|
+
|
76
74
|
## Contributing
|
77
75
|
|
78
76
|
1. Fork it at http://github.com/longhotsummer/slaw/fork
|
@@ -86,6 +84,12 @@ and parser.
|
|
86
84
|
|
87
85
|
## Changelog
|
88
86
|
|
87
|
+
### 2.0.0 (?)
|
88
|
+
|
89
|
+
* Remove support for PDFs. Do text extraction from PDFs outside of this library.
|
90
|
+
* Support dynamically loading grammars from other gems.
|
91
|
+
* Don't change ALL CAPS headings to Sentence Case.
|
92
|
+
|
89
93
|
### 1.0.4 (5 February 2019)
|
90
94
|
|
91
95
|
* SECURITY require Nokogiri 1.8.5 or greater to address https://nvd.nist.gov/vuln/detail/CVE-2018-14404
|
data/bin/slaw
CHANGED
@@ -4,8 +4,6 @@ require 'thor'
|
|
4
4
|
require 'slaw'
|
5
5
|
|
6
6
|
class SlawCLI < Thor
|
7
|
-
# TODO: support different grammars and locales
|
8
|
-
|
9
7
|
# Exit with non-zero exit code on failure.
|
10
8
|
# See https://github.com/erikhuda/thor/issues/244
|
11
9
|
def self.exit_on_failure?
|
@@ -15,29 +13,19 @@ class SlawCLI < Thor
|
|
15
13
|
class_option :verbose, type: :boolean, desc: "Display log output on stderr"
|
16
14
|
|
17
15
|
desc "parse FILE", "Parse FILE into Akoma Ntoso XML"
|
18
|
-
option :input, enum: ['text', '
|
19
|
-
option :pdftotext, desc: "Location of the pdftotext binary if not in PATH"
|
16
|
+
option :input, enum: ['text', 'html'], desc: "Type of input if it can't be determined automatically"
|
20
17
|
option :fragment, type: :string, desc: "Akoma Ntoso element name that the imported text represents. Support depends on the grammar."
|
21
18
|
option :id_prefix, type: :string, desc: "Prefix to be used when generating ID elements when parsing a fragment."
|
22
19
|
option :section_number_position, enum: ['before-title', 'after-title', 'guess'], desc: "Where do section titles come in relation to the section number? Default: before-title"
|
23
|
-
option :crop, type: :string, desc: "Crop box for PDF files, as 'left,top,width,height'."
|
24
20
|
option :grammar, type: :string, desc: "Grammar name (usually a two-letter country code). Default is za."
|
25
21
|
def parse(name)
|
26
22
|
logging
|
27
23
|
|
28
|
-
Slaw::Extract::Extractor.pdftotext_path = options[:pdftotext] if options[:pdftotext]
|
29
24
|
extractor = Slaw::Extract::Extractor.new
|
30
25
|
|
31
|
-
if options[:crop]
|
32
|
-
extractor.cropbox = options[:crop].split(',').map(&:to_i)
|
33
|
-
if extractor.cropbox.length != 4
|
34
|
-
raise Thor::Error.new("--crop requires four comma-separated integers")
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
26
|
case options[:input]
|
39
|
-
when '
|
40
|
-
text = extractor.
|
27
|
+
when 'html'
|
28
|
+
text = extractor.extract_from_html(name)
|
41
29
|
when 'text'
|
42
30
|
text = extractor.extract_from_text(name)
|
43
31
|
else
|
@@ -1,24 +1,12 @@
|
|
1
|
-
require 'open3'
|
2
|
-
require 'tempfile'
|
3
1
|
require 'mimemagic'
|
4
2
|
|
5
3
|
module Slaw
|
6
4
|
module Extract
|
7
5
|
|
8
|
-
# Routines for extracting and cleaning up context from other formats, such as
|
9
|
-
#
|
10
|
-
# You may need to set the location of the `pdftotext` binary.
|
11
|
-
#
|
12
|
-
# On Mac OS X, use `brew install xpdf` or download from http://www.foolabs.com/xpdf/download.html
|
13
|
-
#
|
14
|
-
# On Heroku, you'll need to do some hoop jumping, see http://theprogrammingbutler.com/blog/archives/2011/07/28/running-pdftotext-on-heroku/
|
6
|
+
# Routines for extracting and cleaning up context from other formats, such as HTML.
|
15
7
|
class Extractor
|
16
8
|
include Slaw::Logging
|
17
9
|
|
18
|
-
@@pdftotext_path = "pdftotext"
|
19
|
-
|
20
|
-
attr_accessor :cropbox
|
21
|
-
|
22
10
|
# Extract text from a file.
|
23
11
|
#
|
24
12
|
# @param filename [String] filename to extract from
|
@@ -28,61 +16,13 @@ module Slaw
|
|
28
16
|
mimetype = get_mimetype(filename)
|
29
17
|
|
30
18
|
case mimetype && mimetype.type
|
31
|
-
when '
|
32
|
-
extract_from_pdf(filename)
|
33
|
-
when 'text/html', nil
|
19
|
+
when 'text/html'
|
34
20
|
extract_from_html(filename)
|
35
21
|
when 'text/plain', nil
|
36
22
|
extract_from_text(filename)
|
37
23
|
else
|
38
|
-
|
39
|
-
if text.empty? or text.nil?
|
40
|
-
raise ArgumentError.new("Unsupported file type #{mimetype || 'unknown'}")
|
41
|
-
end
|
42
|
-
text
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
# Extract text from a PDF
|
47
|
-
#
|
48
|
-
# @param filename [String] filename to extract from
|
49
|
-
#
|
50
|
-
# @return [String] extracted text
|
51
|
-
def extract_from_pdf(filename)
|
52
|
-
retried = false
|
53
|
-
|
54
|
-
while true
|
55
|
-
cmd = pdf_to_text_cmd(filename)
|
56
|
-
logger.info("Executing: #{cmd}")
|
57
|
-
stdout, status = Open3.capture2(*cmd)
|
58
|
-
|
59
|
-
case status.exitstatus
|
60
|
-
when 0
|
61
|
-
return stdout
|
62
|
-
when 3
|
63
|
-
return nil if retried
|
64
|
-
retried = true
|
65
|
-
self.remove_pdf_password(filename)
|
66
|
-
else
|
67
|
-
return nil
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
# Build a command for the external PDF-to-text utility.
|
73
|
-
#
|
74
|
-
# @param filename [String] the pdf file
|
75
|
-
#
|
76
|
-
# @return [Array<String>] command and params to execute
|
77
|
-
def pdf_to_text_cmd(filename)
|
78
|
-
cmd = [Extractor.pdftotext_path, "-enc", "UTF-8", "-nopgbrk"]
|
79
|
-
|
80
|
-
if @cropbox
|
81
|
-
# left, top, width, height
|
82
|
-
cmd += "-x -y -W -H".split.zip(@cropbox.map(&:to_s)).flatten
|
24
|
+
raise ArgumentError.new("Unsupported file type #{mimetype || 'unknown'}")
|
83
25
|
end
|
84
|
-
|
85
|
-
cmd + [filename, "-"]
|
86
26
|
end
|
87
27
|
|
88
28
|
def extract_from_text(filename)
|
@@ -93,21 +33,6 @@ module Slaw
|
|
93
33
|
html_to_text(File.read(filename))
|
94
34
|
end
|
95
35
|
|
96
|
-
# Extract text from +filename+ by sending it to apache tika
|
97
|
-
# http://tika.apache.org/
|
98
|
-
def extract_via_tika(filename)
|
99
|
-
# the Yomu gem falls over when trying to write large amounts of data
|
100
|
-
# the JVM stdin, so we manually call java ourselves, relying on yomu
|
101
|
-
# to supply the gem
|
102
|
-
require 'slaw/extract/yomu_patch'
|
103
|
-
logger.info("Using Tika to get text from #{filename}. You need a JVM installed for this.")
|
104
|
-
|
105
|
-
html = Yomu.text_from_file(filename)
|
106
|
-
logger.info("Tika returned #{html.length} bytes")
|
107
|
-
# transform html into text
|
108
|
-
html_to_text(html)
|
109
|
-
end
|
110
|
-
|
111
36
|
def html_to_text(html)
|
112
37
|
here = File.dirname(__FILE__)
|
113
38
|
xslt = Nokogiri::XSLT(File.open(File.join([here, 'html_to_akn_text.xsl'])))
|
@@ -117,34 +42,10 @@ module Slaw
|
|
117
42
|
text.sub(/^<\?xml [^>]*>/, '')
|
118
43
|
end
|
119
44
|
|
120
|
-
def remove_pdf_password(filename)
|
121
|
-
file = Tempfile.new('steno')
|
122
|
-
begin
|
123
|
-
logger.info("Trying to remove password from #{filename}")
|
124
|
-
cmd = "gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=#{file.path} -c .setpdfwrite -f #{filename}".split(" ")
|
125
|
-
logger.info("Executing: #{cmd}")
|
126
|
-
Open3.capture2(*cmd)
|
127
|
-
FileUtils.move(file.path, filename)
|
128
|
-
ensure
|
129
|
-
file.close
|
130
|
-
file.unlink
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
45
|
def get_mimetype(filename)
|
135
46
|
File.open(filename) { |f| MimeMagic.by_magic(f) } \
|
136
47
|
|| MimeMagic.by_path(filename)
|
137
48
|
end
|
138
|
-
|
139
|
-
# Get location of the pdftotext executable for all instances.
|
140
|
-
def self.pdftotext_path
|
141
|
-
@@pdftotext_path
|
142
|
-
end
|
143
|
-
|
144
|
-
# Set location of the pdftotext executable for all instances.
|
145
|
-
def self.pdftotext_path=(val)
|
146
|
-
@@pdftotext_path = val
|
147
|
-
end
|
148
49
|
end
|
149
50
|
end
|
150
51
|
end
|
data/lib/slaw/generator.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'polyglot'
|
2
|
+
require 'treetop'
|
3
|
+
|
1
4
|
module Slaw
|
2
5
|
# Base class for generating Act documents
|
3
6
|
class ActGenerator
|
@@ -20,15 +23,18 @@ module Slaw
|
|
20
23
|
|
21
24
|
def build_parser
|
22
25
|
unless @@parsers[@grammar]
|
23
|
-
# load the grammar
|
24
|
-
|
25
|
-
|
26
|
-
|
26
|
+
# load the grammar with polyglot and treetop
|
27
|
+
# this will ensure the class below is available
|
28
|
+
# see: http://cjheath.github.io/treetop/using_in_ruby.html
|
29
|
+
require "slaw/grammars/#{@grammar}/act"
|
27
30
|
grammar_class = "Slaw::Grammars::#{@grammar.upcase}::ActParser"
|
28
31
|
@@parsers[@grammar] = eval(grammar_class)
|
29
32
|
end
|
30
33
|
|
31
34
|
@parser = @@parsers[@grammar].new
|
35
|
+
@parser.root = :act
|
36
|
+
|
37
|
+
@parser
|
32
38
|
end
|
33
39
|
|
34
40
|
# Generate a Slaw::Act instance from plain text.
|
@@ -76,8 +82,15 @@ module Slaw
|
|
76
82
|
# Transform an Akoma Ntoso XML document back into a plain-text version
|
77
83
|
# suitable for re-parsing back into XML with no loss of structure.
|
78
84
|
def text_from_act(doc)
|
79
|
-
|
80
|
-
|
85
|
+
# look on the load path for an XSL file for this grammar
|
86
|
+
filename = "/slaw/grammars/#{@grammar}/act_text.xsl"
|
87
|
+
|
88
|
+
if dir = $LOAD_PATH.find { |p| File.exist?(p + filename) }
|
89
|
+
xslt = Nokogiri::XSLT(File.read(dir + filename))
|
90
|
+
xslt.transform(doc).child.to_xml
|
91
|
+
else
|
92
|
+
raise "Unable to find text XSL for grammar #{@grammar}: #{fragment}"
|
93
|
+
end
|
81
94
|
end
|
82
95
|
end
|
83
96
|
end
|
data/lib/slaw/parse/builder.rb
CHANGED
@@ -151,28 +151,11 @@ module Slaw
|
|
151
151
|
#
|
152
152
|
# @return [Nokogiri::XML::Document] the updated document
|
153
153
|
def postprocess(doc)
|
154
|
-
normalise_headings(doc)
|
155
154
|
adjust_blocklists(doc)
|
156
155
|
|
157
156
|
doc
|
158
157
|
end
|
159
158
|
|
160
|
-
# Change CAPCASE headings into Sentence case.
|
161
|
-
#
|
162
|
-
# @param doc [Nokogiri::XML::Document]
|
163
|
-
def normalise_headings(doc)
|
164
|
-
logger.info("Normalising headings")
|
165
|
-
|
166
|
-
nodes = doc.xpath('//a:body//a:heading/text()', a: NS) +
|
167
|
-
doc.xpath('//a:component/a:doc[@name="schedules"]//a:heading/text()', a: NS)
|
168
|
-
|
169
|
-
nodes.each do |heading|
|
170
|
-
if !(heading.content =~ /[a-z]/)
|
171
|
-
heading.content = heading.content.downcase.gsub(/^\w/) { $&.upcase }
|
172
|
-
end
|
173
|
-
end
|
174
|
-
end
|
175
|
-
|
176
159
|
# Adjust blocklists:
|
177
160
|
#
|
178
161
|
# - nest them correctly
|
data/lib/slaw/version.rb
CHANGED
data/slaw.gemspec
CHANGED
@@ -18,7 +18,6 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_development_dependency "bundler", "~> 1.5"
|
22
21
|
spec.add_development_dependency "rake", "~> 10.3.1"
|
23
22
|
spec.add_development_dependency "rspec", "~> 2.14.1"
|
24
23
|
|
@@ -27,8 +26,4 @@ Gem::Specification.new do |spec|
|
|
27
26
|
spec.add_runtime_dependency "log4r", "~> 1.1.10"
|
28
27
|
spec.add_runtime_dependency "thor", "~> 0.19.1"
|
29
28
|
spec.add_runtime_dependency "mimemagic", "~> 0.2.1"
|
30
|
-
spec.add_runtime_dependency 'yomu', '~> 0.2.2'
|
31
|
-
# anchor twitter-text to avoid bug in 1.14.3
|
32
|
-
# https://github.com/twitter/twitter-text/issues/162
|
33
|
-
spec.add_runtime_dependency 'twitter-text', '~> 1.12.0'
|
34
29
|
end
|
data/spec/parse/builder_spec.rb
CHANGED
@@ -715,44 +715,6 @@ XML
|
|
715
715
|
end
|
716
716
|
end
|
717
717
|
|
718
|
-
describe '#normalise_headings' do
|
719
|
-
it 'should normalise ALL CAPS headings' do
|
720
|
-
doc = xml2doc(section(<<XML
|
721
|
-
<heading>DEFINITIONS FOR A.B.C.</heading>
|
722
|
-
<content>
|
723
|
-
<p></p>
|
724
|
-
</content>
|
725
|
-
XML
|
726
|
-
))
|
727
|
-
subject.normalise_headings(doc)
|
728
|
-
doc.to_s.should == section(<<XML
|
729
|
-
<heading>Definitions for a.b.c.</heading>
|
730
|
-
<content>
|
731
|
-
<p/>
|
732
|
-
</content>
|
733
|
-
XML
|
734
|
-
)
|
735
|
-
end
|
736
|
-
|
737
|
-
it 'should not normalise normal headings' do
|
738
|
-
doc = xml2doc(section(<<XML
|
739
|
-
<heading>Definitions for A.B.C.</heading>
|
740
|
-
<content>
|
741
|
-
<p></p>
|
742
|
-
</content>
|
743
|
-
XML
|
744
|
-
))
|
745
|
-
subject.normalise_headings(doc)
|
746
|
-
doc.to_s.should == section(<<XML
|
747
|
-
<heading>Definitions for A.B.C.</heading>
|
748
|
-
<content>
|
749
|
-
<p/>
|
750
|
-
</content>
|
751
|
-
XML
|
752
|
-
)
|
753
|
-
end
|
754
|
-
end
|
755
|
-
|
756
718
|
describe '#preprocess' do
|
757
719
|
it 'should split inline table cells into block table cells' do
|
758
720
|
text = <<EOS
|
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: slaw
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Greg Kempe
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-03-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: bundler
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '1.5'
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '1.5'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: rake
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -122,34 +108,6 @@ dependencies:
|
|
122
108
|
- - "~>"
|
123
109
|
- !ruby/object:Gem::Version
|
124
110
|
version: 0.2.1
|
125
|
-
- !ruby/object:Gem::Dependency
|
126
|
-
name: yomu
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
128
|
-
requirements:
|
129
|
-
- - "~>"
|
130
|
-
- !ruby/object:Gem::Version
|
131
|
-
version: 0.2.2
|
132
|
-
type: :runtime
|
133
|
-
prerelease: false
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
135
|
-
requirements:
|
136
|
-
- - "~>"
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
version: 0.2.2
|
139
|
-
- !ruby/object:Gem::Dependency
|
140
|
-
name: twitter-text
|
141
|
-
requirement: !ruby/object:Gem::Requirement
|
142
|
-
requirements:
|
143
|
-
- - "~>"
|
144
|
-
- !ruby/object:Gem::Version
|
145
|
-
version: 1.12.0
|
146
|
-
type: :runtime
|
147
|
-
prerelease: false
|
148
|
-
version_requirements: !ruby/object:Gem::Requirement
|
149
|
-
requirements:
|
150
|
-
- - "~>"
|
151
|
-
- !ruby/object:Gem::Version
|
152
|
-
version: 1.12.0
|
153
111
|
description: Slaw is a lightweight library for rendering and generating Akoma Ntoso
|
154
112
|
acts from plain text and PDF documents.
|
155
113
|
email:
|
@@ -169,7 +127,6 @@ files:
|
|
169
127
|
- lib/slaw.rb
|
170
128
|
- lib/slaw/extract/extractor.rb
|
171
129
|
- lib/slaw/extract/html_to_akn_text.xsl
|
172
|
-
- lib/slaw/extract/yomu_patch.rb
|
173
130
|
- lib/slaw/generator.rb
|
174
131
|
- lib/slaw/grammars/core_nodes.rb
|
175
132
|
- lib/slaw/grammars/inlines.treetop
|