#-- # Copyright protects this work. # See LICENSE file for details. #++ desc: web page for the Internet code: | ICONS_DIR = File.join(ERBook::FORMATS_DIR, 'xhtml', 'icons') JQUERY_DIR = File.join(ERBook::FORMATS_DIR, 'xhtml', 'jquery') # 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 # # However, colons (:) and periods (.) are special characters # in jQuery CSS selector syntax, so we sanitize them as well. # 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 require 'erb' module ERBook ## # Encodes the given input in base64 format. # def ERBook.base_64_encode input #:nodoc: [input].pack('m') end ## # Encodes the contents of the given file in base64 format. # def ERBook.base_64_encode_file path #:nodoc: base_64_encode open(path, 'rb') {|f| f.read } end ## # Returns a string denoting embedded, base64 encoded data. # def ERBook.base_64_embed data, mime #:nodoc: "data:#{mime.to_s.downcase};base64,#{data.tr("\n", '')}" end def ERBook.base_64_embed_file path # :nodoc: data = base_64_encode_file(path) require 'mime/types' mime = MIME::Types.of(path) base_64_embed data, mime end ## # Returns a string denoting embedded, base64 encoded image data. # # [format] # type of 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 ICON_DEFS = YAML.load_file File.join(ICONS_DIR, 'index.yaml') class Icon < Struct.new(:origin, :path, :name, :format, :data) #: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(path) ICON_BY_NAME[name] = Icon.new(origin, path, name, format, data) end ICONS = ICON_BY_NAME.values class Template::Sandbox ## # 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_frag #:nodoc: "__#{type}__" end 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.join.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 for 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 def parent_tabs_begin #:nodoc: if p = parent and pc = p.toc_children and self == pc.first %{
} end end def parent_tabs_end #:nodoc: if p = parent and self == p.toc_children.last '
' end end ## # Returns all children of this node which are # configured to appear in the table of contents. # def toc_children children.select {|c| c.defn['toc'] } end HERE_TEXT = ERBook::PHRASES['Focus this segment'] PREV_TEXT = ERBook::PHRASES['Focus previous segment'] NEXT_TEXT = ERBook::PHRASES['Focus next segment'] LIST_TEXT = ERBook::PHRASES['Return to listing'] HERE_SIGN = ICON_BY_NAME['nav_here'].to_xhtml(:alt => '∗') PREV_SIGN = ICON_BY_NAME['nav_prev'].to_xhtml(:alt => '←') NEXT_SIGN = ICON_BY_NAME['nav_next'].to_xhtml(:alt => '→') LIST_SIGN = ICON_BY_NAME['nav_list'].to_xhtml(:alt => '≡') ## # 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 here_link = %{#{HERE_SIGN}} if here_frag prev_link = %{#{PREV_SIGN}} if prev_frag next_link = %{#{NEXT_SIGN}} if next_frag list_link = %{#{LIST_SIGN}} if list_frag %{} end ## # Returns a hyperlink to this node. # # [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(' ') caption = if type == 'reference' prefix else [prefix, (%{"#{title}"} if label && title)].compact.join('. ') end label_xhtml = (label || title).to_s.to_inline_xhtml %{#{label_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 = "#{frag} #{index || number || salt}".to_uri_fragment 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 ||= "__toc__#{here_frag}".to_uri_fragment end end end nodes: # object model node: toc: false lof: false depth: false index: false number: false silent: false inline: true bypass: 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: | <%= @node.parent_tabs_begin %>
<%= @node.content_xhtml %>
<%= @node.parent_tabs_end %> header_inside_above: *header_insert header_inside_below: *header_insert header_outside_below: *header_insert footer: *header footer_outside_above: *header_insert footer_inside_above: *header_insert footer_inside_below: *header_insert footer_outside_below: *header_insert abstract: toc: false lof: false depth: false index: false number: false silent: true bypass: true output: |
<%= @node.navigation %>

<%= @node.type_label %>

<%= @node.content_xhtml_div %>
# Organization part: &latex toc: true lof: false depth: true index: true number: true silent: false output: | <%= @node.parent_tabs_begin %>
<%= @node.navigation %>

<%= @node.type_label %> <%= @node.index_link %>
<%= @node.title_link %>

<%= @node.content_xhtml_div %>
<%= @node.parent_tabs_end %> chapter: *latex section: toc: true lof: false depth: true index: true number: true silent: false output: | <% depth = [6, @node.depth + 1].min %> <%= @node.parent_tabs_begin %>
<%= @node.navigation %> class="title"> <%= @node.index_and_title_link %> > <%= @node.content_xhtml_div %>
<%= @node.parent_tabs_end %> paragraph: toc: true lof: false depth: false index: false number: false silent: false output: | <%= @node.parent_tabs_begin %>
<%= @node.navigation %>

<%= @node.title_link %>

<%= @node.content_xhtml_div %>
<%= @node.parent_tabs_end %> # Admonitions tip: &admonition toc: false lof: true depth: true index: false number: true silent: false output: | <%= @node.parent_tabs_begin %>
<%= @node.navigation %>

<%= @node.number_and_title_link %>

<%= ICON_BY_NAME[@node.type].to_xhtml %> <%= @node.content_xhtml %>
<%= @node.parent_tabs_end %> note: *admonition caution: *admonition warning: *admonition important: *admonition # Auxilary materials (formal blocks) # see http://www.sagehill.net/docbookxsl/FormalTitles.html figure: &formal toc: false lof: true depth: true index: false number: true silent: false output: | <%= @node.parent_tabs_begin %>
<%= @node.navigation %>

<%= @node.number_and_title_link %>

<%= @node.content_xhtml_div %>
<%= @node.parent_tabs_end %> table: *formal example: *formal equation: *formal procedure: *formal # cross-references xref: toc: false lof: false depth: true index: false number: false silent: false inline: true output: | <%= query, label = @node.args scope = @nodes.select {|n| n.content } target = scope.find {|n| n.id == query } || # id has 1st priority scope.find {|n| n.title == query } if target target.xref_link label else raise ArgumentError, "invalid cross-reference to #{@node.title.inspect}", @node.trace end %> # Bibliography reference: toc: false lof: false depth: false index: false number: true silent: true bypass: true cite: toc: false lof: false depth: false index: false number: false silent: false inline: true output: | <%= target = @nodes_by_type['reference'].find {|n| n.title == @node.title } if target '[%s]' % [ target.xref_link(target.number), *@node.args[1..-1] ].join(', ') else raise ArgumentError, "invalid citation for #{@node.title.inspect}", @node.trace end %> output: | <% # set default parameter values $title = '$title' unless defined? $title $subtitle = '$subtitle' unless defined? $subtitle $authors = {'$authors' => nil} unless defined? $authors $date = Time.now.strftime("%d %B %Y") unless defined? $date abstract = @nodes_by_type['abstract'].first references = @nodes_by_type['reference'] if references.empty? references = nil end # compute table of contents toc_builder = lambda do |n| nested = n.children.inject('') {|s,c| s << toc_builder[c] } nested = nil if nested.empty? if n.defn['toc'] entry = '%s%s' % [ (n.index.to_s + '  ' if n.index), n.list_frag, n.here_frag, n.title.to_s.to_inline_xhtml ] %{
  • #{entry}#{"
      #{nested}
    " if nested}
  • } else nested end.to_s end toc = @roots.inject('') {|s,n| s << toc_builder[n] } # compute list of figures lof_enums = {} # type => nodes @format['nodes'].each_pair do |name, info| if info['lof'] nodes = @nodes_by_type[name] lof_enums[name] = nodes unless nodes.empty? end end lof_sections_frag_and_label = [] lof = lof_enums.sort.map do |type, nodes| nested = nodes.map do |n| %{
  • #{n.title.to_s.to_inline_xhtml}
  • } end label = ERBook::PHRASES[type.capitalize << 's'] frag = nodes.first.type_frag lof_sections_frag_and_label << [frag, label] %{

    #{label}

      #{nested}
    } end %> "<%= icon.data_uri %>"> ]> % if $title || $subtitle <%= [$title, $subtitle].compact.map do |t| t.to_s.to_inline_xhtml end.join(' — ') %> % if $authors % if $date % if $feeds % $feeds.each_pair do |url, fmt| % require 'rainpress' % @format['styles'].each do |style| % style.each_pair do |media, sass| <% text_only_browser_divider = %{



    }.strip %>
    <%= ERBook::PHRASES['Loading...'] %>
    %= node.output if node = @nodes_by_type['header_outside_above'].first
    %= node.output if node = @nodes_by_type['header_inside_above'].first % if header = @nodes_by_type['header'].first <%= header.output %> % else % if $logo
    % if $title

    <%= $title.to_s.to_inline_xhtml %>

    % if $subtitle

    <%= $subtitle.to_s.to_inline_xhtml %>

    % if $authors

    <%= $authors.map do |name, url| if url %{#{name}} else name end end.join(', ') %>

    % if $date

    <%= $date %>

    %= node.output if node = @nodes_by_type['header_inside_below'].first
    %= node.output if node = @nodes_by_type['header_outside_below'].first
    %= abstract.output if abstract % unless toc.empty?

    <%= ERBook::PHRASES['Contents'] %>

      <%= toc %>
    % unless lof.empty?
    <%= lof %>

    <%= ERBook::PHRASES['Document'] %>

    %= @content
    % if references

    <%= ERBook::PHRASES['References'] %>

      % references.each do |n|
    1. <%= n.content_xhtml %>
    %= text_only_browser_divider

    <%= ERBook::PHRASES[ 'This document was generated by %s on %s using the following resources.', %{#{ERBook::DISPLAY}}, %{#{Time.now}} ] %>

    <%= ERBook::PHRASES['Resource'] %> <%= ERBook::PHRASES['Origin'] %> <%= ERBook::PHRASES['License'] %>
    % ICONS.select {|i| i.origin == 'tango' }.each do |icon| %= icon.to_xhtml Tango Icon Theme

    © 2005 Tango Desktop Project

    Creative Commons Attribution-ShareAlike 2.5 License Agreement
    % ICONS.select {|i| i.origin == 'mediawiki' }.each do |icon| %= icon.to_xhtml MediaWiki Monobook Skin

    © 2007 MediaWiki contributors

    GNU General Public License, version 2

    Valid XHTML 1.0 Transitional Valid CSS!

    %= node.output if node = @nodes_by_type['footer_outside_above'].first %= node.output if node = @nodes_by_type['footer_outside_below'].first
    # definition of font families for use in the CSS styles fonts: serif: Constantia, "Book Antiqua", "URW Bookman L", serif sans-serif: Calibri, Verdana, sans-serif monospace: Monaco, Consolas, "Lucida Console", monospace styles: # these are SASS templates - all: | body color: #000000 background-color: #FFFFFF line-height: 1.5em font-family: <%= @format['fonts']['sans-serif'] %> blockquote color: #333 font-style: italic em, strong, dt font-family: <%= @format['fonts']['serif'] %> hr height: 0 border: 0 border-top: thin dashed #000000 tt, code, pre font-family: <%= @format['fonts']['monospace'] %> // appears like "size: small" otherwise font-size: 100% // output of the syntax coloring library code.para white-space: pre a > img border: none dt margin-top: 1.5em font-weight: bolder h1, h2, h3, h4, h5, h6, .title font-weight: lighter font-family: <%= @format['fonts']['serif'] %> #__lof__ h1, h2, h3, h4, h5, h6 margin-top: 1.25em #__doc__ h1, h2, h3, h4, h5, h6 margin-top: 2.5em line-height: 1.25em h1 font-size: 2.0em h2 font-size: 1.8em h3 font-size: 1.6em h4 font-size: 1.4em h5 font-size: 1.2em h6 font-size: 1.0em table border: none // no spacing between cell borders border-collapse: collapse margin: auto margin-top: 1em margin-bottom: 1em th, td padding: 1em border: 1px solid #bbb vertical-align: top background-color: #FFFFFF th background-color: #F5F5F5 #__header__ > .title font-size: 2.25em #__abstract__ margin-bottom: 5em #__toc__ ul > li list-style-type: none li ul padding-bottom: 1em border-left: thick solid #F5F5F5 &:hover border-color: #DCDCDC > ul padding-left: 1em #__footer__ padding-top: 1em text-align: center margin: auto .part > .title, .chapter > .title padding-bottom: 0.5em .part > .title > big, .chapter > .title > big display: block margin-top: 0.25em .paragraph > .title, .tip > .title, .note > .title, .caution > .title, .warning > .title, .important > .title, .figure > .title, .table > .title, .example > .title, .equation > .title, .procedure > .title font-size: large margin-top: 2em .tip, .note, .caution, .warning, .important, .figure, .table, .example, .equation, .procedure margin: 3em .tip .nav, .note .nav, .caution .nav, .warning .nav, .important .nav, .figure .nav, .table .nav, .example .nav, .equation .nav, .procedure .nav margin-right: -3em .tip > .content, .note > .content, .caution > .content, .warning > .content, .important > .content, .figure > .content, .table > .content, .example > .content, .equation > .content, .procedure > .content // height of icon min-height: 48px .tip > .content > .icon, .note > .content > .icon, .caution > .content > .icon, .warning > .content > .icon, .important > .content > .icon float: left margin: top: 0 right: 1em bottom: 1em left: 0 .figure > .title text-align: center .content img display: block margin: auto - screen: | body margin: 0 padding: 0.5em background-color: #FFFFFF #__body__, #__abstract__ > .title, #__toc__ > .title, .part > .title, .chapter > .title, .section > .title, .paragraph > .title, #__bib__ > .title display: none .tabs // otherwise .nav becomes obscured by the tabs clear: both tt background-color: #F0F8FF pre cursor: text line-height: normal border: 1px solid #b1d827 background-color: #F5FFDF padding: 1em // fit container to content; no overflow! display: inline-block margin: 0 min-width: 92.5% // output of the syntax coloring library code.para cursor: text line-height: normal border: 1px solid #b1d827 background-color: #F5FFDF padding: 1em display: inline-block margin: 0 min-width: 92.5% background-color: #FFFFE8 border-color: #EEDD88 pre.para background-color: #FFFFE8 border-color: #EEDD88 a text-decoration: none &:hover text-decoration: underline &:link // maximum saturation of RoyalBlue color: #0038E1 &:visited color: #800080 #__toc__ a:target, #__lof__ a:target background: <%= ICON_BY_NAME['here_frag'].data_css %> background-position: center right background-repeat: no-repeat padding-right: 20px #__header__ > .logo float: left margin-right: 1em margin-top: 0.25em img max-height: 4em max-width: 4em .title_and_subtitle float: left margin-right: 1.5em .title margin-top: 0.25em .authors_and_date text-align: right .authors, .date margin-top: 0 margin-bottom: 0.25em .date font-weight: lighter .nav float: right > a > img border-top: thick solid #FFFFFF &:hover border-top: thick solid #FA8072 #__nfo__ > table td:first-child, #__nfo__ > .validations text-align: center - print: | tt font-weight: normal pre border: none h1, h2, h3, h4, h5, h6 font-weight: normal clear: both =emphasize_hyperlinks color: #0000FF text-decoration: underline font-weight: bolder a // blend all hyperlinks with normal text &:link, &:visited color: #000000 text-decoration: none // emphasize external hyperlinks &[href]:not([href^="#"]) &:link, &:visited +emphasize_hyperlinks // emphasize cross-reference hyperlinks &.xref[title] &:link, &:visited +emphasize_hyperlinks // show URL of destination for external hyperlinks &[href]:not([href^="#"]):after content: " " attr(href) font-family: <%= @format['fonts']['monospace'] %> // show name of destination for cross-references &.xref[title]:after content: " " attr(title) &:after font-weight: normal font-size: smaller .tabs > ul, .nav, #__lof__, #__nfo__ > .validations display: none #__toc__, .part, .chapter, #__bib__ page-break-before: always #__header__, #__footer__ text-align: center #__header__ > .authors margin-top: 1.625em margin-bottom: -0.25em .header_outside_above, #__header__, .header_outside_below, .logo margin-bottom: 5em .footer_outside_above, #__footer__, .footer_outside_below, #__bib__, #__nfo__ margin-top: 5em #__header__ .header_inside_above, #__footer__ .footer_inside_above margin-bottom: 4em #__header__ .header_inside_below, #__footer__ .footer_inside_below margin-top: 4em .part > .title > big, .chapter > .title > big padding-bottom: 0.5em