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 aContent
ERB::Util.html_escape aContent
end
# Returns XHTML for a hyperlink to the given
# URL of the given label and mouse-hover title.
def hyperlink aUrl, aLabel = aUrl, aTitle = nil
%{#{aLabel}}
end
# Returns an tag that embeds the given image file.
#
# aPath:: path to the image file
# aFormat:: format of the image file (e.g. PNG, JPEG, GIF, etc.)
# aAtts:: additional attributes for the tag
#
def embed_image_file aPath, aFormat = aPath[/\w+/], aAtts = {}
data = ERBook.base_64_encode File.read(aPath)
embed_image_data data, aFormat, aAtts
end
# Returns an tag that embeds the given raw image data.
#
# aData:: raw image data
# aFormat:: format of the image file (e.g. PNG, JPEG, GIF, etc.)
# aAtts:: additional attributes for the tag
#
def embed_image_data aData, aFormat, aAtts = {}
aAtts[:src] = ERBook.base_64_embed_image_data(aData, aFormat)
""
end
end
class 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:
type.to_s.capitalize
end
def type_label_here_link #:nodoc:
s = type_label
here_link s, s
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 aTitle = nil
here_link here_frag, aTitle || title_xhtml
end
# Returns a hyperlink to this node
# containing its LaTeX-style index number.
def index_link
list_link here_frag, list_frag, index
end
# Returns a hyperlink to this node containing its occurrence number.
def number_link
list_link here_frag, list_frag, [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
##
# 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
private
def here_link aHereFrag, aLabel #:nodoc:
%{#{aLabel}}
end
def list_link aHereFrag, aListFrag, aLabel #:nodoc:
%{#{aLabel}}
end
end
# Encodes the given input in base64 format.
def ERBook.base_64_encode aInput #:nodoc:
[aInput].pack('m')
end
# Returns a string denoting embedded, base64 encoded data.
def ERBook.base_64_embed aData, aFormat #:nodoc:
"data:#{aFormat.to_s.downcase};base64,#{aData.tr("\n", '')}"
end
# Returns a string denoting embedded, base64 encoded image data.
# aFormat:: format of the image data (e.g. PNG, JPEG, GIF, etc.)
def ERBook.base_64_embed_image_data aData, aFormat #:nodoc:
base_64_embed aData, "image/#{aFormat}"
end
##
# load 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 aAtts = {}
aAtts[:alt] ||= name
aAtts[:src] = entity_xml
aAtts[: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:
##
# Structure
#
header: &header
toc: false
lof: false
index: false
number: false
silent: true
output: <%= @node.content_xhtml %>
header_outside_above: &header_insert
toc: false
lof: false
index: false
number: false
silent: true
output:
}
else
''
end
end
toc = @roots.inject('') {|s,n| s << toc_builder[n] }
# compute list of figures
lof_enums = {} # type => nodes
@spec['nodes'].each_pair do |name, info|
if info['lof']
nodes = @types[name]
lof_enums[name] = nodes unless nodes.empty?
end
end
lof_sections = []
lof = lof_enums.sort.map do |(type, nodes)|
nested = nodes.map do |n|
%{
#{nested}}
end
%>
"<%= icon.data_uri %>">
<% end %>
]>
<%= $title.to_s.to_inline_xhtml %>
<% if $feeds %>
<% $feeds.each_pair do |url, fmt| %>
<% end %>
<% end %>
<% @spec['styles'].each_pair do |media, style| %>
<% end %>
<%
# menu of links to link sections
nav = [
('Abstract' if abstract),
'Contents',
lof_sections,
('References' if references)
].flatten.compact
if nav.length > 1
%>
<%=
nav.map do |section|
%{#{section}}
end.join(' · ')
%>
<% end %>
<%= node = @types['header_outside_above'].first and node.output %>
<%= node = @types['header_inside_above'].first and node.output %>
<% if header = @types['header'].first %>
<%= header.output %>
<% else %>
<%= $logo if defined? $logo %>
<%= $title.to_s.to_inline_xhtml %>
<%=
$authors.map do |(name, url)|
if url
%{#{name}}
else
name
end
end.join(', ')
%>
<%= $date %>
<% end %>
<%= node = @types['header_inside_below'].first and node.output %>
<%= node = @types['header_outside_below'].first and node.output %>
<%= abstract.output if abstract %>
<% unless toc.empty? %>