notroff 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/notroff +47 -0
- data/lib/notroff/code_scrubber.rb +9 -0
- data/lib/notroff/code_typer.rb +37 -0
- data/lib/notroff/command_processor.rb +28 -0
- data/lib/notroff/composite_processor.rb +52 -0
- data/lib/notroff/content.xml.erb +110 -0
- data/lib/notroff/docbook_renderer.rb +155 -0
- data/lib/notroff/embedded.rb +132 -0
- data/lib/notroff/filter.rb +15 -0
- data/lib/notroff/formatter.rb +54 -0
- data/lib/notroff/html_renderer.rb +92 -0
- data/lib/notroff/io.rb +18 -0
- data/lib/notroff/logger.rb +13 -0
- data/lib/notroff/odt_renderer.rb +154 -0
- data/lib/notroff/odt_replacer.rb +22 -0
- data/lib/notroff/paragraph_joiner.rb +53 -0
- data/lib/notroff/processor.rb +192 -0
- data/lib/notroff/skel.odt +0 -0
- data/lib/notroff/string_extensions.rb +6 -0
- data/lib/notroff/template_expander.rb +15 -0
- data/lib/notroff/text.rb +67 -0
- data/lib/notroff/text_replacer.rb +65 -0
- data/lib/notroff/tokenize.rb +64 -0
- data/lib/notroff/type_assigner.rb +25 -0
- data/lib/notroff.rb +23 -0
- data/readme.nr +58 -0
- data/spec/command_processor_spec.rb +15 -0
- data/spec/composite_processor_spec.rb +35 -0
- data/spec/filter_spec.rb +16 -0
- data/spec/formatter_spec.rb +22 -0
- data/spec/hello.rb +1 -0
- data/spec/hello.rb.out +1 -0
- data/spec/paragraph_joiner_spec.rb +26 -0
- data/spec/simple.nr +3 -0
- data/spec/string_extensions_spec.rb +22 -0
- data/spec/text_spec.rb +55 -0
- data/spec/type_assigner_spec.rb +39 -0
- data/spec/with_commands.nr +6 -0
- metadata +83 -0
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'rexml/document'
|
2
|
+
|
3
|
+
module Tokenize
|
4
|
+
def tokenize_body_text( text )
|
5
|
+
text = text.dup
|
6
|
+
re = /\~\~.*?\~\~|\@\@.*?\@\@+|\{\{.*?\}\}|!!.*?!!/
|
7
|
+
results = []
|
8
|
+
until text.empty?
|
9
|
+
match = re.match( text )
|
10
|
+
if match.nil?
|
11
|
+
results << Text.new(text, :type=>:normal)
|
12
|
+
text = ''
|
13
|
+
else
|
14
|
+
unless match.pre_match.empty?
|
15
|
+
results << Text.new(match.pre_match, :type=>:normal)
|
16
|
+
end
|
17
|
+
token = match.to_s
|
18
|
+
results << Text.new(token_text(token), :type=>token_type(token))
|
19
|
+
text = match.post_match
|
20
|
+
end
|
21
|
+
end
|
22
|
+
results
|
23
|
+
end
|
24
|
+
|
25
|
+
def token_type( token )
|
26
|
+
case token
|
27
|
+
when /^\~/
|
28
|
+
:italic
|
29
|
+
when /^\@/
|
30
|
+
:code
|
31
|
+
when /^\{/
|
32
|
+
:footnote
|
33
|
+
when /^!/
|
34
|
+
:bold
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def token_text( token )
|
39
|
+
result = token.sub( /^../, '' ).sub( /..$/, '')
|
40
|
+
#print "token text for #{token} [[#{result}]]"
|
41
|
+
result
|
42
|
+
end
|
43
|
+
|
44
|
+
def remove_escapes( text )
|
45
|
+
text = text.clone
|
46
|
+
|
47
|
+
results = ''
|
48
|
+
|
49
|
+
until text.empty?
|
50
|
+
match = /\\(.)/.match( text )
|
51
|
+
if match.nil?
|
52
|
+
results << text
|
53
|
+
text = ''
|
54
|
+
else
|
55
|
+
unless match.pre_match.empty?
|
56
|
+
results << match.pre_match
|
57
|
+
end
|
58
|
+
results << match[1]
|
59
|
+
text = match.post_match
|
60
|
+
end
|
61
|
+
end
|
62
|
+
results
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class TypeAssigner
|
2
|
+
def process( paragraphs )
|
3
|
+
processed_paragraphs = []
|
4
|
+
|
5
|
+
current_type = :body
|
6
|
+
|
7
|
+
paragraphs.each do |paragraph|
|
8
|
+
type = paragraph[:type]
|
9
|
+
if (type == :body) or (type == :code) or (type == :quote)
|
10
|
+
current_type = type
|
11
|
+
elsif type == :code1
|
12
|
+
paragraph[:type] = :code
|
13
|
+
processed_paragraphs << paragraph
|
14
|
+
elsif type == :text
|
15
|
+
paragraph[:type] = current_type
|
16
|
+
processed_paragraphs << paragraph
|
17
|
+
else
|
18
|
+
processed_paragraphs << paragraph
|
19
|
+
end
|
20
|
+
|
21
|
+
current_type = :body if [ :section, :title, :code1 ].include?(type)
|
22
|
+
end
|
23
|
+
processed_paragraphs
|
24
|
+
end
|
25
|
+
end
|
data/lib/notroff.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
Verbose = false unless defined?(Verbose)
|
2
|
+
|
3
|
+
require "notroff/logger"
|
4
|
+
require "notroff/string_extensions"
|
5
|
+
require "notroff/text"
|
6
|
+
require "notroff/io"
|
7
|
+
require "notroff/filter"
|
8
|
+
require "notroff/code_scrubber"
|
9
|
+
require "notroff/embedded"
|
10
|
+
require "notroff/paragraph_joiner"
|
11
|
+
require "notroff/type_assigner"
|
12
|
+
require "notroff/processor"
|
13
|
+
require "notroff/command_processor"
|
14
|
+
require "notroff/composite_processor"
|
15
|
+
require "notroff/tokenize"
|
16
|
+
require "notroff/html_renderer"
|
17
|
+
require "notroff/docbook_renderer"
|
18
|
+
require "notroff/odt_renderer"
|
19
|
+
require "notroff/odt_replacer"
|
20
|
+
require "notroff/template_expander"
|
21
|
+
require "notroff/code_typer"
|
22
|
+
require "notroff/formatter"
|
23
|
+
require "notroff/filter"
|
data/readme.nr
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
NotRoff Text Formatter
|
2
|
+
========
|
3
|
+
|
4
|
+
NotRoff is a simple plain text file format that allows you to embed all sort of styling, including fixed width, italics and bold into your work using plain text markers. The included notroff program will turn the plain text into an Open Office .odt document. I used NotRoff to format Eloquent Ruby.
|
5
|
+
|
6
|
+
Creating plain text in notroff is very easy -- you just write each paragraph in its own line, separated by blank lines. You can add styling to your text with simple tags: words surrounded by !! become bold, while ~~ tags italics and @@ tags code, for example like this:
|
7
|
+
|
8
|
+
!!This!! is bold, but ~~this~~ is italics and @@all of this@@ looks like code.
|
9
|
+
|
10
|
+
To do fancier stuff there are also dot commands. Each dot command starts with a period, followed by the name of the command, and then -- for most dot commands -- an argument or two. For example, there is a dot command for creating section headers:
|
11
|
+
|
12
|
+
.section NotRoff Includes Section Headers
|
13
|
+
|
14
|
+
There is also a dot command to include some program code from a source code into your final document:
|
15
|
+
|
16
|
+
.inc gutted_doc.rb
|
17
|
+
|
18
|
+
Frequently you don't want the whole file, just a chunk of it. To do that, you can add a second argument to your .inc command, a !!tag!! which will pick out a tagged section of the file. Here's what a .inc command with a tag looks like:
|
19
|
+
|
20
|
+
.inc ex_lazy_document.rb base_doc
|
21
|
+
|
22
|
+
And here is what the corresponding source file looks like:
|
23
|
+
|
24
|
+
.code
|
25
|
+
# This comment is not included in the .odt file
|
26
|
+
|
27
|
+
puts "first included line" ##(base_doc
|
28
|
+
puts "also included"
|
29
|
+
puts "last included line" ##base_doc)
|
30
|
+
.body
|
31
|
+
|
32
|
+
There is a short cut if you want to include a single line from your source file -- Just tag it with ##+tag, like this:
|
33
|
+
|
34
|
+
open_file = File.open( '/etc/passwd' ) ##+open
|
35
|
+
|
36
|
+
You can also explicitly exclude a line with ##--tag.
|
37
|
+
|
38
|
+
One of the problems with including code into text is that the indentation is frequently wrong: The code wants to have indentation that makes sense within the larger program which sometimes looks bad in the text. To deal with this, the .inc command lets you specify a 3rd parameter, the number of spaces that you want to set the indentation to:
|
39
|
+
|
40
|
+
.c1 .inc type_check_spec.rb bad_type 2
|
41
|
+
|
42
|
+
Along with pulling code from a file, you can also include single lines of code directly into the NotRoff file:
|
43
|
+
|
44
|
+
.c1 doc = get_some_kind_of_document
|
45
|
+
|
46
|
+
Or multiple lines of code:
|
47
|
+
|
48
|
+
.code
|
49
|
+
puts "Title: #{doc.title}"
|
50
|
+
puts "Author: #{doc.author}"
|
51
|
+
puts "Content: #{doc.content}"
|
52
|
+
.body
|
53
|
+
|
54
|
+
Using notroff is simple: Just run the notroff script, supplying the path to the plain text file as the first argument and the path to your new OpenOffice .odt file as the second:
|
55
|
+
|
56
|
+
.c1 notroff example.nr example.odt
|
57
|
+
|
58
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
describe CommandProcessor do
|
2
|
+
let(:cp) { CommandProcessor.new }
|
3
|
+
|
4
|
+
it 'should turn a plain line of text into a .text command' do
|
5
|
+
lines = [ 'line 1', 'line 2' ]
|
6
|
+
new_lines = cp.process(lines)
|
7
|
+
new_lines.size.should == 2
|
8
|
+
new_lines[0].string.should == 'line 1'
|
9
|
+
new_lines[1].string.should == 'line 2'
|
10
|
+
new_lines[0][:type].should == :text
|
11
|
+
new_lines[1][:type].should == :text
|
12
|
+
new_lines[0][:original_text].should == 'line 1'
|
13
|
+
new_lines[1][:original_text].should == 'line 2'
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class PUp
|
2
|
+
def process(paras)
|
3
|
+
paras.map {|p| p.upcase}
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
class PDown
|
8
|
+
def process(paras)
|
9
|
+
paras.map {|p| p.downcase}
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe CompositeProcessor do
|
14
|
+
let(:cp) { CompositeProcessor.new() }
|
15
|
+
|
16
|
+
let(:paras) { %W{ para1 para2 para3 } }
|
17
|
+
|
18
|
+
it 'should do nothing with no processors' do
|
19
|
+
new_paras = CompositeProcessor.new.process(paras)
|
20
|
+
new_paras.should == %W{ para1 para2 para3 }
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should work like a single processor with one subprocessor' do
|
24
|
+
cp.add_processor(PUp.new)
|
25
|
+
new_paras = cp.process(paras)
|
26
|
+
new_paras.should == %W{ PARA1 PARA2 PARA3 }
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should apply several processors in turn' do
|
30
|
+
cp.add_processor(PUp.new)
|
31
|
+
cp.add_processor(PDown.new)
|
32
|
+
new_paras = cp.process(paras)
|
33
|
+
new_paras.should == %W{ para1 para2 para3 }
|
34
|
+
end
|
35
|
+
end
|
data/spec/filter_spec.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
describe IncludedFilter do
|
2
|
+
let(:filter) { IncludedFilter.new }
|
3
|
+
|
4
|
+
let(:paras) do
|
5
|
+
paras = %W{ para1 para2 para3 para4 para5}
|
6
|
+
paras.map {|p| Text.new(p) }
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should filter out paras that dont have the included tag' do
|
10
|
+
paras[1][:included] = paras[3][:included] = true
|
11
|
+
new_paras = filter.process(paras)
|
12
|
+
new_paras.size.should == 2
|
13
|
+
new_paras[0].string.should == 'para2'
|
14
|
+
new_paras[1].string.should == 'para4'
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
describe Formatter do
|
2
|
+
let(:formatter) { Formatter.new }
|
3
|
+
|
4
|
+
let(:text_paras) { %W{ para1 para2 para3 para4 para5} }
|
5
|
+
|
6
|
+
it 'should turn join a series of text paragraphs into a single body' do
|
7
|
+
new_paras = formatter.process(text_paras)
|
8
|
+
new_paras.size.should == 1
|
9
|
+
new_paras[0][:type].should == :body
|
10
|
+
new_paras[0].string.should == "para1 para2 para3 para4 para5"
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should deal with sticky commands' do
|
14
|
+
new_paras = formatter.process( %W{body1 .code code1 code2 .body body2} )
|
15
|
+
pp new_paras
|
16
|
+
new_paras.size.should == 4
|
17
|
+
new_paras[0][:type].should == :body
|
18
|
+
new_paras[1][:type].should == :code
|
19
|
+
new_paras[2][:type].should == :code
|
20
|
+
new_paras[3][:type].should == :body
|
21
|
+
end
|
22
|
+
end
|
data/spec/hello.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
puts "hello ruby"
|
data/spec/hello.rb.out
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
hello ruby
|
@@ -0,0 +1,26 @@
|
|
1
|
+
describe BodyParagraphJoiner do
|
2
|
+
let(:pj) { BodyParagraphJoiner.new(:body) }
|
3
|
+
|
4
|
+
let(:paras) do
|
5
|
+
paras = %W{ para1 para2 para3 para4 para5}
|
6
|
+
paras.map {|p| Text.new(p, :type => :body) }
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should turn join a series of similar paragraphs together' do
|
10
|
+
new_paras = pj.process(paras)
|
11
|
+
new_paras.size.should == 1
|
12
|
+
new_paras[0][:type].should == :body
|
13
|
+
new_paras[0].string.should == "para1 para2 para3 para4 para5"
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should turn stop joining on an empty paragraph' do
|
17
|
+
paras[2].string = ''
|
18
|
+
new_paras = pj.process(paras)
|
19
|
+
pp new_paras
|
20
|
+
new_paras.size.should == 2
|
21
|
+
new_paras[0][:type].should == :body
|
22
|
+
new_paras[0].string.should == "para1 para2"
|
23
|
+
new_paras[1][:type].should == :body
|
24
|
+
new_paras[1].string.should == "para4 para5"
|
25
|
+
end
|
26
|
+
end
|
data/spec/simple.nr
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
describe String do
|
2
|
+
it 'should let you turn a string into a Text' do
|
3
|
+
t = 'abc'.to_text
|
4
|
+
t.class.should == Text
|
5
|
+
t.string.should == 'abc'
|
6
|
+
t.attrs.should == {}
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should still have a working ==' do
|
10
|
+
s = 'abc'
|
11
|
+
s.should == 'abc'
|
12
|
+
s.should_not == 'xxx'
|
13
|
+
s.should_not == 123
|
14
|
+
s.should_not == nil
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should be == to Text instances with the same string' do
|
18
|
+
s = 'abc'
|
19
|
+
s.should == Text.new('abc')
|
20
|
+
s.should_not == Text.new('xxx')
|
21
|
+
end
|
22
|
+
end
|
data/spec/text_spec.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
describe Text do
|
2
|
+
let(:t) { Text.new('abc') }
|
3
|
+
|
4
|
+
it 'should be creatable with a string and an attr hash' do
|
5
|
+
text = Text.new('abc', :name => 'russ')
|
6
|
+
text.string.should == 'abc'
|
7
|
+
text.attrs.should == {:name => 'russ'}
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'should provide access to the original string' do
|
11
|
+
t.string.should == 'abc'
|
12
|
+
t.string.class.should == String
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should have a size method like a string' do
|
16
|
+
t.size.should == 3
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should support a sub method which should return a Text' do
|
20
|
+
new_t = t.sub('b', 'B')
|
21
|
+
new_t.class.should == Text
|
22
|
+
new_t.string.should == 'aBc'
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should return attributes when you do arithmetic' do
|
26
|
+
t[:name] = 'russ'
|
27
|
+
new_t = t + "xxx"
|
28
|
+
new_t[:name].should == 'russ'
|
29
|
+
new_t.string.should == 'abcxxx'
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should support setting and getting attrs via the attrs method' do
|
33
|
+
t.attrs[:name] = 'russ'
|
34
|
+
t.attrs[:name].should == 'russ'
|
35
|
+
t.attrs.should == { :name => 'russ' }
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should support setting and getting attrs via subscripting' do
|
39
|
+
t[:name] = 'russ'
|
40
|
+
t[:name].should == 'russ'
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should take attrs into account in ==' do
|
44
|
+
t_new = Text.new('abc')
|
45
|
+
t_new[:name] = 'russ'
|
46
|
+
t[:name] = 'russ'
|
47
|
+
|
48
|
+
t.should == t_new
|
49
|
+
|
50
|
+
t_new[:name] = 'bob'
|
51
|
+
puts "T class: #{t.class}"
|
52
|
+
puts "Tnew class: #{t_new.class}"
|
53
|
+
t.should_not == t_new
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
describe TypeAssigner do
|
2
|
+
let(:ta) { TypeAssigner.new }
|
3
|
+
let(:paras) do
|
4
|
+
paras = %W{ para1 para2 para3 para4 para5}
|
5
|
+
paras.map {|p| Text.new(p, :type => :text) }
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'should turn plain text paras into body paras' do
|
9
|
+
new_paras = ta.process(paras)
|
10
|
+
new_paras.each {|p| p[:type].should == :body}
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should make .code commands sticky while droping the code command' do
|
14
|
+
paras[0] = Text.new( '', :type => :code)
|
15
|
+
new_paras = ta.process(paras)
|
16
|
+
new_paras.size.should == 4
|
17
|
+
new_paras.each {|p| p[:type].should == :code}
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should make switch between .code and .body commands' do
|
21
|
+
paras[0] = Text.new( '', :type => :code)
|
22
|
+
paras[3] = Text.new( '', :type => :body)
|
23
|
+
new_paras = ta.process(paras)
|
24
|
+
new_paras.size.should == 3
|
25
|
+
new_paras[0][:type].should == :code
|
26
|
+
new_paras[1][:type].should == :code
|
27
|
+
new_paras[2][:type].should == :body
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should know that section and code1 are automatically followed by body' do
|
31
|
+
paras[0] = Text.new( 'section!', :type => :sec)
|
32
|
+
paras[2] = Text.new( 'code1!', :type => :code1)
|
33
|
+
new_paras = ta.process(paras)
|
34
|
+
new_paras[0][:type].should == :sec
|
35
|
+
new_paras[1][:type].should == :body
|
36
|
+
new_paras[2][:type].should == :code
|
37
|
+
new_paras[3][:type].should == :body
|
38
|
+
end
|
39
|
+
end
|
metadata
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: notroff
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Russ Olsen
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-01-15 00:00:00.000000000Z
|
13
|
+
dependencies: []
|
14
|
+
description: NotRoff A simple text to openoffice filter
|
15
|
+
email: russ@russolsen.com
|
16
|
+
executables:
|
17
|
+
- notroff
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- readme.nr
|
22
|
+
- spec/command_processor_spec.rb
|
23
|
+
- spec/composite_processor_spec.rb
|
24
|
+
- spec/filter_spec.rb
|
25
|
+
- spec/formatter_spec.rb
|
26
|
+
- spec/hello.rb
|
27
|
+
- spec/hello.rb.out
|
28
|
+
- spec/paragraph_joiner_spec.rb
|
29
|
+
- spec/simple.nr
|
30
|
+
- spec/string_extensions_spec.rb
|
31
|
+
- spec/text_spec.rb
|
32
|
+
- spec/type_assigner_spec.rb
|
33
|
+
- spec/with_commands.nr
|
34
|
+
- lib/notroff/code_scrubber.rb
|
35
|
+
- lib/notroff/code_typer.rb
|
36
|
+
- lib/notroff/command_processor.rb
|
37
|
+
- lib/notroff/composite_processor.rb
|
38
|
+
- lib/notroff/content.xml.erb
|
39
|
+
- lib/notroff/docbook_renderer.rb
|
40
|
+
- lib/notroff/embedded.rb
|
41
|
+
- lib/notroff/filter.rb
|
42
|
+
- lib/notroff/formatter.rb
|
43
|
+
- lib/notroff/html_renderer.rb
|
44
|
+
- lib/notroff/io.rb
|
45
|
+
- lib/notroff/logger.rb
|
46
|
+
- lib/notroff/odt_renderer.rb
|
47
|
+
- lib/notroff/odt_replacer.rb
|
48
|
+
- lib/notroff/paragraph_joiner.rb
|
49
|
+
- lib/notroff/processor.rb
|
50
|
+
- lib/notroff/skel.odt
|
51
|
+
- lib/notroff/string_extensions.rb
|
52
|
+
- lib/notroff/template_expander.rb
|
53
|
+
- lib/notroff/text.rb
|
54
|
+
- lib/notroff/text_replacer.rb
|
55
|
+
- lib/notroff/tokenize.rb
|
56
|
+
- lib/notroff/type_assigner.rb
|
57
|
+
- lib/notroff.rb
|
58
|
+
- bin/notroff
|
59
|
+
homepage: http://www.russolsen.com
|
60
|
+
licenses: []
|
61
|
+
post_install_message:
|
62
|
+
rdoc_options: []
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ! '>='
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
requirements: []
|
78
|
+
rubyforge_project:
|
79
|
+
rubygems_version: 1.8.10
|
80
|
+
signing_key:
|
81
|
+
specification_version: 3
|
82
|
+
summary: NotRoff A simple text to openoffice filter
|
83
|
+
test_files: []
|