docgenerator 0.1.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/examples/docgenerator_example.rb +76 -160
- data/examples/docgenerator_example_footnote.rb +98 -0
- data/examples/docgenerator_example_list.rb +62 -0
- data/examples/docgenerator_example_restrictions.rb +59 -0
- data/examples/docgenerator_example_tabular.rb +68 -0
- data/examples/docgenerator_example_tripfalls.rb +57 -0
- data/examples/wiki2docgenerator_example.rb +270 -0
- data/lib/docgenerator.rb +159 -0
- data/{docgenerator_attribute.rb → lib/docgenerator_attribute.rb} +32 -7
- data/{docgenerator_characters.rb → lib/docgenerator_characters.rb} +15 -0
- data/{docgenerator_css.rb → lib/docgenerator_css.rb} +6 -1
- data/{docgenerator_document.rb → lib/docgenerator_document.rb} +92 -93
- data/{docgenerator_element.rb → lib/docgenerator_element.rb} +125 -51
- data/{docgenerator_elements.rb → lib/docgenerator_elements.rb} +40 -56
- data/{docgenerator_environments.rb → lib/docgenerator_environments.rb} +16 -10
- data/{docgenerator_footnote.rb → lib/docgenerator_footnote.rb} +44 -22
- data/{docgenerator_lists.rb → lib/docgenerator_lists.rb} +44 -39
- data/{docgenerator_sections.rb → lib/docgenerator_sections.rb} +2 -2
- data/{docgenerator_tabular.rb → lib/docgenerator_tabular.rb} +71 -39
- data/{packages → lib/packages}/docgenerator_attachfile.rb +0 -0
- data/{packages → lib/packages}/docgenerator_caption.rb +0 -0
- data/{packages → lib/packages}/docgenerator_hyperref.rb +0 -0
- data/{packages → lib/packages}/docgenerator_listings.rb +1 -2
- data/{packages → lib/packages}/docgenerator_pdfpages.rb +0 -0
- data/{packages → lib/packages}/docgenerator_scrlettr2.rb +2 -2
- data/{packages → lib/packages}/docgenerator_scrpage2.rb +0 -0
- data/{packages → lib/packages}/docgenerator_url.rb +0 -0
- data/lib/templates/docgenerator_template.rb +176 -0
- data/lib/templates/docgenerator_template.yaml +105 -0
- data/lib/wiki2doc/wiki2docgenerator.rb +1161 -0
- data/self_docgenerator.rb +161 -0
- data/unittest/expected/test_beamer_note.html +1 -0
- data/unittest/expected/test_beamer_note.latex +1 -0
- data/unittest/expected/test_beamer_note.text +1 -0
- data/unittest/expected/test_beamer_note.wiki +1 -0
- data/unittest/expected/test_block.html +1 -0
- data/unittest/expected/test_block.latex +1 -0
- data/unittest/expected/test_block.text +1 -0
- data/unittest/expected/test_block.wiki +2 -0
- data/unittest/expected/test_css.css +1 -0
- data/unittest/expected/test_css2.css +1 -0
- data/unittest/expected/test_description.html +1 -0
- data/unittest/expected/test_description.latex +3 -0
- data/unittest/expected/test_description.text +3 -0
- data/unittest/expected/test_description.wiki +3 -0
- data/unittest/expected/test_document_article.latex +23 -0
- data/unittest/expected/test_document_html.html +14 -0
- data/unittest/expected/test_document_replacement_article.latex +23 -0
- data/unittest/expected/test_document_replacement_html.html +14 -0
- data/unittest/expected/test_document_replacement_text.text +5 -0
- data/unittest/expected/test_document_replacement_wiki.wiki +5 -0
- data/unittest/expected/test_document_text.text +5 -0
- data/unittest/expected/test_document_wiki.wiki +5 -0
- data/unittest/expected/test_enumerate.html +1 -0
- data/unittest/expected/test_enumerate.latex +3 -0
- data/unittest/expected/test_enumerate.text +1 -0
- data/unittest/expected/test_enumerate.wiki +2 -0
- data/unittest/expected/test_footnote.html +5 -0
- data/unittest/expected/test_footnote.latex +11 -0
- data/unittest/expected/test_footnote.text +13 -0
- data/unittest/expected/test_footnote.wiki +11 -0
- data/unittest/expected/test_footnote_group.html +8 -0
- data/unittest/expected/test_footnote_group.latex +17 -0
- data/unittest/expected/test_footnote_group.wiki +17 -0
- data/unittest/expected/test_href.html +2 -0
- data/unittest/expected/test_href.latex +8 -0
- data/unittest/expected/test_href.text +4 -0
- data/unittest/expected/test_html_css.html +1 -0
- data/unittest/expected/test_itemize.html +1 -0
- data/unittest/expected/test_itemize.latex +3 -0
- data/unittest/expected/test_itemize.text +1 -0
- data/unittest/expected/test_itemize.wiki +2 -0
- data/unittest/expected/test_section.html +8 -0
- data/unittest/expected/test_section.latex +20 -0
- data/unittest/expected/test_section.text +24 -0
- data/unittest/expected/test_section.wiki +20 -0
- data/unittest/expected/test_tabular.html +10 -0
- data/unittest/expected/test_tabular.latex +10 -0
- data/unittest/expected/test_tabular.wiki +31 -0
- data/unittest/expected/test_tabular_doc.latex +22 -0
- data/unittest/expected/test_wiki.html +6 -0
- data/unittest/expected/test_wiki.latex +12 -0
- data/unittest/expected/test_wiki.text +14 -0
- data/unittest/expected/test_wiki.wiki +12 -0
- data/unittest/expected/test_wiki_amazon.html +10 -0
- data/unittest/expected/test_wiki_description.html +7 -0
- data/unittest/expected/test_wiki_description.latex +11 -0
- data/unittest/expected/test_wiki_description.text +6 -0
- data/unittest/expected/test_wiki_description.wiki +6 -0
- data/unittest/expected/test_wiki_footnote.html +8 -0
- data/unittest/expected/test_wiki_footnote.latex +15 -0
- data/unittest/expected/test_wiki_footnote.text +12 -0
- data/unittest/expected/test_wiki_footnote.wiki +12 -0
- data/unittest/expected/test_wiki_footnote_groupid.html +21 -0
- data/unittest/expected/test_wiki_html_code.html +7 -0
- data/unittest/expected/test_wiki_html_code.latex +10 -0
- data/unittest/expected/test_wiki_html_code.text +6 -0
- data/unittest/expected/test_wiki_html_code.wiki +6 -0
- data/unittest/expected/test_wiki_inline.html +6 -0
- data/unittest/expected/test_wiki_inline.latex +12 -0
- data/unittest/expected/test_wiki_inline.text +8 -0
- data/unittest/expected/test_wiki_inline.wiki +8 -0
- data/unittest/expected/test_wiki_label.html +6 -0
- data/unittest/expected/test_wiki_link.html +8 -0
- data/unittest/expected/test_wiki_link.latex +14 -0
- data/unittest/expected/test_wiki_link.log +3 -0
- data/unittest/expected/test_wiki_link.wiki +6 -0
- data/unittest/expected/test_wiki_list_ol.html +24 -0
- data/unittest/expected/test_wiki_list_ol.latex +30 -0
- data/unittest/expected/test_wiki_list_ol.text +10 -0
- data/unittest/expected/test_wiki_list_ol.wiki +12 -0
- data/unittest/expected/test_wiki_list_ol_after_ul.html +16 -0
- data/unittest/expected/test_wiki_list_ol_after_ul.latex +24 -0
- data/unittest/expected/test_wiki_list_ol_after_ul.text +8 -0
- data/unittest/expected/test_wiki_list_ol_after_ul.wiki +10 -0
- data/unittest/expected/test_wiki_list_ol_ul.html +24 -0
- data/unittest/expected/test_wiki_list_ol_ul.latex +30 -0
- data/unittest/expected/test_wiki_list_ol_ul.text +10 -0
- data/unittest/expected/test_wiki_list_ol_ul.wiki +12 -0
- data/unittest/expected/test_wiki_list_ul.html +24 -0
- data/unittest/expected/test_wiki_list_ul.latex +30 -0
- data/unittest/expected/test_wiki_list_ul.text +10 -0
- data/unittest/expected/test_wiki_list_ul.wiki +12 -0
- data/unittest/expected/test_wiki_list_ul_too_much.html +39 -0
- data/unittest/expected/test_wiki_list_ul_too_much.latex +51 -0
- data/unittest/expected/test_wiki_list_ul_too_much.text +11 -0
- data/unittest/expected/test_wiki_list_ul_too_much.wiki +15 -0
- data/unittest/expected/test_wiki_picture.html +55 -0
- data/unittest/expected/test_wiki_picture.latex +76 -0
- data/unittest/expected/test_wiki_picture_thumb.html +5 -0
- data/unittest/expected/test_wiki_tab1.html +30 -0
- data/unittest/expected/test_wiki_tab1.latex +30 -0
- data/unittest/expected/test_wiki_tab1.wiki +29 -0
- data/unittest/expected/test_wiki_textformatting.html +7 -0
- data/unittest/expected/test_wiki_textformatting.latex +16 -0
- data/unittest/expected/test_wiki_textformatting.text +11 -0
- data/unittest/expected/test_wiki_textformatting.wiki +9 -0
- data/unittest/expected/test_wiki_toc.html +9 -0
- data/unittest/expected/test_wiki_toc.latex +18 -0
- data/unittest/expected/test_wiki_toc.text +21 -0
- data/unittest/expected/test_wiki_toc.wiki +18 -0
- data/unittest/expected/test_wiki_ul_multiple_line.html +18 -0
- data/unittest/expected/test_wiki_ul_multiple_line.latex +19 -0
- data/unittest/expected/test_wiki_ul_multiple_line.text +6 -0
- data/unittest/expected/test_wiki_ul_multiple_line.wiki +7 -0
- data/unittest/test_docgenerator.rb +85 -0
- data/unittest/unittest_docgenerator.rb +454 -0
- data/unittest/unittest_wiki2doc.rb +451 -0
- metadata +155 -31
- data/docgenerator.rb +0 -137
- data/docgenerator_template.rb +0 -103
- data/packages/docgenerator_beamer.rb +0 -250
@@ -1,6 +1,5 @@
|
|
1
1
|
#Administrate attributes for elements.
|
2
2
|
class Attribute
|
3
|
-
include Backlinks
|
4
3
|
@@settings = {}
|
5
4
|
@@values = {}
|
6
5
|
@@sortkey = 99 #Just a counter to get identic positions between different program runs.
|
@@ -115,7 +114,6 @@ class Attribute
|
|
115
114
|
if ! self.allowed?( value )
|
116
115
|
puts "Attribute #{@name}: Illegal value #{value.inspect} in #{@element.inspect}"
|
117
116
|
end
|
118
|
-
set_backlink( value )
|
119
117
|
if unique? and @attr_content.size > 0
|
120
118
|
puts "Attribute #{@name}: More then one value added (#{value}) in #{@element.inspect}"
|
121
119
|
return self
|
@@ -129,14 +127,41 @@ class Attribute
|
|
129
127
|
#Return the content.
|
130
128
|
def to_s()
|
131
129
|
#~ def to_s( target = Document.target( self ) )
|
132
|
-
#list of documents, where this element is part of (normaly only one element)
|
133
|
-
if @part_of_doc.size == 0
|
134
|
-
@part_of_doc = @element.part_of_doc
|
135
|
-
set_backlink( @attr_content )
|
136
|
-
end
|
137
130
|
@attr_content.to_s()
|
138
131
|
end
|
139
132
|
def inspect()
|
140
133
|
return "<#Attribute #{@name} #{@attr_content.inspect} (in #{@element.ids}) >"
|
141
134
|
end
|
142
135
|
end
|
136
|
+
|
137
|
+
#Definition of HTML-Tags (Sublasses of Element).
|
138
|
+
ATTR_LANG = Attribute.create( [ :html ], ['en', 'de'] )
|
139
|
+
#
|
140
|
+
HTML_ATTR_CORE = {
|
141
|
+
:id => Attribute.create( [ :html ] ),
|
142
|
+
:class => Attribute.create( [ :html ] ),
|
143
|
+
:style => Attribute.create( [ :html ], [CSS, String]), #fixm string raus
|
144
|
+
#~ :name => Attribute.create( [ :html ] ),
|
145
|
+
:title => Attribute.create( [ :html ] ) }
|
146
|
+
HTML_ATTR_I18N = {
|
147
|
+
:lang => ATTR_LANG,
|
148
|
+
:dir => Attribute.create( [ :html ], ['ltr', 'rtl'] )
|
149
|
+
}
|
150
|
+
HTML_ATTR_EVENTS = { :onclick => Attribute.create( [ :html ] ),
|
151
|
+
:ondblclick => Attribute.create( [ :html ] ),
|
152
|
+
:onmousedown => Attribute.create( [ :html ] ),
|
153
|
+
:onmouseup => Attribute.create( [ :html ] ),
|
154
|
+
:onmouseover => Attribute.create( [ :html ] ),
|
155
|
+
:onmousemove => Attribute.create( [ :html ] ),
|
156
|
+
:onmouseout => Attribute.create( [ :html ] ),
|
157
|
+
:onkeypress => Attribute.create( [ :html ] ),
|
158
|
+
:onkeyup => Attribute.create( [ :html ] ),
|
159
|
+
:onkeydown => Attribute.create( [ :html ] )
|
160
|
+
}
|
161
|
+
HTML_ATTR_ALL = {}
|
162
|
+
HTML_ATTR_ALL.update(HTML_ATTR_I18N)
|
163
|
+
HTML_ATTR_ALL.update(HTML_ATTR_EVENTS)
|
164
|
+
HTML_ATTR_ALL.update(HTML_ATTR_CORE)
|
165
|
+
|
166
|
+
HTML_ATTR_ALIGN = Attribute.create( [ :html ], ['left', 'center', 'right', 'justify', 'char'] )
|
167
|
+
HTML_ATTR_VALIGN = Attribute.create( [ :html ], ['bottom', 'top', 'middle', 'baseline'] )
|
@@ -1,3 +1,18 @@
|
|
1
|
+
#Some Coding to prepare the unit tests
|
2
|
+
#~ els = nil
|
3
|
+
#~ DATA.each{|line|
|
4
|
+
#~ case line
|
5
|
+
#~ when /\A\s*#/ #skip
|
6
|
+
#~ when /Element.create\( \[(.*)\]/
|
7
|
+
#~ els = $1.split(',').map{|el| el.strip }
|
8
|
+
#~ when /:(html|latex|wiki|text)\s*=>\s*'(.+?)'/
|
9
|
+
#~ els.each{|el|
|
10
|
+
#~ puts " assert_equal( '#{$2}', element(#{el}).to_#{$1})"
|
11
|
+
#~ }
|
12
|
+
#~ end
|
13
|
+
#~ }
|
14
|
+
|
15
|
+
#~ __END__
|
1
16
|
#
|
2
17
|
# Special Characters
|
3
18
|
#
|
@@ -14,9 +14,13 @@ class Style < Element
|
|
14
14
|
Element.add( [:style], self)
|
15
15
|
#~ add_attributes( HTML_ATTR_ALL )
|
16
16
|
add_output( :latex, '')
|
17
|
+
add_output( :text, '')
|
18
|
+
add_output( :wiki, '')
|
17
19
|
#Prepare HTML-Output for Style-Tag.
|
18
20
|
#The values can be overwritten, if different CSS-Elements are inside.
|
19
|
-
def to_html()
|
21
|
+
def to_html( options = {} )
|
22
|
+
o = Docgenerator_logger.set_option_defaults(options)
|
23
|
+
o[:log].debug("Enter style.to_html") if o[:log].debug?
|
20
24
|
res = ""
|
21
25
|
res << "\n" if @crbefore
|
22
26
|
res << "<style type=\"text/css\">\n"
|
@@ -62,6 +66,7 @@ class CSS
|
|
62
66
|
'text-decoration' => ['underline', 'overline', 'line-through', 'blink', 'none'],
|
63
67
|
#Ausrichtung
|
64
68
|
'float' => ['left', 'right', 'none' ],
|
69
|
+
'display' => ['inline'],
|
65
70
|
'text-align' => ['left', 'center', 'right', 'justify', 'char'],
|
66
71
|
'vertical-align' => ['top', 'middle','bottom','baseline','sub','super','text-top','text-bottom'],
|
67
72
|
'clear' => ['left', 'right','both','none'], #Fortsetzung bei Textumfluss
|
@@ -10,68 +10,71 @@ class Document
|
|
10
10
|
#- article
|
11
11
|
#- report
|
12
12
|
#- book
|
13
|
-
def initialize(
|
13
|
+
def initialize( settings = {} )
|
14
14
|
#Set template defaults
|
15
15
|
@template = {
|
16
|
-
:html
|
16
|
+
:html => DocumentTemplate[:html],
|
17
17
|
:latex => DocumentTemplate[:article],
|
18
18
|
:text => DocumentTemplate[:text],
|
19
19
|
:wiki => DocumentTemplate[:wiki],
|
20
20
|
}
|
21
|
-
|
21
|
+
@language = 'ngerman' #default
|
22
|
+
@date = nil
|
23
|
+
|
24
|
+
##>>>>temporary check, old interface
|
25
|
+
#~ puts settings.inspect
|
26
|
+
if ! settings.is_a?(Hash)
|
27
|
+
#Make an exception to correct data
|
28
|
+
raise "Old interface for Document#new, use :template => "
|
29
|
+
settings = { :template => settings }
|
30
|
+
end
|
31
|
+
##<<<<temporary check, old interface
|
32
|
+
@log = settings[:log]
|
33
|
+
@log = Log4r::Logger.new( 'Doc' ) unless @log
|
34
|
+
|
35
|
+
@meta = {} #some meta-Tags for HTML
|
22
36
|
@body = element( :body )
|
23
37
|
@head = element( :head )
|
24
38
|
#~ @body.part_of << self
|
25
39
|
#~ @head.part_of << self
|
26
|
-
@body.part_of_doc << self
|
27
|
-
@head.part_of_doc << self
|
28
|
-
@language = 'ngerman'
|
29
40
|
@options = []
|
30
|
-
@meta = {} #some meta-Tags for HTML
|
31
41
|
#Flag to avoid double definition of docinfo()
|
32
42
|
@docinfo_called = false
|
33
43
|
@creator = nil
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
puts "Unknown template #{templ}, valid:\n\t#{DocumentTemplate.keys.join("\n\t")}" #fixme raise
|
63
|
-
elsif ! @template[target].kind_of?(String )
|
64
|
-
puts "Template no string #{@template.inspect}"
|
65
|
-
@template[target] = @template[target].to_s
|
66
|
-
end
|
67
|
-
}
|
68
|
-
else
|
69
|
-
raise "Should set template, but don't know how #{template.inspect}"
|
70
|
-
end
|
44
|
+
|
45
|
+
settings.each{|key, value|
|
46
|
+
case key
|
47
|
+
when :title, :author, :date, :keywords, :description, :creator, :language
|
48
|
+
self.send("#{key}=".to_sym, value)
|
49
|
+
when :shorttitle, :odp
|
50
|
+
self.meta( key, value )
|
51
|
+
when :template
|
52
|
+
[value].flatten.each{|template|
|
53
|
+
case template
|
54
|
+
when DocumentTemplate
|
55
|
+
@template[template.target] = template
|
56
|
+
when Symbol
|
57
|
+
templ = DocumentTemplate[template]
|
58
|
+
if ! templ.is_a?( DocumentTemplate )
|
59
|
+
puts "Unknown template #{template}, valid:\n\t#{DocumentTemplate.keys.join("\n\t")}" #fixme raise
|
60
|
+
else
|
61
|
+
@template[templ.target] = templ
|
62
|
+
end
|
63
|
+
end
|
64
|
+
} #templates
|
65
|
+
when :maketitle
|
66
|
+
@body << element(:maketitle ).cr
|
67
|
+
else
|
68
|
+
puts "Document.new: Unknown setting #{key.inspect} (=#{value.inspect})"
|
69
|
+
end
|
70
|
+
} #settings
|
71
|
+
|
71
72
|
end
|
72
73
|
#body and head are lists, containing elements.
|
73
74
|
attr_reader :body, :head
|
74
75
|
attr_reader :template
|
76
|
+
#Logger for the document
|
77
|
+
attr_reader :log
|
75
78
|
#Document title
|
76
79
|
attr_accessor :title
|
77
80
|
#Set document description
|
@@ -159,19 +162,22 @@ class Document
|
|
159
162
|
#Supported document types are:
|
160
163
|
#- tex
|
161
164
|
#- html
|
165
|
+
#- (wiki)
|
166
|
+
#- (text)
|
162
167
|
#Depending on a template, different results are created.
|
163
168
|
#
|
164
|
-
#
|
169
|
+
#There is a comparison between an already existing file and the new one.
|
165
170
|
#To write a new version, the document must change and overwrite must be true.
|
166
171
|
#
|
167
172
|
#It is possible to give pairs of RegExp (pattern) and replacements to the result.
|
168
173
|
def save( filename, overwrite=false, replacements = {} )
|
169
174
|
|
170
175
|
if ! @template
|
171
|
-
|
176
|
+
@log.error( "No template available to create #{filename}" ) if @log.error?
|
172
177
|
return false
|
173
178
|
end
|
174
179
|
|
180
|
+
#Get old content for comparison
|
175
181
|
old = nil
|
176
182
|
prefix = [ nil,
|
177
183
|
"Build by\t#{__FILE__}",
|
@@ -183,9 +189,7 @@ class Document
|
|
183
189
|
"#{PREFIX_ENDFLAG}"
|
184
190
|
].join("\n\t")
|
185
191
|
if File.exist?( filename )
|
186
|
-
|
187
|
-
old = f.readlines().to_s
|
188
|
-
f.close
|
192
|
+
old = File.read( filename )
|
189
193
|
end
|
190
194
|
#Determine the target document type, depending on extension.
|
191
195
|
extension = File.basename( filename ).split( /\./).last
|
@@ -199,11 +203,17 @@ class Document
|
|
199
203
|
when /wiki/
|
200
204
|
@target = :wiki
|
201
205
|
else
|
206
|
+
@log.fatal( "Unknown Extension #{extension} for #{File.basename( filename )}" ) if @log.fatal?
|
202
207
|
raise "Unknown Extension #{extension}"
|
203
208
|
end
|
204
209
|
|
205
|
-
|
206
|
-
|
210
|
+
new = to_doc( @target, {
|
211
|
+
:template=> @template[target],
|
212
|
+
:document => self,
|
213
|
+
:filename => filename,
|
214
|
+
:replacements => replacements,
|
215
|
+
:log => @log
|
216
|
+
})
|
207
217
|
|
208
218
|
case @target
|
209
219
|
when :latex
|
@@ -216,6 +226,7 @@ class Document
|
|
216
226
|
when :wiki
|
217
227
|
#~ new.squeeze!("\n")
|
218
228
|
else
|
229
|
+
@log.fatal( "Unknown target #{@target} for #{File.basename( filename )}" ) if @log.fatal?
|
219
230
|
raise "Unknown target #{@target}"
|
220
231
|
end
|
221
232
|
#Make it a bit more compact.
|
@@ -223,7 +234,7 @@ class Document
|
|
223
234
|
new.gsub!(/\n+\n\n/, "\n\n")
|
224
235
|
|
225
236
|
if ! new.kind_of?( String )
|
226
|
-
|
237
|
+
@log.error( "New is wrong type: #{new.inspect}" ) if @log.error?
|
227
238
|
end
|
228
239
|
@target = nil
|
229
240
|
|
@@ -234,12 +245,14 @@ class Document
|
|
234
245
|
answer = $stdin.gets() if $stdin.tty? #nur bei call aus DOS-Box
|
235
246
|
if ! ( answer =~ /[YyjJ].*/ )
|
236
247
|
puts "Bye"
|
248
|
+
@log.info( "Overwrite #{filename} after confirmation" ) if @log.info?
|
237
249
|
return false
|
238
250
|
end
|
239
251
|
end
|
240
252
|
f = File.new( filename, 'w' )
|
241
253
|
f << new
|
242
254
|
f.close
|
255
|
+
@log.info( "Save changed\t#{filename}") if @log.info?
|
243
256
|
puts "Save changed\t#{filename}" if @@givemessage.include?(:change)
|
244
257
|
#Save copy of old version (attention, *.bak makes no control on tex or html)
|
245
258
|
#~ f = File.new( filename.sub( extension, 'bak'), 'w' )
|
@@ -248,6 +261,7 @@ class Document
|
|
248
261
|
Document.runtex( filename, @runtex ) if @runtex
|
249
262
|
return true
|
250
263
|
elsif old
|
264
|
+
@log.info("Unchanged\t#{filename}") if @log.info?
|
251
265
|
puts "Unchanged\t#{filename}" if @@givemessage.include?(:nochange)
|
252
266
|
return false
|
253
267
|
end
|
@@ -261,18 +275,21 @@ class Document
|
|
261
275
|
#(used from Document#save to include some additional information).
|
262
276
|
#
|
263
277
|
#If the method is called directly to prpare document snipplets, you can use:
|
264
|
-
# puts Document#
|
278
|
+
# puts Document#to_doc( :latex, '<<body>>')
|
265
279
|
#
|
266
280
|
#It is possible to give pairs of RegExp (pattern) and a replacement to the result.
|
267
|
-
def
|
268
|
-
|
269
|
-
|
281
|
+
def to_doc( target, options )
|
282
|
+
#~ o = Docgenerator_logger.set_option_defaults(options)
|
283
|
+
options[:log].info( "Build document for #{target.inspect}" ) if options[:log].info?
|
284
|
+
template = options[:template]
|
270
285
|
if ! template
|
271
|
-
|
286
|
+
options[:log].error( "No template available to create #{target.inspect} #{self.class}" ) if options[:log].error?
|
272
287
|
return ''
|
273
288
|
end
|
274
|
-
|
275
|
-
|
289
|
+
replacements = options[:replacements] || {}
|
290
|
+
options[:log].warn( "No filename given " ) if options[:log].warn? and ! options[:filename]
|
291
|
+
|
292
|
+
new = template.template
|
276
293
|
case target
|
277
294
|
when :latex
|
278
295
|
add_option( @language )
|
@@ -280,56 +297,36 @@ class Document
|
|
280
297
|
when :text
|
281
298
|
when :wiki
|
282
299
|
else
|
283
|
-
|
300
|
+
options[:log].fatal( "Unknown target #{target} for #{options[:filename]}" ) if options[:log].fatal?
|
301
|
+
return ''
|
284
302
|
end
|
285
303
|
if ! new.kind_of?( String )
|
286
|
-
|
304
|
+
options[:log].error( "New is wrong type: #{new.inspect}") if options[:log].error?
|
287
305
|
end
|
288
306
|
|
289
307
|
@head << self.docinfo()
|
290
|
-
new.sub!( '<<head>>', @head.
|
291
|
-
new.sub!( '<<body>>', @body.
|
292
|
-
new.sub!( '<<classoptions>>', @options.join(','))
|
308
|
+
new.sub!( '<<head>>', @head.to_doc(target, options ))
|
309
|
+
new.sub!( '<<body>>', @body.to_doc(target, options))
|
310
|
+
new.sub!( '<<classoptions>>', @options.uniq.join(','))
|
293
311
|
|
312
|
+
|
294
313
|
replacements.each{|pattern, replace |
|
314
|
+
options[:log].info("Replace text #{pattern.source} with #{replace}" ) if options[:log].info?
|
295
315
|
new.gsub!( pattern, replace ) if replace
|
296
316
|
}
|
297
317
|
return new
|
298
|
-
end #Document#
|
318
|
+
end #Document#to_doc
|
299
319
|
#Return the actual target type.
|
300
320
|
#Needed by Element#to_s to decide which method is used to prepare the output.
|
301
321
|
#
|
302
322
|
#The usage of this technic makes similar processing unposibble.
|
303
323
|
#Set in Document#save.
|
304
324
|
attr_reader :target
|
305
|
-
|
306
|
-
#Set a major output routine.
|
307
|
-
def Document.target=( target )
|
308
|
-
@@target = target
|
309
|
-
end
|
310
|
-
def Document.target( element )
|
311
|
-
return @@target if @@target #Use global value for multiple outputs
|
312
|
-
case element.part_of_doc.size
|
313
|
-
when 1
|
314
|
-
return element.part_of_doc.first.target
|
315
|
-
when 0
|
316
|
-
puts "Document.target: No related document. Don't know which target to take #{element.inspect} line #{__LINE__}"
|
317
|
-
element.ancestors.flatten.each_with_index{|a,i|
|
318
|
-
puts "\tAncestor #{i}\t#{a.inspect}"
|
319
|
-
puts "\t\t\t#{a.ancestors.inspect}"
|
320
|
-
}
|
321
|
-
#~ puts caller()
|
322
|
-
return :text
|
323
|
-
else
|
324
|
-
puts "Multiple documents. Don't know which target to take #{element.inspect}"
|
325
|
-
element.part_of_doc.each{|d| puts "\t#{d.inspect}" }
|
326
|
-
return :text
|
327
|
-
end
|
328
|
-
end
|
325
|
+
|
329
326
|
#Call TeX and translate the file.
|
330
327
|
#Experimental
|
331
328
|
#Fixme: Chain
|
332
|
-
def Document.runtex( filename, format = :
|
329
|
+
def Document.runtex( filename, format = :xelatex )
|
333
330
|
begin
|
334
331
|
#~ require 'rtex'
|
335
332
|
require 'c:/usr/script/rtex/rtex'
|
@@ -339,9 +336,11 @@ class Document
|
|
339
336
|
end
|
340
337
|
#~ puts "Unknown texfile #{filename}" if ! filename
|
341
338
|
tex = Chain.new()
|
339
|
+
tex.xelatex() #default
|
342
340
|
case format
|
343
|
-
when :
|
344
|
-
|
341
|
+
when :xelatex; tex.xelatex()
|
342
|
+
when :pdflatex; tex.pdflatex()
|
343
|
+
when :latex; tex.latex()
|
345
344
|
end
|
346
345
|
#~ Logger.level=3
|
347
346
|
tex.file = filename
|
@@ -352,7 +351,7 @@ class Document
|
|
352
351
|
return false
|
353
352
|
end
|
354
353
|
end
|
355
|
-
#Make some basic
|
354
|
+
#Make some basic replacements for TeX.
|
356
355
|
#There is no sense to use it with HTML.
|
357
356
|
#
|
358
357
|
#Better solution: Puts String into \path, \verb or similar.
|
@@ -1,7 +1,15 @@
|
|
1
|
+
#Extend all objects by the methods
|
2
|
+
#- to_doc
|
3
|
+
#- to_html
|
4
|
+
#- to_latex
|
5
|
+
#- to_wiki
|
6
|
+
#- to_text
|
7
|
+
#Redefine is_a?:
|
8
|
+
#Return true, when you test with a symbol.
|
1
9
|
class Object
|
2
10
|
alias :old_is_a? :is_a?
|
3
11
|
#Redefine the standard is_a?
|
4
|
-
#Returns also true, if one of the ids is in
|
12
|
+
#Returns also true, if one of the ids is in testvalue
|
5
13
|
def is_a?( testvalue)
|
6
14
|
if testvalue.old_is_a?(Symbol)
|
7
15
|
if old_is_a?(Element)
|
@@ -13,7 +21,50 @@ class Object
|
|
13
21
|
return old_is_a?(testvalue)
|
14
22
|
end
|
15
23
|
end
|
24
|
+
#
|
25
|
+
# to_doc returns the object as a string.
|
26
|
+
# will be redefined for Element
|
27
|
+
#
|
28
|
+
def to_doc(target, options = {})
|
29
|
+
o = Docgenerator_logger.set_option_defaults(options)
|
30
|
+
str = ""
|
31
|
+
if self.is_a?(Element) and ! self.respond_to?(:to_doc)
|
32
|
+
o[:log].error( "Missing to_doc routine for #{self.class}") if o[:log].error?
|
33
|
+
end
|
34
|
+
if self.respond_to?(:to_str)
|
35
|
+
str << self.to_str
|
36
|
+
else
|
37
|
+
str << self.to_s
|
38
|
+
end
|
39
|
+
str
|
40
|
+
end
|
41
|
+
def to_text(options = {}); to_doc(:text, options); end
|
42
|
+
def to_latex(options = {}); to_doc(:latex, options); end
|
43
|
+
def to_html(options = {}); to_doc(:html, options); end
|
44
|
+
def to_wiki(options = {}); to_doc(:wiki, options); end
|
45
|
+
end
|
46
|
+
|
47
|
+
class Array
|
48
|
+
#
|
49
|
+
# Returns the element for each parameter
|
50
|
+
#
|
51
|
+
def to_doc(target, options = {})
|
52
|
+
o = Docgenerator_logger.set_option_defaults(options)
|
53
|
+
o[:log].debug("enter to_doc in array for #{target}") if o[:log].debug?
|
54
|
+
str = ""
|
55
|
+
self.each{|el|
|
56
|
+
begin
|
57
|
+
str << el.to_doc(target, o)
|
58
|
+
rescue ArgumentError
|
59
|
+
o[:log].fatal("ArgumentError to_doc for element <#{el.class}>") if o[:log].fatal?
|
60
|
+
str << el.to_doc(target)
|
61
|
+
end
|
62
|
+
}
|
63
|
+
return str
|
64
|
+
end
|
16
65
|
end
|
66
|
+
|
67
|
+
|
17
68
|
#This class defines possible elements of a document.
|
18
69
|
#For each type of elements a class is defined.
|
19
70
|
#The definition can be done explicite or generic with Element.create.
|
@@ -26,7 +77,6 @@ end
|
|
26
77
|
#But the error is done, when the element is created.
|
27
78
|
#When you redefine ELEMENTS_TRACE, some tracing information are stored during creation.
|
28
79
|
class Element
|
29
|
-
include Backlinks
|
30
80
|
#Hash with all ids and their corresponding classes.
|
31
81
|
@@ids = Hash.new( )
|
32
82
|
#All attributes are stored in this hash.
|
@@ -67,13 +117,15 @@ class Element
|
|
67
117
|
end
|
68
118
|
#Add a new element class or assign another name (synonym) for a class.
|
69
119
|
#The initial call is made by Element.inherited.
|
120
|
+
#
|
121
|
+
#Element.add( [:element], Element )
|
70
122
|
def Element.add( idlist, elementClass )
|
71
123
|
if ! elementClass.new.kind_of?( Element )
|
72
124
|
raise "Element.add get no Element-class #{elementClass}"
|
73
125
|
end
|
74
|
-
|
75
|
-
|
76
|
-
|
126
|
+
idlist = [ idlist ] if ! idlist.kind_of?( Array )
|
127
|
+
raise "Empty idlist for #{elementClass}" if idlist.empty?
|
128
|
+
|
77
129
|
idlist.each{|id|
|
78
130
|
if @@ids[ id ] == nil
|
79
131
|
puts "Element class '#{id}' is new: #{elementClass}" if @@log
|
@@ -147,10 +199,10 @@ class Element
|
|
147
199
|
return elementclass
|
148
200
|
end
|
149
201
|
#Return all id's of the class.
|
150
|
-
|
202
|
+
#@@ids is expanded in Element.add.
|
151
203
|
def ids( )
|
152
204
|
myids = []
|
153
|
-
@@ids.each{|k,v| myids << k if v == self.class }
|
205
|
+
@@ids.each{|k,v| myids << k if v == self.class and k.class != Class }
|
154
206
|
return myids
|
155
207
|
end
|
156
208
|
#Prepares an overview on all Elements.
|
@@ -199,23 +251,28 @@ class Element
|
|
199
251
|
def Element.add_output( target, string )
|
200
252
|
case target
|
201
253
|
when :latex
|
202
|
-
cmd = "def to_latex()\n"
|
254
|
+
cmd = "def to_latex(options = {})\n"
|
203
255
|
when :html
|
204
|
-
cmd = "def to_html()\n"
|
256
|
+
cmd = "def to_html(options = {})\n"
|
205
257
|
when :text
|
206
|
-
cmd = "def to_text()\n"
|
258
|
+
cmd = "def to_text(options = {})\n"
|
207
259
|
when :wiki
|
208
|
-
cmd = "def to_wiki()\n"
|
260
|
+
cmd = "def to_wiki(options = {})\n"
|
209
261
|
else
|
210
262
|
puts "#{self}: Undefined target format #{target}"
|
211
263
|
end
|
212
264
|
if ! string.kind_of?( String )
|
213
265
|
puts "Error element <#{self.new.ids}>: #{string.inspect} is no String"
|
214
266
|
end
|
267
|
+
cmd << <<code
|
268
|
+
o = Docgenerator_logger.set_option_defaults(options)
|
269
|
+
o[:log].debug("enter to_doc for #{self.inspect}") if o[:log].debug?
|
270
|
+
code
|
215
271
|
template = string.gsub(/\\/, '\\\\\\')
|
216
272
|
template.gsub!(/"/, '\"')
|
217
|
-
|
218
|
-
cmd
|
273
|
+
template.gsub!(/@content\}/, "@content.to_doc(#{target.inspect}, options)}")
|
274
|
+
cmd << " \"#{template}\"\n"
|
275
|
+
cmd << "end\n"
|
219
276
|
class_eval( cmd )
|
220
277
|
end
|
221
278
|
#Defines an element.
|
@@ -230,13 +287,14 @@ class Element
|
|
230
287
|
def initialize( attr={}, content = nil)
|
231
288
|
#@attr is a hash containing the values for each attribute.
|
232
289
|
@attr = Hash.new( )
|
290
|
+
@log = DOCGENERATOR_LOGGER
|
291
|
+
#attr alias
|
292
|
+
@attr_alias = Hash.new( )
|
233
293
|
if self.content?()
|
234
294
|
@content = []
|
235
295
|
else
|
236
296
|
@content = nil
|
237
297
|
end
|
238
|
-
@part_of = [] #list of elements, where this element is part of (normaly only one element)
|
239
|
-
@part_of_doc = [] #list of documents, where this element is part of (normaly only one element)
|
240
298
|
@crbefore = false #make \n before element
|
241
299
|
@crmid = false #make \n before and after opening/closing html-tag
|
242
300
|
@crafter = false #make \n after element
|
@@ -262,7 +320,7 @@ class Element
|
|
262
320
|
@@attr[self.class].each{ |k,a|
|
263
321
|
next if !a.kind_of?( Symbol )
|
264
322
|
if @attr[a]
|
265
|
-
@
|
323
|
+
@attr_alias[k] = @attr[a]
|
266
324
|
else
|
267
325
|
puts "Undefined Alias-Attribute #{k}"
|
268
326
|
@attr[k] = Attribute.create().new( k, self )
|
@@ -271,6 +329,8 @@ class Element
|
|
271
329
|
attr.each{ |k,v|
|
272
330
|
if @attr[k]
|
273
331
|
@attr[k] << v
|
332
|
+
elsif @attr_alias[k]
|
333
|
+
@attr_alias[k] << v
|
274
334
|
else
|
275
335
|
puts "Usage of unknown attribute '#{k}' in '#{self.ids.join(',')}'"
|
276
336
|
end
|
@@ -285,11 +345,11 @@ class Element
|
|
285
345
|
def restrict_to( *argv )
|
286
346
|
@targets = []
|
287
347
|
@suppressed_targets = SUPPORTED_TARGETS.dup
|
288
|
-
|
348
|
+
@log.warn("Element#restrict_to: #{self.inspect} restrict to #{argv.inspect}") if @log.warn?
|
289
349
|
argv.each{ |arg|
|
290
350
|
#~ if ! SUPPORTED_TARGETS.include?( arg )
|
291
351
|
if ! @suppressed_targets.delete( arg )
|
292
|
-
|
352
|
+
@log.warn("Restriction for unsupported target #{arg}") if @log.warn?
|
293
353
|
end
|
294
354
|
@targets << arg
|
295
355
|
}
|
@@ -332,10 +392,8 @@ class Element
|
|
332
392
|
if @content
|
333
393
|
@content << content
|
334
394
|
else
|
335
|
-
|
336
|
-
#~ @site.add2log( :error, "Add content to an element without this feature (#{self.ids}, #{content.inspect}" )
|
395
|
+
@log.warn("Add content to an element without this feature #{self.ids.inspect}, #{content.inspect}") if @log.warn?
|
337
396
|
end
|
338
|
-
set_backlink( content )
|
339
397
|
end
|
340
398
|
|
341
399
|
#Add content after a target (other content)
|
@@ -406,6 +464,8 @@ class Element
|
|
406
464
|
#Return an attribute to add content.
|
407
465
|
def [] (key)
|
408
466
|
attr = @attr[key]
|
467
|
+
#If Attribute does not exist, take a look, if it is an alias-name.
|
468
|
+
attr = @attr_alias[key] if !attr
|
409
469
|
if !attr
|
410
470
|
puts "Request unknown attribute '#{key}', return a dummy"
|
411
471
|
attr = Attribute.create( ).new(key, self)
|
@@ -428,53 +488,56 @@ class Element
|
|
428
488
|
@@level = 0
|
429
489
|
#Build a String to be used for the target document.
|
430
490
|
#Calls Element#to_latex and Element#to_html.
|
431
|
-
def to_s( target = Document.target( self ) )
|
491
|
+
#~ def to_s( target = Document.target( self ) )
|
492
|
+
def to_doc( target, options = {} )
|
493
|
+
o = Docgenerator_logger.set_option_defaults(options)
|
494
|
+
o[:log].debug("enter to_doc for #{self.inspect}") if o[:log].debug?
|
432
495
|
#Return empty string, if target is not requested.
|
433
496
|
if ! @targets.include?( target )
|
434
497
|
if @suppressed_targets.include?(target)
|
435
|
-
|
498
|
+
o[:log].info("Element#to_doc: Content of #{self.inspect} suppressed for Target #{target.inspect}.") if o[:log].info?
|
436
499
|
else
|
437
|
-
|
500
|
+
o[:log].warn("Element#to_doc: Target #{target.inspect} not supported for #{self.inspect}.") if o[:log].warn?
|
438
501
|
end
|
439
502
|
return ''
|
440
503
|
end
|
441
504
|
#Some checks
|
442
505
|
@attr.each{|k,v|
|
443
506
|
if v.required? and v.to_s == '' and v.settings.include?(target)
|
444
|
-
|
507
|
+
o[:log].error "#{self.ids}: Attribut '#{k}' without required value" if o[:log].error?
|
445
508
|
end
|
446
509
|
}
|
447
510
|
#Build the string.
|
448
511
|
result = ''
|
449
512
|
case target
|
450
513
|
when :latex
|
451
|
-
result = to_latex()
|
514
|
+
result = to_latex(options)
|
452
515
|
when :html
|
453
|
-
result = to_html()
|
516
|
+
result = to_html(options)
|
454
517
|
when :wiki
|
455
|
-
result = to_wiki()
|
518
|
+
result = to_wiki(options)
|
456
519
|
when :text
|
457
|
-
result = to_text()
|
520
|
+
result = to_text(options)
|
458
521
|
when :debug
|
459
522
|
@@level += 1
|
460
523
|
result = "\n<element #{self.ids.join(',')} begin>"
|
461
524
|
@attr.each{|k,v|
|
462
525
|
#result += "\n\t#{k}: #{v.inspect}"
|
463
526
|
if v != []
|
464
|
-
result
|
527
|
+
result << "\n\t#{k}:"
|
465
528
|
v.each{|v2|
|
466
|
-
result
|
529
|
+
result << v2.to_s
|
467
530
|
}
|
468
531
|
end
|
469
532
|
}
|
470
|
-
result
|
471
|
-
result
|
533
|
+
result << @content.to_s
|
534
|
+
result << "\n<element #{self.ids.join(',')} end>"
|
472
535
|
@@level -= 1
|
473
536
|
result.gsub!(/^/, "\t" * @@level )
|
474
537
|
else
|
475
|
-
|
538
|
+
o[:log].fatal("Undefined target format '#{target}'") if o[:log].fatal?
|
476
539
|
end
|
477
|
-
|
540
|
+
#Already added in submethods
|
478
541
|
#~ result = "\n#{result}" if @crbefore
|
479
542
|
#~ result << "\n" if @crafter
|
480
543
|
return result
|
@@ -483,11 +546,16 @@ class Element
|
|
483
546
|
#This method must be overwritten from the element class.
|
484
547
|
#
|
485
548
|
#By default, the concatenation of all ids and the content is taken.
|
486
|
-
def to_latex()
|
487
|
-
|
549
|
+
def to_latex(options = {})
|
550
|
+
o = Docgenerator_logger.set_option_defaults(options)
|
551
|
+
o[:log].error("Missing output routine for LaTeX (#{self.ids.join(',')}) [#{@called_by}]") if o[:log].error?
|
552
|
+
makroname = 'dummy'
|
553
|
+
self.ids.each{|id|
|
554
|
+
makroname = id if id.is_a?(Symbol) or id.is_a?(String)
|
555
|
+
}
|
488
556
|
cmd = ''
|
489
557
|
cmd << "\n" if @crbefore
|
490
|
-
cmd << "\\#{
|
558
|
+
cmd << "\\#{makroname}{#{@content}}"
|
491
559
|
cmd << "\n" if @crafter
|
492
560
|
return cmd
|
493
561
|
end
|
@@ -518,21 +586,22 @@ class Element
|
|
518
586
|
#The tag from Element.htmltag is taken and all attributes and the content are used.
|
519
587
|
#
|
520
588
|
#This method can be overwriten from the element class.
|
521
|
-
def to_html()
|
589
|
+
def to_html(options = {})
|
590
|
+
o = Docgenerator_logger.set_option_defaults(options)
|
522
591
|
tag = htmltag()
|
523
592
|
if ! tag
|
524
|
-
|
593
|
+
o[:log].error("No HTML element available (#{self.ids.join(',')})") if o[:log].error?
|
525
594
|
return ''
|
526
595
|
elsif tag == ''
|
527
596
|
tag = 'span'
|
528
|
-
|
597
|
+
o[:log].error("Missing output routine for HTML (#{self.ids.join(',')}) [#{@called_by}]") if o[:log].error?
|
529
598
|
end
|
530
599
|
#Test if the HTML-Tag should contain something, but there is nothing.
|
531
600
|
#If :empty_ok it is ok, that there is no content (e.g <td>)
|
532
601
|
#May make problems, if an empty tag is used to set a id-mark.
|
533
602
|
if content?() and content? != :empty_ok and
|
534
603
|
( ! @content or @content == [] or @content == [nil] )
|
535
|
-
|
604
|
+
o[:log].warn("HTML-Tag #{tag} without content -> ignored") if o[:log].warn?
|
536
605
|
return ''
|
537
606
|
end
|
538
607
|
html = String.new()
|
@@ -544,7 +613,7 @@ class Element
|
|
544
613
|
if @content
|
545
614
|
html << ">"
|
546
615
|
html <<"\n" if @crmid
|
547
|
-
html << "#{@content}"
|
616
|
+
html << "#{@content.to_html(options = {})}"
|
548
617
|
html << "\n" if @crmid and @content.size > 0 and html[-1,1] != "\n"
|
549
618
|
html << "</#{tag}>"
|
550
619
|
elsif content?() == nil
|
@@ -555,16 +624,21 @@ class Element
|
|
555
624
|
html << "\n" if @crafter
|
556
625
|
return html
|
557
626
|
end #to_html
|
558
|
-
def to_wiki()
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
627
|
+
def to_wiki(options = {})
|
628
|
+
o = Docgenerator_logger.set_option_defaults(options)
|
629
|
+
o[:log].error("Missing output routine for Wiki (#{self.ids.join(',')}) [#{@called_by}]") if o[:log].error?
|
630
|
+
return "#{@content.to_wiki(options)}\n"
|
631
|
+
end
|
632
|
+
def to_text(options = {})
|
633
|
+
o = Docgenerator_logger.set_option_defaults(options)
|
634
|
+
o[:log].error("Missing output routine for Text (#{self.ids.join(',')}) [#{@called_by}]") if o[:log].error?
|
564
635
|
text = String.new()
|
565
636
|
text << "\n" if @crbefore
|
566
|
-
text = "#{@content}".strip
|
637
|
+
text = "#{@content.to_text(options)}".strip
|
567
638
|
text << "\n" if @crafter
|
568
639
|
return text
|
569
640
|
end
|
570
|
-
|
641
|
+
def to_s()
|
642
|
+
return self.inspect
|
643
|
+
end
|
644
|
+
end #Element
|