deplate 0.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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