papyrus 0.0.1

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.
@@ -0,0 +1,399 @@
1
+ # -*- coding: utf-8 -*-
2
+ =begin
3
+ This file is part of RDoc PDF LaTeX.
4
+
5
+ RDoc PDF LaTeX is a RDoc plugin for generating PDF files.
6
+ Copyright © 2011 Pegasus Alpha
7
+
8
+ RDoc PDF LaTeX is free software; you can redistribute it and/or modify
9
+ it under the terms of the GNU General Public License as published by
10
+ the Free Software Foundation; either version 2 of the License, or
11
+ (at your option) any later version.
12
+
13
+ RDoc PDF LaTeX is distributed in the hope that it will be useful,
14
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ GNU General Public License for more details.
17
+
18
+ You should have received a copy of the GNU General Public License
19
+ along with RDoc PDF LaTeX; if not, write to the Free Software
20
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
+ =end
22
+
23
+ gem "rdoc"
24
+ require "rdoc/markup/formatter"
25
+ require "rdoc/markup/inline"
26
+
27
+ #This is an RDoc Converter/Formatter that turns the RDoc
28
+ #markup into LaTeX code. It’s intended for use with
29
+ #the RDoc::Generator::PDF_LaTeX class, but if you like you
30
+ #can use it on it’s own (but note this class absolutely
31
+ #depends on RDoc’s parser). To use it, you first have
32
+ #to instanciate this class, and then call the #convert method
33
+ #on it with the text you want to convert:
34
+ #
35
+ # f = RDoc::Markup::ToLaTeX.new
36
+ # f.convert("A *bold* and +typed+ text.")
37
+ #
38
+ #Should result in:
39
+ #
40
+ # A \textbf{bold} and \texttt{typed} text.
41
+ #
42
+ #If for any reason you want to just escape LaTeX control characters,
43
+ #you may do so by calling the #escape method. See it’s documentation
44
+ #for an example.
45
+ #
46
+ #Some parts of this class are heavily inspired by RDoc’s own
47
+ #code, namely:
48
+ #* ::new
49
+ #* #handle_special_TIDYLINK
50
+ #
51
+ #See each method’s descriptions for more details.
52
+ #
53
+ #==How to write a formatter
54
+ #RDoc offers an easy to adapt visitor pattern for creating new formatters.
55
+ #"Easy" to a certain extend, as soon as you get into inline formatting
56
+ #RDoc’s documentation lacks some serious information. Nevertheless, I'll
57
+ #describe the process of formatting here, even if I reiterate some of the
58
+ #concepts the documentation for class RDoc::Markup::Formatter mentions.
59
+ #
60
+ #First, you have to derive your class from RDoc::Markup::Formatter and
61
+ #then obscurely have to include the RDoc::Text module, because this one
62
+ #is responsible for parsing inline markup.
63
+ #
64
+ #Assuming you already wrote a generator making use of your
65
+ #formatter (because without writing a generator, writing
66
+ #a formatter is a somewhat nonsense undertaking as noone
67
+ #instanciates the class), I continue on how RDoc interacts
68
+ #with your formatter class.
69
+ #
70
+ #So, somewhere in your generator you call the ::new method of
71
+ #your formatter (preferably inside the YourGenerator#formatter
72
+ #method, but I assume you know this as it belongs to writing
73
+ #generators and not formatters). Ensure that this method takes
74
+ #at least one argument called +markup+, which defaults to a +nil+
75
+ #value! Till now I didn’t really find out what it’s for, but
76
+ #the RDoc::Markup::Formatter::new method expects it, so we
77
+ #should obey it. All other arguments are up to your choice,
78
+ #just ensure that you call +super+ inside your +initialize+ method
79
+ #with the +markup+ parameter as it’s sole argument.
80
+ #
81
+ #The next task for your +initialize+ is to tell RDoc how to cope
82
+ #with the three inline formatting sequences: Bold, italic
83
+ #and teletypd text. Call the +add_tag+ inherited from
84
+ #the Formatter class and pass it one of the following
85
+ #symbols along with how you want to transform the given
86
+ #sequence:
87
+ #
88
+ #* <tt>:BOLD</tt>
89
+ #* <tt>:EM</tt>
90
+ #* <tt>:TT</tt>
91
+ #
92
+ #If you want to add so-called "specials" to your formatter (and you’re likely
93
+ #to, as hyperlinks are such specials), you have to dig around in RDoc’s
94
+ #own formatters, namely RDoc::Markup::ToHtml, and find out that there’s
95
+ #an instance variable called @markup that allows you to do this. Call
96
+ #it’s +add_special+ method with a regular expression that finds your special
97
+ #and a name for it as a symbol. RDoc itself uses the following specials:
98
+ #
99
+ # @markup.add_special(/((link:|https?:|mailto:|ftp:|www\.)\S+\w)/, :HYPERLINK)
100
+ # @markup.add_special(/(((\{.*?\})|\b\S+?)\[\S+?\.\S+?\])/, :TIDYLINK)
101
+ #
102
+ #If you add a special, you have to provide a <tt>handle_special_YOURSPECIAL</tt> method
103
+ #in your formatter, where YOURSPECIAL corresponds to the symbol you previously
104
+ #passed to the +add_special+ method. This method gets passed a RDoc::Special object, from
105
+ #which you just need to know the +text+ method that retrieves the text your regular
106
+ #expression matched. Apply whatever you want, and return a string RDoc will incorporate
107
+ #into the result.
108
+ #
109
+ #During the formatting process RDoc calls various methods on your
110
+ #formatter, the full list can be seen in the documentation for the
111
+ #class RDoc::Markup::Formatter. Note that *those* methods should _not_
112
+ #return a string--in fact, RDoc ignores their return values. You are
113
+ #expected to keep track of your formatted text, e.g. create an instance
114
+ #variable @result in your +initialize+ method and fill it with text
115
+ #in the methods called by RDoc.
116
+ #
117
+ #When everything has been processed, RDoc calls the +end_accepting+ method
118
+ #on your formatter instance. It’s return value is expected to be the complete
119
+ #parsing result, so if you used a string instance variable @result as
120
+ #I recommended above, you should return it’s value from that method.
121
+ #
122
+ #=== Inline formatting
123
+ #This isn’t as hard as I explained earlier, but you have to know what
124
+ #to do, otherwise you’ll be stuck with paragraphs being treated as
125
+ #paragraphs as a whole, but no inline formatting happens. So, to
126
+ #achieve this, you have to define a method that initiates the
127
+ #inline formatting process, RDoc’s HTML formatter’s method
128
+ #is RDoc::Markup::HTML#to_html, so you may choose a name
129
+ #fitting that name scheme (I did for this formatter as
130
+ #well, but the +to_latex+ method is private). You then call
131
+ #this method inside your +accept_paragraph+ method with the
132
+ #paragraph’s text as it’s argument. The content of the method
133
+ #cannot be known if you didn’t dig around in RDoc’s formatter
134
+ #sources--it’s the following:
135
+ #
136
+ # convert_flow(@am.flow(paragraph_text_here))
137
+ #
138
+ #So, what does this do? It uses the superclass’s (undocumented) instance
139
+ #variable @am, which is an instance of RDoc::AttributeFormatter that
140
+ #is responsible for keeping track of which inline text attributes to
141
+ #apply where. It has this magic method called +flow+ which takes
142
+ #one argument: The text of the paragraph you want to format. It tokenizes
143
+ #the paragraph into little pieces of some RDoc tokens and plain strings
144
+ #and returns them as an array (yes, this was the inline parsing process).
145
+ #We then take that token array and pass it directly to the +convert_flow+
146
+ #method (inhertied from the Formatter class) which knows how to handle
147
+ #the token sequence and comes back to your formatter instance each time
148
+ #it wants to format something, bold or teletyped text for instance
149
+ #(remember? You defined that with +add_tag+). If you want to format plain
150
+ #text without any special markup as well (I had to for the LaTeX formatter,
151
+ #because for LaTeX several characters have to be escaped even in
152
+ #nonformatted text, e.g. the underscore) you have to provide the method
153
+ #+convert_string+. It will get passed all strings that don’t have any
154
+ #markup applied; it’s return value will be in the final result.
155
+ class RDoc::Markup::ToLaTeX < RDoc::Markup::Formatter
156
+ include RDoc::Text
157
+
158
+ #Maps RDoc’s list types to the corresponding LaTeX ones.
159
+ LIST_TYPE2LATEX = {
160
+ :BULLET => ["\\begin{itemize}", "\\end{itemize}"],
161
+ :NUMBER => ["\\begin{enumerate}", "\\end{enumerate}"],
162
+ :LABEL => ["\\begin{description}", "\\end{description}"],
163
+ :UALPHA => ["\\begin{ualphaenum}", "\\end{ualphaenum}"],
164
+ :LALPHA => ["\\begin{lalphaenum}", "\\end{lalphaenum}"],
165
+ :NOTE => ["\\begin{description}", "\\end{description}"]
166
+ }.freeze
167
+
168
+ #LaTeX heading commands. 0 is nil as there is no zeroth heading.
169
+ LATEX_HEADINGS = [nil, #Dummy, no hash needed with this
170
+ "\\section{%s}", #h1
171
+ "\\subsection{%s}", #h2
172
+ "\\subsubsection{%s}", #h3
173
+ "\\subsubsubsection{%s}", #h4
174
+ "\\microsection*{%s}", #h5
175
+ "\\paragraph*{%s.} ", #h6
176
+ "\\subparagraph*{%s}", #Needed??
177
+ "%s", "%s", "%s", "%s", "%s", "%s"].freeze #Everything below is just ignored.
178
+
179
+ #Characters that need to be escaped for LaTeX and their
180
+ #corresponding escape sequences. Note the order if important,
181
+ #otherwise some things (especiallaly \ and {}) are escaped
182
+ #twice.
183
+ LATEX_SPECIAL_CHARS = {
184
+ /\\/ => "\\textbackslash{}",
185
+ /\$/ => "\\$",
186
+ /#/ => "\\#",
187
+ /%/ => "\\%",
188
+ /\^/ => "\\^",
189
+ /&/ => "\\\\&", #WTF? \\& in gsub doesn't do anything?! TODO: File Ruby bug when back from vaction...
190
+ /(?<!textbackslash){/ => "\\{",
191
+ /(?<!textbackslash{)}/ => "\\}",
192
+ /_/ => "\\textunderscore{}",
193
+ /\.{3}/ => "\\ldots",
194
+ /~/ => "\\~",
195
+ /©/ => "\\copyright{}",
196
+ /LaTeX/ => "\\LaTeX{}"
197
+ }.freeze
198
+
199
+ #Level relative to which headings are produced from this
200
+ #formatter. E.g., if this is 1, and the user requests a level
201
+ #2 heading, he actually gets a level 3 one.
202
+ attr_reader :heading_level
203
+ #Contains everything processed so far as a string.
204
+ attr_reader :result
205
+ alias res result
206
+ #The innermost type of list we’re currently in or +nil+
207
+ #if we don’t process a list at the moment.
208
+ attr_reader :list_in_progress
209
+
210
+ #Instanciates this formatter.
211
+ #==Parameters
212
+ #[heading_level] Minimum heading level. Useful for context-based heading;
213
+ # a value of 1 indicates that all requested level 2 headings
214
+ # are turned into level 3 ones; a value of 2 would turn them
215
+ # into level 4 ones.
216
+ #[markup] Parameter expected by the superclass. TODO: What for?
217
+ #==Return value
218
+ #A new instance of this class.
219
+ #==Example
220
+ # f = RDoc::Formatter::ToLaTeX.new
221
+ # puts f.convert("Some *bold* text") #=> Some \textbf{bold} text
222
+ #==Remarks
223
+ #Some lines of this method have their origin in the RDoc project. See
224
+ #the code for more details.
225
+ def initialize(heading_level = 0, markup = nil)
226
+ super(markup)
227
+
228
+ @heading_level = heading_level
229
+ @result = ""
230
+ @list_in_progress = nil
231
+
232
+ #Copied from RDoc 3.8, adds link capabilities
233
+ @markup.add_special(/((link:|https?:|mailto:|ftp:|www\.)\S+\w)/, :HYPERLINK)
234
+ @markup.add_special(/(((\{.*?\})|\b\S+?)\[\S+?\.\S+?\])/, :TIDYLINK)
235
+
236
+ #Add definitions for inline markup
237
+ add_tag(:BOLD, "\\textbf{", "}")
238
+ add_tag(:TT, "\\texttt{", "}")
239
+ add_tag(:EM, "\\textit{", "}")
240
+ end
241
+
242
+ ########################################
243
+ # Visitor
244
+ ########################################
245
+
246
+ #First method called.
247
+ def start_accepting
248
+ @result = ""
249
+ end
250
+
251
+ #Last method called. Supposed to return the result string.
252
+ def end_accepting
253
+ @result
254
+ end
255
+
256
+ #Adds par’s text plus newline to the result.
257
+ def accept_paragraph(par)
258
+ @result << to_latex(par.text) << "\n"
259
+ end
260
+
261
+ #Puts ver’s text between \begin{verbatim} and \end{verbatim}
262
+ def accept_verbatim(ver)
263
+ @result << "\\begin{Verbatim}\n" << ver.text.chomp << "\n\\end{Verbatim}\n"
264
+ end
265
+
266
+ #Adds a \rule. The rule’s height is <tt>rule.weight</tt> pt, the
267
+ #rule’s width \textwidth.
268
+ def accept_rule(rule)
269
+ @result << "\\par\\noindent\\rule{\\textwidth}{" << rule.weight.to_s << "pt}\\par\n"
270
+ end
271
+
272
+ #Adds \begin{<list type>}.
273
+ def accept_list_start(list)
274
+ @list_in_progress = list.type
275
+ @result << LIST_TYPE2LATEX[list.type][0] << "\n"
276
+ end
277
+
278
+ #Adds \end{list_type}.
279
+ def accept_list_end(list)
280
+ @result << LIST_TYPE2LATEX[list.type][1] << "\n"
281
+ @list_in_progress = nil
282
+ end
283
+
284
+ #Adds \item[label_if_necessary].
285
+ def accept_list_item_start(item)
286
+ if item.label
287
+
288
+ if @list_in_progress == :NOTE
289
+ @result << "\\item[#{to_latex_suppress_crossref(item.label)}:] " #Newline done by ending paragraph
290
+ else
291
+ @result << "\\item[#{to_latex_suppress_crossref(item.label)}] " #Newline done by ending paragraph
292
+ end
293
+ else
294
+ @result << "\\item " #Newline done by ending method
295
+ end
296
+ end
297
+
298
+ #Adds a terminating \n for a list item if this is necessary
299
+ #(usually the newline is automatically created by processing
300
+ #the list paragraph).
301
+ def accept_list_item_end(item)
302
+ @result << "\n" unless @result.end_with?("\n")
303
+ end
304
+
305
+ #Termiantes a paragraph by inserting two newlines.
306
+ def accept_blank_line(line)
307
+ @result.chomp!
308
+ @result << "\n\n"
309
+ end
310
+
311
+ #Adds a fitting \section, \subsection, etc. for the heading.
312
+ def accept_heading(head)
313
+ @result << sprintf(LATEX_HEADINGS[@heading_level + head.level], to_latex_suppress_crossref(head.text)) << "\n"
314
+ end
315
+
316
+ #Writes the raw thing as-is into the document.
317
+ def accept_raw(raw)
318
+ @result << raw.parts.join("\n")
319
+ end
320
+
321
+ #Handles raw hyperlinks.
322
+ def handle_special_HYPERLINK(special)
323
+ make_url(special.text)
324
+ end
325
+
326
+ #Called for each plaintext string in a paragraph by
327
+ #the #convert_flow method called in #to_latex.
328
+ def convert_string(str)
329
+ escape(str)
330
+ end
331
+
332
+ #Method copied from RDoc project and slightly modified.
333
+ #
334
+ #Handles hyperlinks of form {text}[url] and text[url].
335
+ def handle_special_TIDYLINK(special)
336
+ text = special.text
337
+
338
+ return escape(text) unless text =~ /\{(.*?)\}\[(.*?)\]/ or text =~ /(\S+)\[(.*?)\]/
339
+
340
+ label = $1
341
+ url = $2
342
+ make_url url, escape(label)
343
+ end
344
+
345
+ #Escapes all LaTeX control characters from a string.
346
+ #==Parameter
347
+ #[str] The string to remove the characters from.
348
+ #==Return value
349
+ #A new string with many backslashes. :-)
350
+ #==Example
351
+ # f = RDoc::Markup::ToLaTeX.new
352
+ # str = "I paid 20$ to buy the_item #15."
353
+ # puts f.escape(str) #=> I paid 20\$ to buy the\textunderscore{}item \#15.
354
+ def escape(str)
355
+ result = str.dup
356
+ LATEX_SPECIAL_CHARS.each_pair do |regexp, escape_seq|
357
+ result.gsub!(regexp, escape_seq)
358
+ end
359
+ result
360
+ end
361
+
362
+ private
363
+
364
+ #LaTeX doesn't like excessive cross-references in certain
365
+ #playes, e.g. headings. To allow for inline formatting without
366
+ #cross-references, this method exists. It’s exactly the same
367
+ #as #to_latex, except it’ll never rely on subclasses such
368
+ #as ToLaTeX_Crossref.
369
+ def to_latex_suppress_crossref(item)
370
+ RDoc::Markup::ToLaTeX.new(@heading_level).instance_eval do
371
+ convert_flow(@am.flow(item))
372
+ end
373
+ end
374
+
375
+ #Converts +item+ to LaTeX text. Difference to #escape: It
376
+ #does inline formatting!
377
+ def to_latex(item)
378
+ #This method’s code has purely been guessed by looking
379
+ #at the caller stack for RDoc::Markup::ToHtml#to_html and examining
380
+ #it’s code. The RDoc team should really document better
381
+ #how to write a formatter!
382
+ convert_flow(@am.flow(item)) #See superclass for @am
383
+ end
384
+
385
+ #Turns +text+ and +url+ into a LaTeX (hyperref) link via \href.
386
+ #If URL doesn’t start with a protocol definition (e.g. <tt>ftp://</tt>),
387
+ #prepend <tt>http://</tt>. If +text+ is nil, the link is displayed
388
+ #raw (but the protocol still is prepended if necessary).
389
+ def make_url(url, text = nil)
390
+ url = "http://#{url}" unless url =~ /^.*?:/
391
+ if text
392
+ "\\href{#{url}}{#{text}}"
393
+ else
394
+ "\\url{#{url}}"
395
+ end
396
+ end
397
+
398
+ end
399
+
@@ -0,0 +1,182 @@
1
+ # -*- coding: utf-8 -*-
2
+ =begin
3
+ This file is part of RDoc PDF LaTeX.
4
+
5
+ RDoc PDF LaTeX is a RDoc plugin for generating PDF files.
6
+ Copyright © 2011 Pegasus Alpha
7
+
8
+ RDoc PDF LaTeX is free software; you can redistribute it and/or modify
9
+ it under the terms of the GNU General Public License as published by
10
+ the Free Software Foundation; either version 2 of the License, or
11
+ (at your option) any later version.
12
+
13
+ RDoc PDF LaTeX is distributed in the hope that it will be useful,
14
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ GNU General Public License for more details.
17
+
18
+ You should have received a copy of the GNU General Public License
19
+ along with RDoc PDF LaTeX; if not, write to the Free Software
20
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
+ =end
22
+
23
+ require "rdoc/cross_reference"
24
+ require_relative "to_latex"
25
+
26
+ #Class adding cross-referencing facility to the
27
+ #RDoc::Markup::ToLaTeX class. If using this class
28
+ #instead of RDoc::Markup::ToLaTeX, names of classes
29
+ #and modules inside descriptions are recognized as well
30
+ #as <tt>rdoc-ref</tt> links, which have the following
31
+ #form:
32
+ # rdoc-ref: WhatYouWantToReference
33
+ #For information on how to use this class, see it’s
34
+ #superclass RDoc::Markup::ToLaTeX.
35
+ class RDoc::Markup::ToLaTeX_Crossref < RDoc::Markup::ToLaTeX
36
+
37
+ #RDoc::Context this formatter resolves it’s references from.
38
+ attr_accessor :context
39
+
40
+ #Creates a new instance of this class.
41
+ #==Parameters
42
+ #[context] The RDoc::Context from which references will be
43
+ # resolved relatively.
44
+ #[show_hash] Wheather or not to show hash signs # in front of
45
+ # methods if present.
46
+ #[heading_level] (0) Base level for LaTeX headings. This is useful
47
+ # to ensure logical smaller parts get smaller
48
+ # headings; see also RDoc::Markup::ToLaTeX for
49
+ # more information.
50
+ #[hyperlink_all] (false) If true, tries to hyperlink everything that
51
+ # looks like a method name. If false, just hyperlink
52
+ # references with mixed-case or uppercase words or
53
+ # references starting with # or ::.
54
+ #[markup] TODO.
55
+ #==Return value
56
+ #The newly created instance.
57
+ #==Example
58
+ # f = RDoc::Markup::ToLaTeX_Crossref.new(a_rdoc_toplevel, false)
59
+ def initialize(context, heading_level = 0, show_hash = false, show_pages = true, hyperlink_all = false, markup = nil)
60
+ super(heading_level, markup)
61
+
62
+ @context = context
63
+ @show_hash = show_hash
64
+ @show_pages = show_pages
65
+ @hyperlink_all = hyperlink_all
66
+ @crossref_resolver = RDoc::CrossReference.new(@context)
67
+
68
+ if @hyperlink_all
69
+ @markup.add_special(RDoc::CrossReference::ALL_CROSSREF_REGEXP, :CROSSREF)
70
+ else
71
+ @markup.add_special(RDoc::CrossReference::CROSSREF_REGEXP, :CROSSREF)
72
+ end
73
+
74
+ @markup.add_special(/rdoc-ref:\S\w/, :HYPERLINK)
75
+ end
76
+
77
+ #call-seq:
78
+ # show_hash?() ==> bool
79
+ # show_hashes?() ==> bool
80
+ #
81
+ #Wheather or not the hash signs # are shown in front of
82
+ #methods.
83
+ #==Return value
84
+ #Either true or false.
85
+ #==Example
86
+ # f.show_hashes? #=> true
87
+ def show_hash?
88
+ @show_hash
89
+ end
90
+ alias show_hashes? show_hash?
91
+
92
+ #Wheather or not this formatter tries to resolve
93
+ #even words that may not be references (such as "new"),
94
+ #i.e. those with no method prefix <tt>#</tt> or
95
+ #<tt>::</tt> in front and all in lowercase.
96
+ #==Return value
97
+ #Either true or false.
98
+ #==Example
99
+ # f.hyperlink_all? #=> false
100
+ def hyperlink_all?
101
+ @hyperlink_all
102
+ end
103
+
104
+ #Handles encountered cross references.
105
+ def handle_special_CROSSREF(special)
106
+ #If we aren’t instructed to try resolving all possibilities,
107
+ #we won’t resolve all-lowercase words (which may be false
108
+ #positives not meant to be a reference).
109
+ if !@hyperlink_all and special.text =~ /^[a-z]+$/
110
+ return escape(special.text)
111
+ end
112
+
113
+ make_crossref(special.text)
114
+ end
115
+
116
+ #Adds handling of encountered <tt>rdoc-ref</tt> links
117
+ #to the HYPERLINK handler of the ToLaTeX formatter.
118
+ def handle_special_HYPERLINK(special)
119
+ return make_crossref($') if special.text =~ /^rdoc-ref:/
120
+ super
121
+ end
122
+
123
+ private
124
+
125
+ #Tries to resolve the given reference name.
126
+ #==Parameters
127
+ #[name] The name to resolve.
128
+ #[display_name] (nil) If +name+ can be resolved, the generated
129
+ # \\hyperlink will use this as it’s text. This
130
+ # is automatically derived from +name+ if not
131
+ # given.
132
+ #==Return value
133
+ #If +name+ can be properly resolved, a \hyperlink construct
134
+ #of the following form is returned:
135
+ #
136
+ # \hyperlink[<resolved reference>]{<display_name>}%
137
+ # \nolinebreak[2]%
138
+ # [p.~\pageref{<resolved reference>}]
139
+ #
140
+ #In any case, the first matching of the following
141
+ #actions is taken:
142
+ #
143
+ #1. If +name+ can be resolved and is documented, returns
144
+ # the above \hyperlink construct.
145
+ #2. If +name+ can be resolved, but isn’t documented, returns
146
+ # +display_text+.
147
+ #3. If +name+ was escaped, returns +name+.
148
+ #4. If +name+ is completely unresolved, returns +display_text+.
149
+ #==Remarks
150
+ #Note that this method automatically adds explicit LaTeX hyphenation
151
+ #indications (i.e. <tt>\-</tt>) before namespace separators to
152
+ #prevent names like <tt>Foo::Bar::Baz::FooBar::Hello::World</tt> from producing
153
+ #overfull \hbox-es and running out of the page.
154
+ def make_crossref(name, display_name = nil)
155
+ #If no display name is given, calculate it from
156
+ #the original reference name. If the reference
157
+ #is starting with '#', strip the hash sign if
158
+ #we’re instructed to not show these hashes.
159
+ #In all other cases, just reuse the reference
160
+ #name.
161
+ if !display_name
162
+ if name.start_with?("#") and !@show_hash
163
+ display_name = name[1..-1]
164
+ else
165
+ display_name = name
166
+ end
167
+ end
168
+
169
+ resolved_name = @crossref_resolver.resolve(name, display_name)
170
+
171
+ if resolved_name.kind_of?(String)
172
+ escape(resolved_name).gsub("::", "\\-::")
173
+ else #Some RDoc::CodeObject sublass instance
174
+ if @show_pages
175
+ "\\hyperref[#{resolved_name.latex_label}]{#{escape(display_name).gsub("::", "\\-::")}} \\nolinebreak[2][p.~\\pageref{#{resolved_name.latex_label}}]"
176
+ else
177
+ "\\hyperref[#{resolved_name.latex_label}]{#{escape(display_name).gsub("::", "\\-::")}}"
178
+ end
179
+ end
180
+ end
181
+
182
+ end