desc: web page for the Internet
code: |
# load the String#to_xhtml and String#to_inline_xhtml methods
require 'erbook/to_xhtml'
class String
# Transforms this UTF-8 string into XML entities.
def to_xml_entities
unpack('U*').map! {|c| "#{c};"}.join
end
# Transforms this string into a valid URI fragment.
# See http://www.nmt.edu/tcc/help/pubs/xhtml/id-type.html
def to_uri_fragment
# remove XML tags from the input
buf = gsub(/<.*?>/, '')
# The first or only character must be a letter.
buf.insert(0, 'a') unless buf[0,1] =~ /[[:alpha:]]/
# The remaining characters must be letters, digits, hyphens (-),
# underscores (_), colons (:), or periods (.) or Unicode characters
buf.unpack('U*').map! do |code|
if code > 0xFF or code.chr =~ /[[:alnum:]\-_:\.]/
code
else
32 # ASCII character code for a single space
end
end.pack('U*').strip.gsub(/[[:space:]-]+/, '-')
end
end
class Hash
# Transforms this hash into a string of XML attribute key="value" pairs.
def to_xml_atts
inject([]) {|s,(k,v)| s << %( #{k}="#{v}") }.join
end
end
module ERBook
class Template
# Protects the given content from the text-to-XHTML conversion process.
def verbatim content
ERB::Util.html_escape content
end
# Returns XHTML for a hyperlink to the given
# URL of the given label and mouse-hover title.
def hyperlink url, label = url, title = nil
%{#{label}}
end
# Returns an tag that embeds the given image file.
#
# path:: path to the image file
# format:: format of the image file (e.g. PNG, JPEG, GIF, etc.)
# atts:: additional attributes for the tag
#
def embed_image_file path, format = path[/\w+/], atts = {}
data = ERBook.base_64_encode File.read(path)
embed_image_data data, format, atts
end
# Returns an tag that embeds the given raw image data.
#
# data:: raw image data
# format:: format of the image file (e.g. PNG, JPEG, GIF, etc.)
# atts:: additional attributes for the tag
#
def embed_image_data data, format, atts = {}
atts[:src] = ERBook.base_64_embed_image_data(data, format)
""
end
end
class Document::Node
# Returns the user-defined title for this node's content.
def title
@title ||= args[0]
end
# Returns the user-defined indentifer for this node.
def id
@id ||= args[1]
end
##
# utility methods
#
def type_label #:nodoc:
ERBook::PHRASES[type.to_s.capitalize]
end
# Returns the title of this node as XHTML.
def title_xhtml
title.to_s.to_inline_xhtml
end
# Returns the content of this node as XHTML.
def content_xhtml
content.to_s.to_xhtml
end
# Returns the content of this node as XHTML inside a
.
def content_xhtml_div #:nodoc:
%{
#{content_xhtml}
}
end
# Returns a hyperlink to this node containing its title.
def title_link title = nil
title || title_xhtml
end
# Returns a hyperlink to this node
# containing its LaTeX-style index number.
def index_link
index
end
# Returns a hyperlink to this node containing its occurrence number.
def number_link
[type_label, number].compact.join(' ')
end
# Returns a hyperlink to this node containing
# its ocurrence number and its title.
def number_and_title_link #:nodoc:
"#{number_link}. #{title_link}"
end
# Returns a hyperlink to this node containing
# its LaTeX-style index number and its title.
def index_and_title_link #:nodoc:
"#{index_link} #{title_link}"
end
# Returns a navigation menu relative to this node.
def navigation
self.class.navigation(
here_frag,
(list_frag if defn['toc'] || defn['lof']),
(prev_node.here_frag if prev_node),
(next_node.here_frag if next_node)
)
end
LIST_SIGN = '≡' # identical to
HERE_SIGN = '◎' # bullseye
PREV_SIGN = '△' # white up-pointing triangle
NEXT_SIGN = '▽' # white down-pointing triangle
LIST_TEXT = ERBook::PHRASES['Reverse jump to listing']
HERE_TEXT = ERBook::PHRASES['Jump to this segment']
PREV_TEXT = ERBook::PHRASES['Jump to previous segment']
NEXT_TEXT = ERBook::PHRASES['Jump to next segment']
# Calculates a local navigation menu containing links
# to the given URI fragments (which can be nil).
def self.navigation here_frag, list_frag, prev_frag, next_frag
list_link = list_frag ? %{#{LIST_SIGN}} : LIST_SIGN
here_link = here_frag ? %{#{HERE_SIGN}} : HERE_SIGN
prev_link = prev_frag ? %{#{PREV_SIGN}} : PREV_SIGN
next_link = next_frag ? %{#{NEXT_SIGN}} : NEXT_SIGN
%{
#{list_link}#{prev_link}#{next_link}#{here_link}
}
end
# Returns a hyperlink to this node.
#
# @param [String] label
# Optional label (may contain XHTML) for the hyperlink.
#
# If not specified, the title and designation of
# this node will be used as the label instead.
#
def xref_link label = nil
prefix = [type_label, index || number].compact.join(' ')
title_text =
if type == 'reference'
prefix
else
[prefix, (%{"#{title}"} if title)].compact.join('. ')
end
title_xhtml =
if label
label
else
title_text
end.to_s.to_inline_xhtml
%{#{title_xhtml}}
end
##
# URI fragments
#
@@frags = []
# Returns a unique URI fragment for this node.
def here_frag #:nodoc:
unless defined? @here_frag
salt = object_id.abs
frag = (id || title || salt).to_s.to_uri_fragment
# make it unique
while @@frags.include? frag
frag << '-' << (index || number || salt).to_s
end
@@frags << frag
@here_frag = frag
end
@here_frag
end
# Returns the URI fragment for the location in the table
# of contents / list of figures that points this node.
def list_frag #:nodoc:
@list_frag ||= "rev:#{here_frag}"
end
end
# Encodes the given input in base64 format.
def ERBook.base_64_encode input #:nodoc:
[input].pack('m')
end
# Returns a string denoting embedded, base64 encoded data.
def ERBook.base_64_embed data, format #:nodoc:
"data:#{format.to_s.downcase};base64,#{data.tr("\n", '')}"
end
# Returns a string denoting embedded, base64 encoded image data.
#
# format:: format of the image data (e.g. PNG, JPEG, GIF, etc.)
#
def ERBook.base_64_embed_image_data data, format #:nodoc:
base_64_embed data, "image/#{format}"
end
##
# admonition icons
#
ICONS_DIR = File.join(ERBook::FORMATS_DIR, 'xhtml.icons')
ICON_DEFS = YAML.load_file File.join(ICONS_DIR, 'index.yaml')
Icon = Struct.new(:origin, :path, :name, :format, :data)
class Icon #:nodoc:
# Returns a data URI containing embedded image data.
def data_uri
ERBook.base_64_embed_image_data self.data, self.format
end
# Returns a CSS url() containing embedded image data.
def data_css
%{url("#{data_uri}")}
end
# Returns a XML entity reference (to this icon's
# embedded image data) ready for insertion into XML.
def entity_xml
"{entity_name};"
end
# Returns the name of the XML entity whose
# value contains embedded image data.
def entity_name
"icon_#{name}"
end
# Returns an tag that renders the image
# data embedded as an ENTITY in the html DOCTYPE.
def to_xhtml atts = {}
atts[:alt] ||= name
atts[:src] = entity_xml
atts[:class] = :icon
""
end
end
ICON_BY_NAME = {}
ICON_DEFS.each_pair do |name, path|
format = File.extname(path).sub('.', '')
origin = path[/^\w+/]
path = File.join(ICONS_DIR, path) # make the path absolute
data = base_64_encode File.open(path, 'rb') {|f| f.read }
ICON_BY_NAME[name] = Icon.new(origin, path, name, format, data)
end
ICONS = ICON_BY_NAME.values
end
nodes:
# object model
node:
toc: false
lof: false
depth: false
index: false
number: false
silent: false
inline: true
output: <%= @node.content_xhtml %>
# Structure
header: &header
toc: false
lof: false
depth: false
index: false
number: false
silent: true
inline: true
output: <%= @node.content_xhtml %>
header_outside_above: &header_insert
toc: false
lof: false
depth: false
index: false
number: false
silent: true
inline: true
output:
#{nested}}
end
%>
"<%= icon.data_uri %>">
<% end %>
]>
<% if $title %>
<%= $title.to_s.to_inline_xhtml %>
<% end %>
<% if $authors %>
<% end %>
<% if $date %>
<% end %>
<% if $feeds %>
<% $feeds.each_pair do |url, fmt| %>
<% end %>
<% end %>
<% @format['styles'].each do |style| %>
<% style.each_pair do |media, code| %>
<% end %>
<% end %>
<%
# menu of links to link sections
nav = [
(ERBook::PHRASES['Abstract'] if abstract),
ERBook::PHRASES['Contents'],
lof_sections,
(ERBook::PHRASES['References'] if references)
].flatten.compact
if nav.length > 1
%>