deplate 0.7.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (145) hide show
  1. data/AUTHORS.TXT +26 -0
  2. data/CHANGES.TXT +177 -0
  3. data/LICENSE.TXT +340 -0
  4. data/NEWS.TXT +29 -0
  5. data/README.TXT +86 -0
  6. data/TODO.TXT +202 -0
  7. data/VERSION.TXT +1 -0
  8. data/bin/deplate +3 -0
  9. data/bin/deplate.bat +2 -0
  10. data/etc/deplate.ini +361 -0
  11. data/lib/deplate.rb +31 -0
  12. data/lib/deplate/abstract-class.rb +30 -0
  13. data/lib/deplate/builtin.rb +11 -0
  14. data/lib/deplate/cache.rb +59 -0
  15. data/lib/deplate/commands.rb +693 -0
  16. data/lib/deplate/common.rb +335 -0
  17. data/lib/deplate/converter.rb +99 -0
  18. data/lib/deplate/core.rb +2705 -0
  19. data/lib/deplate/css/article.css +545 -0
  20. data/lib/deplate/css/deplate.css +699 -0
  21. data/lib/deplate/css/heading-navbar.css +29 -0
  22. data/lib/deplate/css/layout-deplate-print.css +540 -0
  23. data/lib/deplate/css/layout-deplate.css +764 -0
  24. data/lib/deplate/css/sans-serif.css +160 -0
  25. data/lib/deplate/css/serif-e.css +170 -0
  26. data/lib/deplate/css/serif-rel.css +121 -0
  27. data/lib/deplate/css/serif.css +190 -0
  28. data/lib/deplate/css/slides.css +11 -0
  29. data/lib/deplate/css/tabbar-left.css +91 -0
  30. data/lib/deplate/css/tabbar-right-ie.css +14 -0
  31. data/lib/deplate/css/tabbar-right.css +118 -0
  32. data/lib/deplate/css/tabbar-top.css +64 -0
  33. data/lib/deplate/css/tabbar.css +81 -0
  34. data/lib/deplate/css/text-sans-serif.css +154 -0
  35. data/lib/deplate/css/text-serif.css +175 -0
  36. data/lib/deplate/define.rb +439 -0
  37. data/lib/deplate/docbook.rb +738 -0
  38. data/lib/deplate/elements.rb +1355 -0
  39. data/lib/deplate/etc.rb +199 -0
  40. data/lib/deplate/external.rb +135 -0
  41. data/lib/deplate/fmt/dbk-article-4.1.2.rb +21 -0
  42. data/lib/deplate/fmt/dbk-article.rb +46 -0
  43. data/lib/deplate/fmt/dbk-book.rb +46 -0
  44. data/lib/deplate/fmt/dbk-ref.rb +105 -0
  45. data/lib/deplate/fmt/dbk-slides.rb +47 -0
  46. data/lib/deplate/fmt/dbk-snippet.rb +21 -0
  47. data/lib/deplate/fmt/html-snippet.rb +21 -0
  48. data/lib/deplate/fmt/html.rb +1696 -0
  49. data/lib/deplate/fmt/htmlsite.rb +419 -0
  50. data/lib/deplate/fmt/htmlslides.rb +21 -0
  51. data/lib/deplate/fmt/htmlwebsite.rb +70 -0
  52. data/lib/deplate/fmt/latex-snippet.rb +22 -0
  53. data/lib/deplate/fmt/latex.rb +1242 -0
  54. data/lib/deplate/fmt/php.rb +19 -0
  55. data/lib/deplate/fmt/phpsite.rb +19 -0
  56. data/lib/deplate/fmt/plain.rb +598 -0
  57. data/lib/deplate/fmt/template.rb +34 -0
  58. data/lib/deplate/fmt/xhtml10t.rb +41 -0
  59. data/lib/deplate/formatter-snippet.rb +17 -0
  60. data/lib/deplate/formatter.rb +1210 -0
  61. data/lib/deplate/input.rb +492 -0
  62. data/lib/deplate/input/deplate-headings.rb +48 -0
  63. data/lib/deplate/input/deplate-restricted.rb +70 -0
  64. data/lib/deplate/input/deplate.rb +28 -0
  65. data/lib/deplate/input/rdoc.rb +277 -0
  66. data/lib/deplate/input/template.rb +29 -0
  67. data/lib/deplate/lib/latex/highlight-extra.sty +15 -0
  68. data/lib/deplate/lib/latex/highlight-typical.sty +15 -0
  69. data/lib/deplate/lib/tabmenu.js +146 -0
  70. data/lib/deplate/locale/de.latin1 +708 -0
  71. data/lib/deplate/locale/ru.koi8-r +48 -0
  72. data/lib/deplate/locale/zh_cn.gb2312 +35 -0
  73. data/lib/deplate/macros.rb +639 -0
  74. data/lib/deplate/messages.rb +120 -0
  75. data/lib/deplate/metadata.rb +77 -0
  76. data/lib/deplate/metadata/marshal.rb +24 -0
  77. data/lib/deplate/metadata/xml.rb +42 -0
  78. data/lib/deplate/metadata/yaml.rb +26 -0
  79. data/lib/deplate/mod/anyword.rb +56 -0
  80. data/lib/deplate/mod/babelfish.rb +27 -0
  81. data/lib/deplate/mod/code-gvim.rb +52 -0
  82. data/lib/deplate/mod/code-highlight.rb +91 -0
  83. data/lib/deplate/mod/colored-log.rb +17 -0
  84. data/lib/deplate/mod/de.rb +19 -0
  85. data/lib/deplate/mod/en.rb +17 -0
  86. data/lib/deplate/mod/endnotes.rb +60 -0
  87. data/lib/deplate/mod/fr.rb +46 -0
  88. data/lib/deplate/mod/html-asciimath.rb +40 -0
  89. data/lib/deplate/mod/html-deplate-button.rb +15 -0
  90. data/lib/deplate/mod/html-headings-navbar.rb +39 -0
  91. data/lib/deplate/mod/html-obfuscate-email.rb +47 -0
  92. data/lib/deplate/mod/html-sidebar.rb +232 -0
  93. data/lib/deplate/mod/htmlslides-navbar-fh.rb +32 -0
  94. data/lib/deplate/mod/iconv.rb +35 -0
  95. data/lib/deplate/mod/imgurl.rb +30 -0
  96. data/lib/deplate/mod/inlatex-compound.rb +69 -0
  97. data/lib/deplate/mod/koma.rb +109 -0
  98. data/lib/deplate/mod/latex-emph-table-head.rb +38 -0
  99. data/lib/deplate/mod/latex-styles.rb +461 -0
  100. data/lib/deplate/mod/latex-verbatim-small.rb +29 -0
  101. data/lib/deplate/mod/makefile.rb +194 -0
  102. data/lib/deplate/mod/mark-external-urls.rb +38 -0
  103. data/lib/deplate/mod/markup-1-warn.rb +37 -0
  104. data/lib/deplate/mod/markup-1.rb +41 -0
  105. data/lib/deplate/mod/navbar-png.rb +33 -0
  106. data/lib/deplate/mod/noindent.rb +32 -0
  107. data/lib/deplate/mod/numpara.rb +40 -0
  108. data/lib/deplate/mod/particle-math.rb +34 -0
  109. data/lib/deplate/mod/php-extra.rb +44 -0
  110. data/lib/deplate/mod/pstoedit.rb +71 -0
  111. data/lib/deplate/mod/recode.rb +57 -0
  112. data/lib/deplate/mod/ru_koi8-r.rb +20 -0
  113. data/lib/deplate/mod/smiley.rb +50 -0
  114. data/lib/deplate/mod/soffice.rb +23 -0
  115. data/lib/deplate/mod/symbols-latin1.rb +58 -0
  116. data/lib/deplate/mod/symbols-od-utf-8.rb +16 -0
  117. data/lib/deplate/mod/symbols-plain.rb +58 -0
  118. data/lib/deplate/mod/symbols-sgml.rb +97 -0
  119. data/lib/deplate/mod/symbols-utf-8.rb +81 -0
  120. data/lib/deplate/mod/symbols-xml.rb +34 -0
  121. data/lib/deplate/mod/syntax-region-alt.rb +37 -0
  122. data/lib/deplate/mod/utf8.rb +49 -0
  123. data/lib/deplate/mod/validate-html.rb +35 -0
  124. data/lib/deplate/mod/xmlrpc.rb +233 -0
  125. data/lib/deplate/mod/zh-cn-autospace.rb +108 -0
  126. data/lib/deplate/mod/zh-cn.rb +59 -0
  127. data/lib/deplate/once-method.rb +44 -0
  128. data/lib/deplate/output.rb +249 -0
  129. data/lib/deplate/particles.rb +815 -0
  130. data/lib/deplate/regions.rb +1076 -0
  131. data/lib/deplate/structured.rb +763 -0
  132. data/lib/deplate/template.rb +430 -0
  133. data/lib/deplate/templates/html-doc.html +28 -0
  134. data/lib/deplate/templates/html-left-tabbar-js.html +37 -0
  135. data/lib/deplate/templates/html-left-tabbar.html +31 -0
  136. data/lib/deplate/templates/html-tabbar-right-table.html +43 -0
  137. data/lib/deplate/templates/html-tabbar-right.html +23 -0
  138. data/lib/deplate/templates/html-tabbar-top.html +43 -0
  139. data/lib/deplate/templates/html-tabbar.html +31 -0
  140. data/lib/deplate/wiki-markup.rb +117 -0
  141. data/lib/deplate/xml.rb +109 -0
  142. data/lib/deplate/zh-cn.rb +59 -0
  143. data/lib/ps2ppm.rb +239 -0
  144. data/man/man1/deplate.1 +692 -0
  145. metadata +210 -0
@@ -0,0 +1,105 @@
1
+ # dbk-ref.rb
2
+ # @Author: Thomas Link (samul AT web.de)
3
+ # @Website: http://deplate.sf.net/
4
+ # @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
5
+ # @Created: 17-M�r-2004.
6
+ # @Last Change: 23-Okt-2005.
7
+ # @Revision: 0.2124
8
+
9
+ require "deplate/docbook"
10
+
11
+ class Deplate::Formatter::DbkRef < Deplate::Formatter::Docbook
12
+ self.myname = "dbk-ref"
13
+ self.rx = /dbk|dbk-ref|docbook/i
14
+
15
+ def initialize(deplate, args)
16
+ @headings = ["refsect1", "refsect2", "refsect3"]
17
+ super
18
+ end
19
+
20
+ def setup
21
+ @deplate.variables["headings"] = "plain"
22
+ @deplate.variables['dbkClass'] ||= 'refentry'
23
+ end
24
+
25
+ def get_doc_open(args)
26
+ out = @deplate.variables["refentry"]
27
+ unless out
28
+ out = @deplate.options.out
29
+ out = File.basename(out, File.extname(out))
30
+ @deplate.variables["refentry"] = out
31
+ end
32
+ o = []
33
+ lang = @deplate.options.messages.prop('lang', self)
34
+ if lang
35
+ o << %{ lang="#{lang}"}
36
+ end
37
+ return %{<refentry id="%s"%s>} % [out, o.join]
38
+ end
39
+
40
+ def get_doc_close(args)
41
+ return "</refentry>"
42
+ end
43
+
44
+ # get_doc_head_open(args)
45
+ noop self, "get_doc_head_open"
46
+
47
+ # get_doc_head_close(args)
48
+ noop self, "get_doc_head_close"
49
+
50
+ def get_doc_head(args)
51
+ refentry = @deplate.variables["refentry"]
52
+ refentrytitle = formatted_inline("refentrytitle", refentry)
53
+ manvolnum = formatted_inline("manvolnum", @deplate.variables["manvol"] || "1")
54
+ refmeta = formatted_block("refmeta", [refentrytitle, manvolnum].join("\n"))
55
+
56
+ refname = formatted_inline("refname", refentry)
57
+ ti = @deplate.get_clip("title")
58
+ refpurpose = ti ? formatted_inline("refpurpose", ti.elt) : nil
59
+ refnamediv = formatted_block("refnamediv", [refname, refpurpose].join("\n"))
60
+
61
+ authors = @deplate.options.author
62
+ accAuthors = docbook_authors(authors)
63
+ if authors.size > 1
64
+ refauthor = formatted_block("authorgroup", accAuthors.join("\n"))
65
+ else
66
+ refauthor = accAuthors.join("\n")
67
+ end
68
+
69
+ dt = @deplate.get_clip("date")
70
+ dt = dt.elt if dt
71
+ date = dt ? formatted_inline("date", dt) : nil
72
+
73
+ yr = @deplate.variables["copyrightYear"] || dt
74
+ if yr
75
+ year = yr.split(/[\s,;]/).collect {|yr| formatted_inline("year", yr)}
76
+ holder = @deplate.get_clip("author")
77
+ holder = formatted_inline("holder", holder.elt) if holder
78
+ copyright = formatted_block("copyright", [year, holder].flatten.compact.join("\n"))
79
+ else
80
+ copyright = nil
81
+ end
82
+
83
+ refentryinfo = [copyright || refauthor, date].compact
84
+ unless refentryinfo.empty?
85
+ refentryinfo = formatted_block("refentryinfo", refentryinfo.join("\n"))
86
+ else
87
+ refentryinfo = nil
88
+ end
89
+
90
+ # <refsynopsisdiv>
91
+ # <cmdsynopsis>
92
+ # <command>/usr/bin/ls</command>
93
+ # <arg choice="opt">
94
+ # <option>aAbcCdfFgilLmnopqrRstux1</option>
95
+ # </arg>
96
+ # <arg choice="opt" rep="repeat">file</arg>
97
+ # </cmdsynopsis>
98
+ # </refsynopsisdiv>
99
+
100
+ return [refentryinfo, refmeta, refnamediv].join("\n")
101
+ end
102
+
103
+ noop self, "get_index"
104
+ end
105
+
@@ -0,0 +1,47 @@
1
+ # dbk-slides.rb
2
+ # @Author: Thomas Link (samul AT web.de)
3
+ # @Website: http://deplate.sf.net/
4
+ # @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
5
+ # @Created: 29-Apr-2005.
6
+ # @Last Change: 23-Okt-2005.
7
+ # @Revision: 0.13
8
+
9
+ require 'deplate/docbook'
10
+
11
+ # <+TBD+>Untested
12
+ class Deplate::Formatter::DbkSlides < Deplate::Formatter::Docbook
13
+ self.myname = 'dbk-slides'
14
+ self.rx = /dbk|dbk-slides|docbook/i
15
+
16
+ def initialize(deplate, args)
17
+ @headings = ['foilgroup', 'foil']
18
+ super
19
+ end
20
+
21
+ def setup
22
+ @deplate.variables['dbkClass'] ||= 'slides'
23
+ end
24
+
25
+ # Document skeleton
26
+ def get_doc_open(args)
27
+ o = []
28
+ lang = @deplate.options.messages.prop('lang', self)
29
+ if lang
30
+ o << %{ lang="#{lang}"}
31
+ end
32
+ return "<slides#{o.join}>"
33
+ end
34
+
35
+ def get_doc_close(args)
36
+ return '</slides>'
37
+ end
38
+
39
+ def get_doc_head_open(args)
40
+ return '<slidesinfo>'
41
+ end
42
+
43
+ def get_doc_head_close(args)
44
+ return '</slidesinfo>'
45
+ end
46
+ end
47
+
@@ -0,0 +1,21 @@
1
+ # docbook-snippet.rb
2
+ # @Author: Thomas Link (samul AT web.de)
3
+ # @Website: http://deplate.sf.net/
4
+ # @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
5
+ # @Created: 11-Aug-2005.
6
+ # @Last Change: 23-Okt-2005.
7
+ # @Revision: 0.17
8
+
9
+ require 'deplate/fmt/dbk-article.rb'
10
+ require 'deplate/formatter-snippet.rb'
11
+
12
+ class Deplate::Formatter::DbkSnippet < Deplate::Formatter::DbkArticle
13
+ self.myname = "dbk-snippet"
14
+
15
+ include Deplate::Snippet
16
+
17
+ def format_paragraph(invoker)
18
+ invoker.elt
19
+ end
20
+ end
21
+
@@ -0,0 +1,21 @@
1
+ # html-snippet.rb
2
+ # @Author: Thomas Link (samul AT web.de)
3
+ # @Website: http://deplate.sf.net/
4
+ # @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
5
+ # @Created: 11-Aug-2005.
6
+ # @Last Change: 23-Okt-2005.
7
+ # @Revision: 0.12
8
+
9
+ require 'deplate/fmt/html.rb'
10
+ require 'deplate/formatter-snippet.rb'
11
+
12
+ class Deplate::Formatter::HTML_Snippet < Deplate::Formatter::HTML
13
+ self.myname = "html-snippet"
14
+
15
+ include Deplate::Snippet
16
+
17
+ def format_paragraph(invoker)
18
+ invoker.elt
19
+ end
20
+ end
21
+
@@ -0,0 +1,1696 @@
1
+ # fmt-html.rb
2
+ # @Author: Thomas Link (samul AT web.de)
3
+ # @Website: http://deplate.sf.net/
4
+ # @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
5
+ # @Created: 17-M�r-2004.
6
+ # @Last Change: 02-Nov-2005.
7
+ # @Revision: 0.3513
8
+
9
+ require 'uri'
10
+ require 'parsedate'
11
+ require 'time'
12
+ require 'pathname'
13
+
14
+ require 'deplate/formatter'
15
+
16
+ # A sample html formatter.
17
+
18
+ class Deplate::Formatter::HTML < Deplate::Formatter
19
+ self.myname = "html"
20
+ self.rx = /html?/i
21
+ self.suffix = ".html"
22
+
23
+ self.label_delegate = [
24
+ :format_heading,
25
+ :format_LIST,
26
+ :format_anchor,
27
+ :format_list,
28
+ :format_list_env,
29
+ ]
30
+
31
+ self.label_once = [
32
+ :format_table,
33
+ :format_IMG,
34
+ :format_figure,
35
+ :format_IDX,
36
+ :format_MAKEBIB,
37
+ :format_paragraph,
38
+ :format_verbatim,
39
+ ]
40
+
41
+ attr_accessor :html_class
42
+
43
+
44
+ ################################################ Setup {{{1
45
+ def initialize(deplate, args)
46
+ super
47
+ # Create OpenOffice compatible footnotes
48
+ @footnote_template = "sdfootnote%dsym"
49
+ @is_html_pageicons = false
50
+ @special_symbols = {
51
+ %{"} => %{&quot;},
52
+ %{>} => %{&gt;},
53
+ %{<} => %{&lt;},
54
+ %{&} => %{&amp;},
55
+ %{ } => lambda {|escaped| escaped ? "&nbsp;" : " "},
56
+ }
57
+ build_plain_text_rx
58
+ @encodings = {
59
+ 'latin1' => 'iso-8859-1',
60
+ }
61
+ end
62
+
63
+ def hook_post_write_file_html
64
+ @deplate.options.css.each do |name, anyway|
65
+ begin
66
+ src = @deplate.collected_css[name]
67
+ css = File.basename(src)
68
+ dest = @deplate.auxiliary_filename(css, true)
69
+ if anyway or !File.exist?(dest)
70
+ File.copy(src, dest)
71
+ log(["Copy css file", css])
72
+ end
73
+ rescue
74
+ log(["Can't copy css file", css], :error)
75
+ end
76
+ end
77
+ end
78
+
79
+ def hook_pre_body_flush_html
80
+ url = @variables["baseUrl"]
81
+ if url
82
+ fn = @deplate.output.top_heading.destination || @deplate.options.out
83
+ if fn && fn != "-"
84
+ fn = Pathname.new(fn).expand_path
85
+ unless fn.dirname.to_s == "."
86
+ pwd = Pathname.new(Dir.pwd).expand_path
87
+ fn = fn.relative_path_from(pwd).to_s.gsub(/\\/, "/")
88
+ fp = @variables["baseUrlStripDir"]
89
+ if fp
90
+ fn = fn.split(/\//)
91
+ fn = fn[fp.to_i..-1]
92
+ fn = File.join(*fn)
93
+ end
94
+ end
95
+ url += fn
96
+ # if @variables["useDublinCore"]
97
+ set_at(:pre, :head_identifier, head_meta_tag(%{name="DC.Identifier" content="%s"}) % url)
98
+ # else
99
+ # end
100
+ end
101
+ end
102
+
103
+ unless @is_html_pageicons
104
+ if @deplate.post_matter[@deplate.slot_by_name(:html_pageicons)]
105
+ consume_label('pageicons', true)
106
+ output_at(:post, :html_pageicons_beg, %{<div id="pageicons" class="pageicons">})
107
+ output_at(:post, :html_pageicons_end, %{</div>})
108
+ @is_html_pageicons = true
109
+ end
110
+ end
111
+
112
+ unless output_empty_at?(:body, :footnotes)
113
+ output_at(:body, :footnotes, :prepend, %{<div class="footnotes">})
114
+ output_at(:body, :footnotes, %{</div>})
115
+ end
116
+ end
117
+
118
+ def prepare
119
+ html_head
120
+
121
+ bodyOpts = @variables["bodyOptions"] || ""
122
+ output_at(:pre, :body_beg, %{<body #{bodyOpts}>\n<a name="#pagetop"></a>})
123
+
124
+ output_at(:post, :body_end, "</body>")
125
+ output_at(:post, :doc_end, "</html>")
126
+ end
127
+
128
+ def html_head
129
+ output_at(:pre, :doc_def, head_doctype)
130
+ output_at(:pre, :doc_beg, html_def)
131
+ output_at(:pre, :head_beg, "<head>")
132
+
133
+ t = @variables["encoding"] || "ISO-8859-1"
134
+ t = canonic_enc_name(t)
135
+ t = %{http-equiv="content-type" content="text/html; charset=#{t}"}
136
+ output_at(:pre, :head, head_meta_tag(t))
137
+
138
+ author = @deplate.get_clip('author')
139
+ author = clean_tags(author.elt) if author
140
+ desc = @variables['description']
141
+ kw = keywords
142
+ lang = html_lang(true)
143
+
144
+ date = @deplate.get_clip('date')
145
+ if date
146
+ date = date.elt
147
+ if date =~ /^\d\d(\d\d)$/
148
+ date = Time.local(date)
149
+ else
150
+ if date =~ /^(\w+)\s+(\d\d(\d\d))$/
151
+ date = "1-#$1-#$2"
152
+ end
153
+ begin
154
+ date = ParseDate.parsedate(date, true)
155
+ date = Time.local(*date)
156
+ rescue
157
+ log(["Can't parse date", @deplate.get_clip("date").elt], :error)
158
+ date = nil
159
+ end
160
+ end
161
+ end
162
+ date ||= Time.now
163
+ # date = date.xmlschema
164
+ date = xmlschema(date)
165
+
166
+ title = @deplate.get_clip("title")
167
+ title = clean_tags(title.elt) if title
168
+
169
+ if @variables["useDublinCore"]
170
+ output_at(:pre, :head_meta, head_meta_tag(%{name="DC.Title" content="%s"}) % title) if title
171
+ output_at(:pre, :head_meta, head_meta_tag(%{name="DC.Creator" content="%s"}) % author) if author
172
+ # DC.Subject
173
+ output_at(:pre, :head_meta, head_meta_tag(%{name="DC.Description" content="%s"}) % desc) if desc
174
+ # DC.Publisher, DC.Contributor
175
+ output_at(:pre, :head_meta, head_meta_tag(%{name="DC.Date" content="%s"}) % date) if date
176
+ # DC.Type, DC.Format, DC.Identifier, DC.Source
177
+ output_at(:pre, :head_meta, head_meta_tag(%{name="DC.Language" content="%s"}) % lang) if lang
178
+ # DC.Relation, DC.Coverage, DC.Rights
179
+ else
180
+ output_at(:pre, :head_meta, head_meta_tag(%{name="author" content="%s"}) % author) if author
181
+ output_at(:pre, :head_meta, head_meta_tag(%{name="description" content="%s"}) % desc) if desc
182
+ output_at(:pre, :head_meta, head_meta_tag(%{name="keywords" content="%s"}) % kw.join(", ")) if kw
183
+ output_at(:pre, :head_meta, head_meta_tag(%{name="language" content="%s"}) % lang) if lang
184
+ output_at(:pre, :head_meta, head_meta_tag(%{name="date" content="%s"}) % date) if date
185
+ end
186
+ output_at(:pre, :head_meta, head_meta_tag(%{name="generator" content="deplate.rb #{Deplate::Core.version}"})) unless @variables["noGenerator"]
187
+ md = @variables["metaDataExtra"]
188
+ output_at(:pre, :head_meta, md) if md
189
+
190
+ output_at(:pre, :head_title, %{<title>%s</title>} % title) if title
191
+
192
+ headExtra = @variables["headExtra"]
193
+ headExtra = headExtra.join("\n") if headExtra.kind_of?(Array)
194
+ output_at(:pre, :head_extra, headExtra) if headExtra and !headExtra.empty?
195
+
196
+ css = head_css
197
+ output_at(:pre, :css, css) unless css.empty?
198
+
199
+ styleExtra = @variables["styleExtra"]
200
+ if styleExtra
201
+ styleExtra = styleExtra.join("\n") if styleExtra.kind_of?(Array)
202
+ styleExtra = <<EOH
203
+ <style type="text/css">
204
+ <!--
205
+ #{styleExtra}
206
+ -->
207
+ </style>
208
+ EOH
209
+ output_at(:pre, :css, styleExtra)
210
+ end
211
+
212
+ shortcutIcon = @variables["shortcutIcon"]
213
+ output_at(:pre, :head_end, head_link_tag(%{rel="shortcut icon" href="#{shortcutIcon}" type="image/x-icon"})) if shortcutIcon
214
+ pageicon = @variables["pageIcon"]
215
+ output_at(:pre, :head_end, head_link_tag(%{rel="icon" href="#{pageicon}" type="image/x-icon"})) if pageicon
216
+
217
+ output_at(:pre, :html_relations, @deplate.invoke_service("navigation_links")) unless @variables["noPageNavigation"]
218
+
219
+ output_at(:pre, :head_end, @variables["explorerHack"])
220
+ output_at(:pre, :head_end, "</head>")
221
+ end
222
+
223
+ def head_meta_tag(text)
224
+ return %Q{<meta #{text}>}
225
+ end
226
+
227
+ def head_link_tag(text)
228
+ return %Q{<link #{text}>}
229
+ end
230
+
231
+ def xmlschema(time)
232
+ z = time.zone.scan(/([+-])(\d+):(\d+)/)[0]
233
+ z = z ? ("%s%02d:%02d" % z) : ""
234
+ if time.hour != 0 or time.min != 0 or time.sec != 0
235
+ time.strftime("%Y-%m-%dT%H:%M:%S" + z)
236
+ else
237
+ time.strftime("%Y-%m-%d")
238
+ end
239
+ end
240
+ private :xmlschema
241
+
242
+ def read_bib(bibfiles)
243
+ simple_bibtex_reader(bibfiles)
244
+ end
245
+
246
+ def open_tag(invoker, tag, opts=nil, other_args={})
247
+ args = invoker.args
248
+ single = other_args[:single] || false
249
+ no_id = other_args[:no_id] || false
250
+ opts ||= {}
251
+ args ||= {}
252
+ unless no_id
253
+ id = use_id(args, opts)
254
+ oid = opts['id']
255
+ if oid and oid != id
256
+ log(['ID mismatch', id, oid, opts, args], :error)
257
+ end
258
+ opts['id'] = encode_id(id) if id
259
+ # args = args.dup
260
+ args.delete('id')
261
+ end
262
+ id = opts['id']
263
+ unless consume_label(id)
264
+ opts = opts.dup
265
+ opts.delete('id')
266
+ end
267
+ cls = opts['class']
268
+ case cls
269
+ when Array
270
+ unless opts['class'].empty?
271
+ opts['class'] = opts['class'].join(' ')
272
+ end
273
+ when nil
274
+ opts['class'] = get_html_class(invoker)
275
+ end
276
+ opts = opts.collect do |k, v|
277
+ if v and !(v.empty?)
278
+ %{%s="%s"} % [k, v]
279
+ end
280
+ end
281
+ if single
282
+ opts << "/"
283
+ end
284
+ %{<%s>} % [tag, *opts].compact.join(" ")
285
+ end
286
+
287
+ def consume_label(label, warn=false)
288
+ if !label
289
+ return false
290
+ elsif @consumed_labels.include?(label)
291
+ log(['Duplicate label'], label, :error) if warn
292
+ return false
293
+ else
294
+ @consumed_labels << label
295
+ return true
296
+ end
297
+ end
298
+
299
+ def close_tag(invoker, tag)
300
+ %{</%s>} % tag
301
+ end
302
+
303
+ def inline_tag(invoker, tag, text, opts={})
304
+ [open_tag(invoker, tag, opts), text, close_tag(invoker, tag)].join
305
+ end
306
+
307
+ def wrap_text(text, args={})
308
+ args[:check] ||= lambda do |line|
309
+ line =~ /<[^>]*$/
310
+ end
311
+ super(text, args)
312
+ end
313
+
314
+
315
+ ################################################ Lists {{{1
316
+ def format_list_item(invoker, type, level, item, html_class=nil, explicit=false)
317
+ indent = format_indent(level, true)
318
+ body = item.body
319
+ body = wrap_text(body) if body
320
+ opts = {"class" => []}
321
+ html_class ||= item.style || get_html_class(invoker)
322
+ if html_class
323
+ opts["class"] << html_class
324
+ end
325
+ case type
326
+ when "Numbered", "Itemize"
327
+ ev = list_item_explicit_value(item, explicit)
328
+ if ev
329
+ opts["value"] = ev
330
+ else
331
+ case item.item
332
+ when "-"
333
+ opts["class"] << "dash"
334
+ when "+"
335
+ opts["class"] << "plus"
336
+ when "*"
337
+ opts["class"] << "asterisk"
338
+ when "�"
339
+ opts["class"] << "bullet"
340
+ end
341
+ end
342
+ li = open_tag(invoker, "li", opts)
343
+ # indent1 = format_indent(level + 1, true)
344
+ # return %{#{indent}#{li}\n#{indent1}#{body}}, %{#{indent}</li>}
345
+ body = indent_text(body, level + 1)
346
+ return %{#{indent}#{li}\n#{body}}, %{#{indent}</li>}
347
+ when "Description"
348
+ dt = open_tag(invoker, "dt", opts)
349
+ dd = open_tag(invoker, "dd", opts)
350
+ accum = []
351
+ accum << "#{dt}#{item.item}</dt>\n" if item.item
352
+ accum << "#{dd}\n"
353
+ accum << indent_text(body, 1) if body
354
+ return indent_text(accum.join, level), "#{indent}</dd>"
355
+ when "Paragraph"
356
+ return indent_text(%{<br class="itempara" />#{body}}, 2), nil
357
+ else
358
+ raise "Unknown list type: #{item.inspect}"
359
+ end
360
+ end
361
+
362
+ def format_list_env(invoker, type, level, what, subtype=nil)
363
+ indent = format_indent(level)
364
+ opts = {'class' => []}
365
+ html_class ||= get_html_class(invoker)
366
+ if html_class
367
+ opts["class"] << html_class
368
+ end
369
+ case type
370
+ when "Numbered"
371
+ case subtype
372
+ when "a"
373
+ opts["type"] = "a"
374
+ opts['class'] << 'alpha'
375
+ when "A"
376
+ opts["type"] = "A"
377
+ opts['class'] << 'Alpha'
378
+ # when "1"
379
+ # type = %{}
380
+ else
381
+ opts['class'] << 'numeric'
382
+ # type = %{}
383
+ end
384
+ tag = "ol"
385
+ when "Itemize"
386
+ tag = "ul"
387
+ when "Description"
388
+ tag = "dl"
389
+ else
390
+ raise "Unknown list type: #{type}"
391
+ end
392
+
393
+ case what
394
+ when :open
395
+ return indent + open_tag(invoker, tag, opts)
396
+ when :close
397
+ return indent + close_tag(invoker, tag)
398
+ end
399
+ end
400
+
401
+
402
+ ################################################ General {{{1
403
+ def format_environment(invoker, env, opts, text)
404
+ if text
405
+ ot = open_tag(invoker, env, opts)
406
+ ct = close_tag(invoker, env)
407
+ join_blocks([ot, text, "#{ct}\n"])
408
+ end
409
+ end
410
+
411
+ def get_html_class(invoker, default=nil)
412
+ html_class = [
413
+ invoker.args["htmlClass"],
414
+ invoker.styles_as_string,
415
+ ]
416
+ html_class.compact!
417
+ if invoker.respond_to?(:html_class)
418
+ hc = invoker.html_class
419
+ if invoker.respond_to?(:html_class=) and (!hc or hc.empty?)
420
+ invoker.html_class = default
421
+ html_class << default
422
+ end
423
+ if html_class.empty?
424
+ html_class << invoker.html_class
425
+ end
426
+ end
427
+ html_class.compact!
428
+ return html_class.empty? ? nil : html_class.join(" ")
429
+ end
430
+
431
+ def format_label(invoker, mode=nil, label=nil, with_id=true)
432
+ accum = []
433
+ label ||= invoker.label
434
+ label = use_labels(invoker.args, label, :with_id => with_id)
435
+ unless !label or label.empty?
436
+ case mode
437
+ when :before
438
+ for l in label
439
+ accum << %{<a name="#{l}">}
440
+ @open_labels << l
441
+ end
442
+ when :after
443
+ for l in label
444
+ if @open_labels.delete(l)
445
+ accum << "</a>"
446
+ end
447
+ end
448
+ when :closeOpen
449
+ while !@open_labels.empty?
450
+ l = @open_labels.pop
451
+ accum << format_label(invoker, :after)
452
+ end
453
+ # when :once
454
+ else
455
+ for l in label
456
+ text = if block_given? then yield(l) else "" end
457
+ accum << %{<a name="#{l}"></a>#{text}}
458
+ end
459
+ end
460
+ end
461
+ return accum.join
462
+ end
463
+
464
+ def format_figure(invoker, inline=false, elt=nil)
465
+ elt ||= invoker.elt
466
+ if inline
467
+ include_image(elt, invoker.args)
468
+ else
469
+ acc = []
470
+ fig = @deplate.msg("Figure")
471
+ caption = invoker.caption
472
+ if caption
473
+ capAbove = !(caption && caption.args && caption.args.include?("below"))
474
+ lev = invoker.level_as_string
475
+ # copts = ["", %{style="text-align=#{float_align_caption(invoker)};"}]
476
+ # cap = %{<p#{copts.join(" ")} class="caption">#{fig} #{lev}: #{caption.elt}</p>}
477
+ cap = %{<p class="caption">#{fig} #{lev}: #{caption.elt}</p>}
478
+ else
479
+ capAbove = false
480
+ end
481
+ #+++options: here/top etc.
482
+ acc << %{<div class="figure">}
483
+ if caption and capAbove
484
+ acc << cap
485
+ end
486
+ acc << include_image(elt, invoker.args)
487
+ if caption and !capAbove
488
+ acc << cap
489
+ end
490
+ acc << "</div>\n"
491
+ join_blocks(acc)
492
+ end
493
+ end
494
+
495
+ def include_image(file, args, inline=false)
496
+ o = []
497
+ w = args["w"] || args["width"]
498
+ o << %{width="#{w}"} if w
499
+ h = args["h"] || args["heigth"]
500
+ o << %{height="#{h}"} if h
501
+ o = o.join(" ")
502
+ f = file[0..-(File.extname(file).size + 1)]
503
+ alt = args["alt"]
504
+ if alt
505
+ alt.gsub!(/[\\"&<>]/) do |s|
506
+ case s
507
+ when '\\'
508
+ '\\\\'
509
+ else
510
+ plain_text(s)
511
+ end
512
+ end
513
+ else
514
+ alt = File.basename(file, '.*')
515
+ end
516
+ style = [args["style"]]
517
+ style << "inline" if inline
518
+ style = style.compact.join(", ")
519
+ for sfx in image_suffixes
520
+ fs = f + sfx
521
+ ff = @deplate.auxiliary_filename(fs)
522
+ fff = @deplate.auxiliary_filename(fs, true)
523
+ if File.exist?(fff)
524
+ return %{<img src="#{ff}" #{o} alt="#{alt}" class="#{style}" />}
525
+ end
526
+ end
527
+ return %{<img src="#{file}" alt="#{alt}" class="#{style}" />}
528
+ end
529
+
530
+ def image_suffixes
531
+ [".png", ".jpeg", ".jpg", ".gif", ".bmp"]
532
+ end
533
+
534
+ ################################################ Elements {{{1
535
+ def format_note(invoker)
536
+ marker = invoker.marker
537
+ case marker
538
+ when "#"
539
+ html_class = "note"
540
+ when "+"
541
+ html_class = "warning"
542
+ when "?"
543
+ html_class = "caution"
544
+ when "!"
545
+ html_class = "important"
546
+ else
547
+ log(["Unknown marker", marker], :error)
548
+ html_class = "note"
549
+ end
550
+ cls = %{ class="%s"} % html_class
551
+ join_blocks(["<div#{cls}><p#{cls}>", invoker.elt, "</p></div>\n"])
552
+ end
553
+
554
+ def format_table(invoker)
555
+ args = invoker.args
556
+ elt = invoker.elt
557
+ caption = invoker.caption
558
+ level_as_string = invoker.level_as_string
559
+ style = invoker.styles_as_string || @variables["tableStyle"]
560
+ style.gsub!(/[,;]+/, " ") if style
561
+ html_class = style || get_html_class(invoker)
562
+ capAbove = !(caption && caption.args && caption.args.include?("below"))
563
+ clss = html_class ? html_class : "standard"
564
+ clsss = %{ class="#{clss}"}
565
+ opts = format_particle(:table_args, invoker)
566
+ halfindent = " "
567
+ indent = halfindent * 2
568
+
569
+ acc = []
570
+ unless args[:dontWrapTable]
571
+ acc << %{<div class="#{['table', style].compact.join(' ')}">}
572
+ end
573
+ acc << %{<table#{clsss}#{opts}>}
574
+ if caption
575
+ if !capAbove
576
+ capOpts = [%{ align="bottom"}]
577
+ else
578
+ # capOpts = [""]
579
+ capOpts = []
580
+ end
581
+ # capOpts << %{style="text-align=#{float_align_caption(invoker)};"}
582
+ cap = %{#{@deplate.msg("Table")} #{level_as_string}: #{caption.elt}}
583
+ acc << %{<caption#{capOpts.join(" ")}>#{cap}</caption>}
584
+ end
585
+
586
+ acc_head = []
587
+ acc_foot = []
588
+ acc_body = []
589
+ elt.each_with_index do |r, n|
590
+ if r.head
591
+ row = formatted_table_row(n, r, args, indent, clss, "th")
592
+ if row
593
+ table_add_row(acc_head, row, %{head #{style}}, :indent => halfindent)
594
+ end
595
+ elsif r.foot
596
+ row = formatted_table_row(n, r, args, indent, clss, "td")
597
+ if row
598
+ table_add_row(acc_foot, row, %{foot #{style}}, :indent => halfindent)
599
+ end
600
+ elsif r.high
601
+ row = formatted_table_row(n, r, args, indent, clss, "td")
602
+ table_add_row(acc_body, row, %{high #{style}}, :indent => halfindent) if row
603
+ elsif r.is_ruler
604
+ else
605
+ row = formatted_table_row(n, r, args, indent, clss)
606
+ table_add_row(acc_body, row, clss, :indent => halfindent) if row
607
+ end
608
+ end
609
+
610
+ unless acc_head.empty?
611
+ acc << %{#{halfindent}<thead#{clsss}>}
612
+ acc << acc_head
613
+ acc << "#{halfindent}</thead>"
614
+ end
615
+ unless acc_foot.empty?
616
+ acc << %{#{halfindent}<tfoot#{clsss}>}
617
+ acc << acc_foot
618
+ acc << "#{halfindent}</tfoot>"
619
+ end
620
+ acc << acc_body
621
+
622
+ acc << "</table>"
623
+ note = invoker.args["note"]
624
+ if note
625
+ note = @deplate.parse_and_format(invoker, note)
626
+ nopts = ['', %{class="tableNote"}]
627
+ align = float_align_note(invoker)
628
+ nopts << %{style="text-align=#{align};"} if align
629
+ acc << %{<div#{nopts.join(' ')}>#{note}</div>}
630
+ end
631
+ acc << "</div>\n" unless args[:dontWrapTable]
632
+ acc << ""
633
+
634
+ join_blocks(acc)
635
+ end
636
+
637
+ def table_add_row(acc, row, clss, args)
638
+ tag = args[:tag] || "tr"
639
+ indent = args[:indent] || " "
640
+ dblindent = indent * 2
641
+ row = row.join("\n#{dblindent}")
642
+ acc << %{#{indent}<#{tag} class="#{clss}">}
643
+ acc << %{#{dblindent}#{row}}
644
+ acc << "#{indent}</#{tag}>"
645
+ end
646
+
647
+ def format_heading(invoker)
648
+ l = format_label(invoker, nil, nil, false)
649
+ level = invoker.level
650
+ args = invoker.args
651
+ elt = invoker.elt
652
+ html_args = invoker.html_args || ''
653
+ id = invoker.get_id
654
+ if consume_label(id)
655
+ html_args += %{ id="#{id}"}
656
+ end
657
+ if level > 0 and level <= 6
658
+ hd = "h#{level}"
659
+ if invoker.plain_caption?
660
+ ls = ""
661
+ else
662
+ ls = invoker.level_as_string + "&nbsp;"
663
+ end
664
+ %{\n<#{hd}#{html_args}>#{l}#{ls}#{elt}</#{hd}>\n}
665
+ else
666
+ l += format_label(invoker, :string, [id]) if id
667
+ "\n#{l}#{elt}"
668
+ end
669
+ end
670
+
671
+ def format_list(invoker)
672
+ printable_list(invoker) + "\n"
673
+ end
674
+
675
+ def format_break(invoker)
676
+ format_pagebreak(invoker, "break")
677
+ end
678
+
679
+ def format_anchor(invoker)
680
+ format_label(invoker, :once)
681
+ end
682
+
683
+ def format_paragraph(invoker)
684
+ # html_class = get_html_class(invoker)
685
+ # cls = html_class.empty? ? "" : (%{ class="%s"} % html_class)
686
+ # join_blocks(["<p#{cls}>", indent_text(invoker.elt, 1), "</p>\n"])
687
+ # [open_tag(invoker, "p"), invoker.elt, close_tag(invoker, "p"), "\n"].join
688
+ [open_tag(invoker, "p"), wrap_text(invoker.elt), close_tag(invoker, "p"), "\n"].join
689
+ end
690
+
691
+
692
+ ################################################ Regions {{{1
693
+ def format_verbatim(invoker, text=nil)
694
+ text ||= invoker.elt
695
+ format_environment(invoker, "pre", {"class"=>"verbatim"}, plain_text(text, :pre))
696
+ end
697
+
698
+ def format_abstract(invoker)
699
+ format_environment(invoker, %{blockquote}, {"class"=>"abstract"}, invoker.elt)
700
+ end
701
+
702
+ def format_quote(invoker)
703
+ if invoker.args["long"]
704
+ format_environment(invoker, %{blockquote}, {"class"=>"quote"}, invoker.elt)
705
+ else
706
+ format_environment(invoker, %{blockquote}, {"class"=>"longquote"}, invoker.elt)
707
+ end
708
+ end
709
+
710
+ def format_header(invoker)
711
+ format_header_or_footer(invoker, :pre, :header, "HEADER", "header")
712
+ nil
713
+ end
714
+
715
+ def format_footer(invoker)
716
+ format_header_or_footer(invoker, :post, :footer, "FOOTER", "footer")
717
+ nil
718
+ end
719
+
720
+
721
+ ################################################ Commands {{{1
722
+ def format_title(invoker)
723
+ acc = []
724
+ acc << %{<div class="title">}
725
+ for i, c in [["title", %{<p class="title">%s</p>}],
726
+ ["author", %{<p class="author">%s</p>}],
727
+ ["authornote", %{<p class="authornote">%s</p>}],
728
+ ["date", %{<p class="date">%s</p>}]]
729
+ ii = @deplate.get_clip(i)
730
+ acc << c % ii.elt if ii
731
+ end
732
+ acc << %{</div>}
733
+ acc << format_pagebreak(invoker, "title") if invoker.args["page"]
734
+ join_blocks(acc)
735
+ end
736
+
737
+ alias :format_IMG :format_figure
738
+
739
+ alias :format_MAKETITLE :format_title
740
+
741
+ def format_MAKEBIB(invoker)
742
+ format_bibliography(invoker) do |key, labels, text|
743
+ consume_label(key, true)
744
+ %{<p id="#{key}" class="bib">#{labels}#{text}</p>}
745
+ end
746
+ end
747
+
748
+ def format_IDX(invoker)
749
+ invoker.elt
750
+ end
751
+
752
+ def format_pagebreak(invoker, html_class=nil, major=false)
753
+ if html_class
754
+ opt = %{ class="#{html_class}"}
755
+ else
756
+ opt = %{ class="pagebreak"}
757
+ end
758
+ # poor man's pagebreak
759
+ "<hr#{opt} />\n"
760
+ end
761
+
762
+
763
+ ################################################ Particles {{{1
764
+ def format_emphasize(invoker, text)
765
+ inline_tag(invoker, "em", text)
766
+ end
767
+
768
+ def format_code(invoker, text)
769
+ inline_tag(invoker, "code", plain_text(text, :code))
770
+ end
771
+
772
+ def format_url(invoker, name, dest, anchor, literal=false)
773
+ dest = Deplate::HyperLink.url_anchor(dest, anchor)
774
+ dest.gsub!(/&/, "&amp;")
775
+ inline_tag(invoker, "a", name, href_args(invoker, dest))
776
+ end
777
+
778
+ def format_wiki(invoker, name, dest, anchor)
779
+ dest = Deplate::HyperLink.url_anchor(dest, anchor)
780
+ # dest.gsub!(/&/, "&amp;")
781
+ inline_tag(invoker, "a", name, href_args(invoker, dest))
782
+ end
783
+
784
+ def href_args(invoker, dest)
785
+ args = {"href" => dest}
786
+ target = invoker.args['target']
787
+ if target
788
+ args['target'] = target
789
+ end
790
+ return args
791
+ end
792
+ private :href_args
793
+
794
+ def format_symbol(invoker, text)
795
+ case text
796
+ when "<-"
797
+ return "&larr;"
798
+ when "->"
799
+ return "&rarr;"
800
+ when "<=", "<<<"
801
+ return "&lArr;"
802
+ when "=>", ">>>"
803
+ return "&rArr;"
804
+ when "<->"
805
+ return "&harr;"
806
+ when "<=>"
807
+ return "&hArr;"
808
+ when "!="
809
+ return "&ne;"
810
+ when "~~"
811
+ return "&asymp;"
812
+ when "..."
813
+ return "&hellip;"
814
+ when "--"
815
+ return "&ndash;"
816
+ when "=="
817
+ return "&equiv;"
818
+ when "+++", "###", "???", "!!!"
819
+ m = plain_text(text)
820
+ return %{<span class="marker"><em class="marker">#{m}</em></span>}
821
+ # when "<~"
822
+ # return ""
823
+ # when "~>"
824
+ # return ""
825
+ # when "<~>"
826
+ # return ""
827
+ else
828
+ return plain_text(text)
829
+ end
830
+ end
831
+
832
+ def doublequote_open(invoker)
833
+ "&ldquo;"
834
+ end
835
+
836
+ def doublequote_close(invoker)
837
+ "&rdquo;"
838
+ end
839
+
840
+ def singlequote_open(invoker)
841
+ "&lsquo;"
842
+ end
843
+
844
+ def singlequote_close(invoker)
845
+ "&rsquo;"
846
+ end
847
+
848
+
849
+ ################################################ Macros {{{1
850
+ def format_index(invoker, idx)
851
+ if idx
852
+ return format_label(invoker, :string, [idx.label])
853
+ else
854
+ return ""
855
+ end
856
+ end
857
+
858
+ def format_footnote(invoker)
859
+ elt = invoker.elt
860
+ if elt and elt.elt and elt.elt.consumed
861
+ fn = elt.elt
862
+ lab = fn.label
863
+ if !@deplate.footnotes_used.include?(lab)
864
+ idx = @deplate.footnote_last_idx +=1
865
+ hclass = "sdfootnoteanc"
866
+ id = "sdfootnote%d" % idx
867
+ name = "sdfootnote%danc" % idx
868
+ href = @footnote_template % idx
869
+ lab = [href]
870
+ fn.n = idx
871
+ fn.label = lab
872
+ @deplate.footnotes_used << lab
873
+ invoker.container.postponed_format << Proc.new do |container|
874
+ consume_label(id, true)
875
+ t = [%{<div id="#{id}">},
876
+ %{<p class="sdfootnote">},
877
+ %{<a class="sdfootnotesym" name="#{href}" href="##{name}">#{idx}</a>},
878
+ %{#{fn.body}},
879
+ %{</p></div>}]
880
+ output_at(:body, :footnotes, t.join("\n"))
881
+ end
882
+ else
883
+ href = @footnote_template % fn.n
884
+ end
885
+ return %{<a class="sdfootnoteanc" name="#{name}" href="##{href}">#{fn.n}</a>}
886
+ else
887
+ return ""
888
+ end
889
+ end
890
+
891
+ def format_ref(invoker)
892
+ text = invoker.text || ""
893
+ f = @deplate.get_filename_for_label(invoker, text)
894
+ if f
895
+ # if invoker.args['obj'] and (o = @deplate.label_aliases[text])
896
+ o = @deplate.label_aliases[text]
897
+ if o
898
+ l = o.level_as_string
899
+ else
900
+ l = @deplate.labels[text]
901
+ end
902
+ if l
903
+ t = plain_text(l)
904
+ else
905
+ t = @variables["refButton"] || "[&rArr;]"
906
+ end
907
+ return %{&nbsp;<a href="#{URI.escape(f)}##{URI.escape(text)}" class="ref">#{t}</a>}
908
+ end
909
+ end
910
+
911
+ def format_linebreak(invoker)
912
+ open_tag(invoker, "br", nil, :single => true)
913
+ end
914
+
915
+ # def format_cite(invoker)
916
+ # container = invoker.container
917
+ # args = invoker.args
918
+ # n = args["n"]
919
+ # p = args["p"]
920
+ # np = args["np"]
921
+ # y = args["y"]
922
+ # acc = []
923
+ # pmsg = @deplate.msg("p.\\ ")
924
+ # for c in invoker.elt
925
+ # cc = bib_entry(c)
926
+ # if cc
927
+ # yr = cc.assoc("year")
928
+ # yr = if yr then yr[1] else "" end
929
+ # if p
930
+ # p = @deplate.parse_and_format(container, "#{pmsg}#{p}")
931
+ # yr += ": #{p}"
932
+ # # yr += ": " + p if p
933
+ # end
934
+ # if y
935
+ # acc << referenced_bib_entry(invoker, c, yr)
936
+ # else
937
+ # nm = cc.assoc("author") || cc.assoc("editor")
938
+ # if nm
939
+ # nm = nm[1]
940
+ # nm = nm.gsub(/\s+/, " ").split(" and ").collect do |a|
941
+ # a.scan(/\w+$/)
942
+ # end
943
+ # nm = nm.join(", ")
944
+ # acc << referenced_bib_entry(invoker, c, [nm, yr].join(" "))
945
+ # else
946
+ # acc << referenced_bib_entry(invoker, c, c)
947
+ # end
948
+ # end
949
+ # end
950
+ # end
951
+ # n &&= n + " "
952
+ # acc = acc.join("; ")
953
+ # if np
954
+ # return %{#{n}#{acc}}
955
+ # else
956
+ # return %{&nbsp;(#{n}#{acc})}
957
+ # end
958
+ # end
959
+
960
+ def referenced_bib_entry(invoker, key, text)
961
+ hd = @deplate.options.html_makebib_heading
962
+ f = hd ? hd.top_heading.output_file_name(:relative => invoker.container) : ""
963
+ %{<a href="#{f}##{encode_id(key)}">#{text}</a>}
964
+ end
965
+ private :referenced_bib_entry
966
+
967
+ def format_subscript(invoker)
968
+ inline_tag(invoker, "sub", invoker.elt)
969
+ end
970
+
971
+ def format_superscript(invoker)
972
+ inline_tag(invoker, "sup", invoker.elt)
973
+ end
974
+
975
+ # this doesn't work with IExplorer and others
976
+ def format_stacked(invoker)
977
+ elt = invoker.elt
978
+ sup = %{<span style="display:table-row"><sup style="display:table-cell">#{elt[0]}</sup></span>}
979
+ sub = %{<span style="display:table-row"><sub style="display:table-cell">#{elt[1]}</sub></span>}
980
+ stk = %{<span style="font-size: 80%; position:relative; top:0.5em; display:inline-table">#{sup}#{sub}</span>}
981
+ return stk
982
+ end
983
+
984
+ def format_pagenumber(invoker)
985
+ return ""
986
+ end
987
+
988
+
989
+ protected ######################################## private methods {{{1
990
+ ################################################ General {{{1
991
+ def clean_tags(text)
992
+ if text
993
+ t = text.gsub(/\<[^>]*?\>/, '')
994
+ t.gsub!(/^\s*$/, '')
995
+ t.gsub!(/^\n\s*/, '')
996
+ t.gsub!(/\n\s*$/, '')
997
+ t
998
+ end
999
+ end
1000
+
1001
+ def format_header_or_footer(invoker, type, slot, html_type, html_class)
1002
+ args = invoker.args
1003
+ acc = []
1004
+ acc << %{<div type="#{html_type}" class="#{html_class}">}
1005
+ for e in invoker.elt
1006
+ e.html_class = html_class
1007
+ e.args[:dontWrapTable] = true
1008
+ acc << e.format_current
1009
+ end
1010
+ acc << %{</div>}
1011
+ output_at(type, slot, *acc)
1012
+ nil
1013
+ end
1014
+
1015
+
1016
+ ################################################ Head {{{1
1017
+ def head_css
1018
+ csso = @variables["css"]
1019
+ if csso
1020
+ csss = csso.split(/\s+/)
1021
+ else
1022
+ csss = []
1023
+ end
1024
+ cls = @variables["class"]
1025
+ if cls
1026
+ csss << cls + ".css"
1027
+ end
1028
+ acc = []
1029
+ csss.each_with_index do | f, i |
1030
+ css, media = f.split(/\|/)
1031
+ if css =~ /^\+/
1032
+ css = css[1..-1]
1033
+ with_title = false
1034
+ else
1035
+ with_title = true
1036
+ end
1037
+ cssName = File.basename(css, ".css")
1038
+ cssFile = @deplate.auxiliary_filename(css)
1039
+ opts = [%{rel="stylesheet" type="text/css" href="#{URI.escape(cssFile)}"}]
1040
+ opts << %{title="#{cssName}"} if with_title
1041
+ opts << %{media="#{media}"} if media
1042
+ acc << head_link_tag(opts.join(" "))
1043
+ end
1044
+ cssExtra = @variables["cssExtra"]
1045
+ acc << cssExtra if cssExtra
1046
+ return acc.join("\n")
1047
+ end
1048
+
1049
+ def head_doctype
1050
+ return %Q{<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">}
1051
+ end
1052
+
1053
+ def html_lang(stripped=false)
1054
+ lang = @deplate.options.messages.prop('lang', self)
1055
+ if lang
1056
+ return stripped ? lang : %{lang="#{lang}"}
1057
+ end
1058
+ end
1059
+
1060
+ def html_def
1061
+ acc = []
1062
+ acc << html_lang
1063
+ acc << @variables["htmlDefEtc"] if @variables["htmlDefEtc"]
1064
+ if acc.empty?
1065
+ return "<html>"
1066
+ else
1067
+ return "<html #{acc.join(" ")}>"
1068
+ end
1069
+ end
1070
+
1071
+
1072
+ ################################################ List of ... {{{1
1073
+ def format_list_of_contents(invoker)
1074
+ format_list_of(invoker, "Table of Contents", @deplate.table_of_contents, "hd",
1075
+ :flat => false, :html_class => "toc")
1076
+ end
1077
+
1078
+ alias :format_list_of_toc :format_list_of_contents
1079
+
1080
+ def format_list_of_minitoc(invoker)
1081
+ data = @deplate.table_of_contents.find_all {|e| e.level == 1}
1082
+ format_list_of(invoker, "Contents", data, "hd",
1083
+ :flat => false, :img => @variables["navGif"],
1084
+ :html_class => "minitoc") do |hd|
1085
+ hd.args["shortcaption"] || hd.args["id"]
1086
+ end
1087
+ end
1088
+
1089
+ def format_list_of_tables(invoker)
1090
+ format_list_of(invoker, "List of Tables", @deplate.table_of_tables, "tab",
1091
+ :flat => true, :html_class => "lot")
1092
+ end
1093
+
1094
+ def format_list_of_figures(invoker)
1095
+ @html_class = "lof"
1096
+ format_list_of(invoker, "List of Figures", @deplate.table_of_figures, "fig",
1097
+ :flat => true, :html_class => "lof")
1098
+ end
1099
+
1100
+ def format_list_of_index(invoker)
1101
+ format_the_index(invoker, "Index", @deplate.index, "idx",
1102
+ true, :html_class => "index")
1103
+ end
1104
+
1105
+ def format_list_of(invoker, name, data, prefix, other_args)
1106
+ args = invoker.args
1107
+ flat = other_args[:flat] || false
1108
+ img = other_args[:img] || nil
1109
+ img = %{<img src="#{img}" border="0" alt="" />} if img
1110
+ html_class = get_html_class(invoker, other_args[:html_class])
1111
+ name = args["title"] || name
1112
+ id = name.gsub(/\W/, "_")
1113
+
1114
+ acc = []
1115
+ consume_label(id, true)
1116
+ consume_label("#{id}Block", true)
1117
+ acc << %{<div id="%s">%s\n<div id="%sBlock" class="%s">} % [id, img, id, html_class]
1118
+ unless args["plain"] || args["noTitle"]
1119
+ ti = @deplate.msg(name)
1120
+ acc << %{<h1 class="%s">%s%s</h1>} % [html_class, format_label(invoker), ti]
1121
+ end
1122
+
1123
+ ll = 1
1124
+ levels = args['levels']
1125
+ if levels
1126
+ range_from, range_to, rest = levels.split(/\.\./)
1127
+ if rest
1128
+ log(['Malformed range', levels], :error)
1129
+ end
1130
+ end
1131
+ range_from ||= args['min']
1132
+ if range_from
1133
+ range_from = range_from.to_i
1134
+ end
1135
+ range_to ||= args['max']
1136
+ if range_to
1137
+ range_to = range_to.to_i
1138
+ end
1139
+ top = args['top']
1140
+ if top
1141
+ top = /^#{Regexp.escape(top)}/
1142
+ end
1143
+ sub = args['sub']
1144
+ if sub
1145
+ sub = /^#{Regexp.escape(invoker.level_as_string)}\./
1146
+ end
1147
+ accData = []
1148
+ for hd in data
1149
+ if hd.nil? or hd.args["noList"]
1150
+ next
1151
+ end
1152
+ if range_from and hd.level < range_from
1153
+ next
1154
+ end
1155
+ if range_to and hd.level > range_to
1156
+ next
1157
+ end
1158
+ if top and hd.level_as_string !~ top
1159
+ next
1160
+ end
1161
+ if sub and hd.level_as_string !~ sub
1162
+ next
1163
+ end
1164
+ l = if flat then 1 else hd.level end
1165
+ f = hd.output_file_name(:relative => invoker)
1166
+ d = f + "#" + @deplate.elt_label(prefix, hd.level_as_string)
1167
+ v = nil
1168
+ if block_given?
1169
+ v = yield(hd)
1170
+ end
1171
+ unless v
1172
+ v = hd.caption ? hd.caption.elt : hd.elt.dup
1173
+ end
1174
+ # v.gsub!(/<a name=".*?"><\/a>/, "")
1175
+ v = clean_tags(v)
1176
+ v = [hd.level_as_string, v].join(" ") unless hd.plain_caption?
1177
+ b = format_url(invoker, v, d, nil, true)
1178
+ s = Deplate::ListItem.new(nil, b, "Itemize", "Itemize", l, 0, true)
1179
+ s.style = html_class
1180
+ accData << s
1181
+ end
1182
+ acc << printable_list(invoker, accData)
1183
+ acc << %{</div></div>}
1184
+ join_blocks(acc)
1185
+ end
1186
+
1187
+ def format_the_index(invoker, name, data, prefix="", flat=false, other_args={})
1188
+ html_class = other_args[:html_class] || "index"
1189
+ accum = []
1190
+ chars = []
1191
+
1192
+ # accum << format_list_env(invoker, "Description", 0, :open)
1193
+ for n, arr in sort_index_entries(data)
1194
+ cht = get_first_char(n, true)
1195
+ if !chars.include?(cht)
1196
+ chars << cht
1197
+ lab = format_label(invoker, :string, [format_index_hd_label(cht)])
1198
+ accum << format_list_env(invoker, "Description", 0, :close) unless accum.empty?
1199
+ accum << %{<h2 class="%s">%s%s</h2>} % [html_class, lab, cht]
1200
+ accum << format_list_env(invoker, "Description", 0, :open)
1201
+ end
1202
+ acc = []
1203
+ for i in arr
1204
+ ff = @deplate.dest
1205
+ if i.file or i.level_as_string
1206
+ f = i.file || invoker.output_file_name(:level_as_string => i.level_as_string,
1207
+ :relative => invoker)
1208
+ if f == ff
1209
+ f = ""
1210
+ l = i.level_as_string
1211
+ if l and !l.empty?
1212
+ t = l
1213
+ elsif @deplate.options.multi_file_output
1214
+ t = @variables["refButton"] || "[&rArr;]"
1215
+ else
1216
+ t = "I"
1217
+ end
1218
+ else
1219
+ t = @deplate.file_with_suffix(f, "", true)
1220
+ end
1221
+ acc << format_url(invoker, t, f, i.label, true)
1222
+ else
1223
+ log(["Index: Neither file nor level defined: dropping", i.label], :error)
1224
+ end
1225
+ end
1226
+ l = format_label(invoker, :string, [format_index_entry_label(invoker, n)])
1227
+ s = Deplate::ListItem.new(l + plain_text(n), acc.join(", "))
1228
+ accum += format_list_item(invoker, "Description", 0, s)
1229
+ end
1230
+ accum << format_list_env(invoker, "Description", 0, :close)
1231
+
1232
+ acc = []
1233
+ acc << %{<p class="%stoc">} % html_class
1234
+ for c in chars
1235
+ l = format_url(invoker, c, "", format_index_hd_label(c), true)
1236
+ acc << l
1237
+ end
1238
+ acc << %{</p>}
1239
+ acc << accum.join("\n")
1240
+ join_blocks(acc)
1241
+ end
1242
+
1243
+ def format_index_entry_label(invoker, text)
1244
+ return "idxEntry00" + text.gsub(/\W/, "00")
1245
+ end
1246
+
1247
+ def format_index_hd_label(char)
1248
+ return "hdIdx#{char}"
1249
+ end
1250
+
1251
+
1252
+ ################################################ Table {{{1
1253
+ def table_args(invoker)
1254
+ args = invoker.args
1255
+ caption = invoker.caption
1256
+ opts = [nil]
1257
+ align = float_align(invoker)
1258
+ case align
1259
+ when "center"
1260
+ when "right"
1261
+ when "left"
1262
+ end
1263
+ opts << %{align="#{align}"} if align
1264
+ width = args["width"] || @variables["tableWidth"]
1265
+ opts << %{width="#{width}"} if width
1266
+ opts << %{summary="#{caption.elt}"} if caption and caption.elt
1267
+ return opts.join(" ")
1268
+ end
1269
+
1270
+ def float_align(invoker)
1271
+ args = invoker.args
1272
+ args["align"] || @variables["floatAlign"]
1273
+ # || "center"
1274
+ end
1275
+
1276
+ def float_align_caption(invoker)
1277
+ float_align(invoker)
1278
+ # || "left"
1279
+ end
1280
+
1281
+ def float_align_note(invoker)
1282
+ float_align(invoker)
1283
+ # || "left"
1284
+ end
1285
+
1286
+ def formatted_table_row(n, row, args, indent, html_class=nil, thistag=nil)
1287
+ colwidths = Deplate::Core.props(args["cols"], "w")
1288
+ coljusts = Deplate::Core.props(args["cols"], "j")
1289
+ rowheight = Deplate::Core.props(args["rows"], "h")
1290
+ t = []
1291
+ row.cols.each_with_index do |cell, i|
1292
+ case cell
1293
+ when :join_left, :join_above
1294
+ when :ruler, :noruler
1295
+ return nil
1296
+ else
1297
+ c = cell.cell
1298
+ if thistag
1299
+ tag = thistag
1300
+ else
1301
+ if row.head
1302
+ tag = "th"
1303
+ else
1304
+ tag = "td"
1305
+ end
1306
+ end
1307
+
1308
+ opts = []
1309
+ opts << if row.head
1310
+ %{ class="head #{html_class}"}
1311
+ elsif row.foot
1312
+ %{ class="foot #{html_class}"}
1313
+ elsif cell.high or row.high
1314
+ %{ class="high #{html_class}"}
1315
+ else
1316
+ %{ class="#{html_class}"}
1317
+ end
1318
+
1319
+ styles = []
1320
+ w = colwidths[i]
1321
+ if w and !w.empty?
1322
+ styles << %{width:%s} % w
1323
+ end
1324
+ j = coljusts[i]
1325
+ if j and !j.empty?
1326
+ styles << %{text-align:%s} % j
1327
+ end
1328
+ h = rowheight[n]
1329
+ if h and !h.empty?
1330
+ styles << %{height:%s} % h
1331
+ end
1332
+
1333
+ if styles.empty?
1334
+ styles = ""
1335
+ else
1336
+ opts << %{style="%s"} % styles.join("; ")
1337
+ end
1338
+
1339
+ if cell.span_x > 1
1340
+ opts << %{colspan="#{cell.span_x}"}
1341
+ end
1342
+ if cell.span_y > 1
1343
+ opts << %{rowspan="#{cell.span_y}"}
1344
+ end
1345
+
1346
+ # t << "<#{tag}#{opts.join(" ")}>#{indented(c, indent)}\n#{indent}</#{tag}>"
1347
+ t << "<#{tag}#{opts.join(" ")}>#{c}</#{tag}>"
1348
+ end
1349
+ end
1350
+ t
1351
+ end
1352
+
1353
+ def indented(text, indent)
1354
+ return text.collect do |l|
1355
+ indent + l
1356
+ end
1357
+ end
1358
+
1359
+
1360
+ public
1361
+ ################################################ navigation bar {{{1
1362
+ def format_navigation_bar(invoker, type, slot, bartype, first=false, last=false)
1363
+ idx, first, last = navbar_output_index(invoker, first, last)
1364
+
1365
+ nomenu = invoker.args['noNavMenu'] || @variables['noNavMenu']
1366
+ nobuttons = invoker.args['noNavButtons'] || @variables['noNavButtons']
1367
+
1368
+ navbar_begin(type, slot, idx)
1369
+ navbar_menu(type, slot, idx, bartype) unless nomenu
1370
+ unless nobuttons
1371
+ urlp, prv = navbar_button_prev(type, slot, idx, bartype, !first && idx > 0)
1372
+ url, home = navbar_button_home(type, slot, idx, bartype, idx > 0)
1373
+ urln, nxt = navbar_button_next(type, slot, idx, bartype, !last)
1374
+
1375
+ case bartype
1376
+ when :top, :inline
1377
+ if urlp
1378
+ titp = @deplate.options.heading_names[idx - 1]
1379
+ link_prev = head_link_tag(%{rel="previous" href="#{urlp}" title="#{clean_tags(titp)}"})
1380
+ set_at(:pre, :htmlsite_prev, link_prev)
1381
+ end
1382
+ if urln
1383
+ titn = @deplate.options.heading_names[idx + 1]
1384
+ link_next = head_link_tag(%{rel="next" href="#{urln}" title="#{clean_tags(titn)}"})
1385
+ set_at(:pre, :htmlsite_next, link_next)
1386
+ urlspace = urln
1387
+ else
1388
+ urlspace = url
1389
+ end
1390
+ if url
1391
+ tit = @deplate.options.heading_names[0]
1392
+ link_up = head_link_tag(%{rel="up" href="#{url}" title="#{clean_tags(tit)}"})
1393
+ set_at(:pre, :htmlsite_up, link_up)
1394
+ end
1395
+ unless bartype == :inline or @variables["noBindKeys"]
1396
+ output_at(:body, :navbar_js, html_navigation_keys({"next" => urlspace}, ""))
1397
+ end
1398
+ else
1399
+ if (first or idx == 0) and !@variables["noNavigationNote"]
1400
+ output_at(type, slot, @deplate.invoke_service("navigation_note"))
1401
+ end
1402
+ end
1403
+ end
1404
+ navbar_end(type, slot, idx)
1405
+ end
1406
+
1407
+ def navbar_button_prev(type, slot, idx, bartype, ok)
1408
+ if ok
1409
+ text = @variables["prevButton"] || @deplate.formatter.plain_text("<<")
1410
+ urlp = navbar_guess_file_name(idx - 1, idx, bartype)
1411
+ ak = bartype == :top ? %{ accesskey="B"} : ""
1412
+ prv = %{<a class="navbarUrl" title="Previous" href="#{urlp}"#{ak}>#{text}</a>}
1413
+ else
1414
+ urlp = nil
1415
+ end
1416
+ unless urlp
1417
+ prv = "&nbsp;"
1418
+ end
1419
+ navbar_add_element(type, slot, idx, prv, "navbar")
1420
+ return urlp, prv
1421
+ end
1422
+
1423
+ def navbar_button_home(type, slot, idx, bartype, ok)
1424
+ if ok or @variables["homeShowAlways"]
1425
+ text = @variables["homeButton"] || "[-]"
1426
+ url = navbar_guess_file_name(0, idx, bartype) || "#pagetop"
1427
+ ak = [:top, "navbar"].include?(bartype) ? %{ accesskey="H"} : ""
1428
+ hc = ["navbar"].include?(bartype) ? "navBar" : "navbarUrl"
1429
+ home = %{<a class="#{hc}" title="Home" href="#{url}"#{ak}>#{text}</a>}
1430
+ else
1431
+ url = nil
1432
+ end
1433
+ unless url
1434
+ home = "&nbsp;"
1435
+ end
1436
+ navbar_add_element(type, slot, idx, home, "navbar")
1437
+ return url, home
1438
+ end
1439
+
1440
+ def navbar_button_next(type, slot, idx, bartype, ok)
1441
+ if ok
1442
+ text = @variables["nextButton"] || @deplate.formatter.plain_text(">>")
1443
+ urln = navbar_guess_file_name(idx + 1, idx, bartype)
1444
+ ak = bartype == :top ? %{ accesskey="N"} : ""
1445
+ nxt = %{<a class="navbarUrl" title="Next" href="#{urln}"#{ak}>#{text}</a>}
1446
+ else
1447
+ urln = nil
1448
+ end
1449
+ unless urln
1450
+ nxt = "&nbsp;"
1451
+ end
1452
+ navbar_add_element(type, slot, idx, nxt, "navbar")
1453
+ return urln, nxt
1454
+ end
1455
+
1456
+ def navbar_menu(type, slot, idx, bartype)
1457
+ unless @deplate.options.navmenu
1458
+ navmenu = [%{<form action=""><select class="navmenu" name="Contents"
1459
+ onChange="self.location.href=this.form.Contents.options[this.form.Contents.options.selectedIndex].value">},
1460
+ %{<option value="">[ #{@deplate.msg("Contents")} ]</option>},
1461
+ %{<option value="">------------------------</option>}]
1462
+
1463
+ acc = []
1464
+ @variables["@contents"] ||= acc
1465
+ @deplate.each_heading(:top) do |hd, title|
1466
+ file = hd.output_file_name(:basename => true)
1467
+ unless hd.kind_of?(Deplate::NullTop)
1468
+ anchor = hd.get_id
1469
+ if anchor
1470
+ file += "##{anchor}"
1471
+ end
1472
+ acc << [title, file]
1473
+ end
1474
+ navmenu << %{<option value="#{file}">#{title}</option>}
1475
+ end
1476
+
1477
+ navmenu << %{</select>}
1478
+ # navmenu << %{<button class="navgo" name="Go" type="button" value="Go" onClick="self.location.href=this.form.Contents.options[this.form.Contents.options.selectedIndex].value">}
1479
+ # navmenu << %{<p class="navgo">%s</p>} % (@variables["goButton"] || "Go")
1480
+ # navmenu << %{</button>}
1481
+ navmenu << %{</form>}
1482
+ @deplate.options.navmenu = navmenu.join("\n")
1483
+ end
1484
+ navbar_add_element(type, slot, idx, @deplate.options.navmenu, "navmenu")
1485
+ end
1486
+
1487
+
1488
+ ################################################ Site navigation {{{1
1489
+ def format_navigation_links(depth)
1490
+ acc = []
1491
+ start = navbar_guess_file_name(0, nil, :inline)
1492
+ if start and start != ""
1493
+ title = @deplate.msg("Frontpage")
1494
+ acc << head_link_tag(%{rel="start" href="#{start}" title="#{clean_tags(title)}"})
1495
+ end
1496
+ tags = ["", "chapter", "section", "subsection"]
1497
+ @deplate.each_heading(depth || 2) do |hd, title|
1498
+ ref = tags[hd.level]
1499
+ anchor = hd.args[:id] || hd.label.first
1500
+ file = hd.output_file_name(:basename => true)
1501
+ file = [file, "#", anchor].join if anchor
1502
+ acc << head_link_tag(%{rel="#{ref}" href="#{file}" title="#{clean_tags(title)}"})
1503
+ end
1504
+ acc.join("\n")
1505
+ end
1506
+
1507
+ def navbar_guess_file_name(idx, base, bartype, section=nil)
1508
+ b = @deplate.output_filename_by_idx(base)
1509
+ ff = @deplate.output_filename_by_idx(idx)
1510
+ f = @deplate.relative_path_by_file(ff, b)
1511
+ if bartype == :inline
1512
+ section ||= @deplate.top_heading_by_idx(idx)
1513
+ if section
1514
+ anchor = section.args[:id] || section.label.first
1515
+ if anchor and anchor != "deplateNullTop"
1516
+ f = [f, "#", anchor].join
1517
+ end
1518
+ end
1519
+ end
1520
+ return f
1521
+ end
1522
+
1523
+
1524
+ private
1525
+ def navbar_begin(type, slot, idx)
1526
+ output_at(type, slot, %{<table class="navbar"><tr class="navbar">})
1527
+ end
1528
+
1529
+ def navbar_end(type, slot, idx)
1530
+ output_at(type, slot, %{</tr></table>})
1531
+ end
1532
+
1533
+ def navbar_add_element(type, slot, idx, element, htmlclass)
1534
+ if !@variables["noTabBarButtons"] and type and slot
1535
+ output_at(type, slot, %{<td class="#{htmlclass}">#{element}</td>})
1536
+ end
1537
+ end
1538
+
1539
+ def navbar_output_index(invoker, first=false, last=false)
1540
+ acc = []
1541
+ if invoker.respond_to?(:top_heading)
1542
+ th = invoker.top_heading
1543
+ acc << @deplate.output_index(th)
1544
+ acc << first || th.first_top
1545
+ acc << last || th.last_top
1546
+ else
1547
+ idx = @deplate.output_index
1548
+ acc << idx
1549
+ acc << (first || (idx == 0))
1550
+ acc << (last || (@deplate.number_of_outputs == idx + 1))
1551
+ end
1552
+ return acc
1553
+ end
1554
+
1555
+ end
1556
+
1557
+
1558
+ class Deplate::Core
1559
+ def formatter_initialize_html
1560
+ @doc_services["navigation_bar"] = :html_navigation_bar
1561
+ @doc_services["navigation_note"] = :html_navigation_note
1562
+ @doc_services["navigation_keys"] = :html_navigation_keys
1563
+ @doc_services["navigation_links"] = :html_navigation_links
1564
+ @html_navigation_note = nil
1565
+ end
1566
+
1567
+ def html_navigation_links(args, text)
1568
+ depth = args["depth"]
1569
+ depth &&= depth.to_i
1570
+ @formatter.format_navigation_links(depth)
1571
+ end
1572
+
1573
+ def html_navigation_bar(args, text)
1574
+ type = :array
1575
+ slot = []
1576
+ invoker = args[:invoker]
1577
+ if invoker
1578
+ invoker.args.update(args)
1579
+ else
1580
+ invoker = Deplate::PseudoContainer.new(@deplate, :args => args)
1581
+ end
1582
+ @formatter.format_navigation_bar(invoker, type, slot, :inline)
1583
+ slot.join("\n")
1584
+ end
1585
+
1586
+ # 8 ... BS
1587
+ # 9 ... tab
1588
+ # 13 ... enter
1589
+ # 16 ... shift
1590
+ # 17 ... ctrl
1591
+ # 18 ... alt
1592
+ # 27 ... esc
1593
+ # 32 ... space
1594
+ # 37 ... left
1595
+ # 39 ... right
1596
+ # 78 ... n
1597
+ # 191 ... #
1598
+ def html_navigation_keys(args, text)
1599
+ nextKey = @variables["nextKey"] || "16"
1600
+ nextKey = ",%s," % nextKey.split(/\s*,\s*/).join(",")
1601
+ prevKey = @variables["prevKey"] || "8"
1602
+ prevKey = ",%s," % prevKey.split(/\s*,\s*/).join(",")
1603
+ acc = []
1604
+ if nextKey.to_i > 0
1605
+ acc << <<-EOJS
1606
+ <script type="text/javascript">
1607
+ <!--
1608
+ function HandleSpace() {
1609
+ this.event = function(e) {
1610
+ if (!e) { e = window.event; }
1611
+ EOJS
1612
+ if args["next"]
1613
+ acc << <<-EOJS
1614
+ if ("#{nextKey}".indexOf(","+ e.keyCode +",") != -1) {
1615
+ window.location="#{args["next"]}";
1616
+ }
1617
+ EOJS
1618
+ end
1619
+ acc << <<-EOJS
1620
+ };
1621
+ var self = this;
1622
+ }
1623
+ var k = new HandleSpace();
1624
+ document.onkeydown = k.event;
1625
+ //-->
1626
+ </script>
1627
+ EOJS
1628
+ end
1629
+ acc.join
1630
+ end
1631
+
1632
+ def html_navigation_note(args, text)
1633
+ unless @html_navigation_note
1634
+ @html_navigation_note = msg(:htmlnavigation_note)
1635
+ unless @html_navigation_note
1636
+ @html_navigation_note = [
1637
+ %{<p class="htmlnavigationnote" />},
1638
+ %{<hr class="htmlnavigationnote" />},
1639
+ %{<p class="htmlnavigationnote">Navigation tips:</p>},
1640
+ %{<ul class="htmlnavigationnote">},
1641
+ %{<li class="htmlnavigationnote"> Press &lt;a-n&gt; to jump to the next page</li>},
1642
+ if args['nextKey'] then
1643
+ %{<li class="htmlnavigationnote"> Press &lt;#{args['nextKey']}&gt; to jump to the next page</li>}
1644
+ end,
1645
+ %{<li class="htmlnavigationnote"> Press &lt;a-b&gt; to jump to the previous one</li>},
1646
+ %{<li class="htmlnavigationnote"> Press &lt;a-h&gt; to jump to the title page</li>},
1647
+ %{<li class="htmlnavigationnote"> It depends on the browser whether
1648
+ these shortcuts are activated (e.g. Mozilla) or just selected (e.g. MS IE),
1649
+ in which case you have to press &lt;enter&gt;</li>},
1650
+ %{</ul>},
1651
+ ].join("\n")
1652
+ end
1653
+ end
1654
+ return @html_navigation_note
1655
+ end
1656
+ end
1657
+
1658
+
1659
+ class Deplate::Element
1660
+ attr_accessor :html_class, :html_args
1661
+
1662
+ def hook_pre_setup_html
1663
+ @html_class = nil
1664
+ @html_args = nil
1665
+ end
1666
+ end
1667
+
1668
+
1669
+ class Deplate::Command::MAKEBIB
1670
+ accumulate_pre(self, Deplate::Formatter::HTML) do |src, array, deplate, text, match, args, cmd|
1671
+ unless args['plain']
1672
+ n = Deplate::Element::Heading.markup(deplate.msg('Bibliography'))
1673
+ m = Deplate::Element::Heading.match(n)
1674
+ Deplate::Element::Heading.accumulate(src, array, deplate, n, m)
1675
+ o = array[-1]
1676
+ o.finish.update_options(args)
1677
+ deplate.options.html_makebib_heading = o
1678
+ end
1679
+ end
1680
+ end
1681
+
1682
+
1683
+ class Deplate::Command::LIST
1684
+ accumulate_pre(self, Deplate::Formatter::HTML) do |src, array, deplate, text, match, args, cmd|
1685
+ if text == 'index' and !args['plain'] and !args['noTitle']
1686
+ n = Deplate::Element::Heading.markup(deplate.msg('Index'))
1687
+ m = Deplate::Element::Heading.match(n)
1688
+ Deplate::Element::Heading.accumulate(src, array, deplate, n, m)
1689
+ o = array[-1]
1690
+ o.finish.update_options(args)
1691
+ end
1692
+ end
1693
+ end
1694
+
1695
+
1696
+ # vim: ff=unix