desc: web page for the Internet code: | # load the String#to_html and String#to_inline_html methods require 'erbook/html' class String # Transforms this UTF-8 string into HTML entities. def to_html_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 HTML 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 HTML attribute key=value pairs. def to_html_atts inject([]) {|s,(k,v)| s << %( #{k}="#{v}") }.join 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 def type_label type.to_s.capitalize end def type_atts { :class => type }.to_html_atts end def title_atts { :class => :title, :id => here_frag }.to_html_atts end def title_html title.to_s.to_inline_html end def content_html content.to_s.to_html end def title_link aTitle = nil here_link here_frag, aTitle || title_html # %{#{aTitle || title_html}    #{here_link here_frag, '¶'} #{list_link here_frag, list_frag, '≡'}} end def index_link list_link here_frag, list_frag, index # %{#{index}} end def number_link list_link here_frag, list_frag, [type_label, number].compact.join(' ') # %{#{[type_label, number].compact.join(' ')}} end def number_and_title_link "#{number_link}.  #{title_link}" end def index_and_title_link "#{index_link}  #{title_link}" end def content_div %{
#{content_html}
} end @@frags = [] # Returns a unique URI fragment for this node. def here_frag 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 @list_frag ||= "rev:#{here_frag}" end end def here_link aHereFrag, aLabel %{#{aLabel}} end def list_link aHereFrag, aListFrag, aLabel %{#{aLabel}} end # Returns a hyperlink to the given URL of # the given label and mouse-hover title. def link aUrl, aLabel = aUrl, aTitle = nil %{#{aLabel}} end # Encodes the given input in base64 format. def base_64_encode aInput [aInput].pack('m') end # Returns a string denoting embedded, base64 encoded data. def base_64_embed aData, aFormat "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, JPG, GIF, etc.) def base_64_embed_image_data aData, aFormat base_64_embed aData, "image/#{aFormat}" end # Returns a HTML tag that embeds the given image file. # # aPath:: path to the image file # aFormat:: format of the image file (e.g. PNG, JPG, GIF, etc.) # aAtts:: additional attributes for the tag # def embed_image_file aPath, aFormat = aPath[/\w+/], aAtts = {} data = base_64_encode File.read(aPath) aAtts['src'] = base_64_embed_image_data(data, aFormat) "" end ## # load admonition icons # Icon = Struct.new(:path, :name, :format, :data) class Icon # Returns the CSS class for this icon. def css_class @css_class ||= "icon-#{name}" end # Returns a CSS url() containing embedded image data. def css_image "url(#{base_64_embed_image_data self.data, self.format})" end end ICONS = {} Dir[File.join(ERBook::FORMATS_DIR, 'html.icons', '*.*')].each do |path| ext = File.extname(path) name = File.basename(path, ext) data = base_64_encode File.open(path, 'rb') {|f| f.read } ICONS[name] = Icon.new(path, name, ext.sub('.', ''), data) end # STDERR.puts ICONS.inspect nodes: ## # Structure # header: &header toc: false lof: false index: false number: false silent: true output: <%= @node.content_html %> header_outside_above: &header_insert toc: false lof: false index: false number: false silent: true output:
<%= @node.content_html %>
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 index: false number: false silent: true output: | <% label = @node.type_label %>

<%= here_link label, label %>

<%= @node.content_div %>
## # Organization # part: &latex toc: true lof: false index: true number: true output: |
> <%= @node.type_label %> <%= @node.index_link %>
<%= @node.title_link %> <%= @node.content_div %>
chapter: *latex section: toc: true lof: false index: true number: true output: | <% depth = [6, @node.depth + 1].min %>
<%= @node.title_atts %>> <%= @node.index_and_title_link %> > <%= @node.content_div %>
paragraph: toc: false lof: false index: false number: false output: | > ><%= @node.title_link %>

<%= @node.content_div %> ## # Admonitions # tip: &admonition toc: false lof: true index: false number: true output: | > ><%= @node.number_and_title_link %>

<%= @node.content_html %>
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 index: false number: true output: |

<%= @node.number_and_title_link %>

<%= @node.content_div %>
table: *formal example: *formal equation: *formal procedure: *formal ## # cross-references # xref: toc: false lof: false index: false number: false output: | <%= scope = @nodes.select {|n| n.content} target = scope.find {|n| n.id == @node.args[0]} || # id has 1st priority scope.find {|n| n.title == @node.args[0]} if target prefix = "#{target.type_label} #{target.index || target.number}" title_text = if target.type == 'reference' prefix else [prefix, target.title].compact.join('. ') end title_auto = @node.args.length < 2 title_html = if title_auto title_text else @node.args[1].to_s end.to_inline_html %{#{title_html}} else raise ArgumentError, "invalid cross-reference to #{@node.title.inspect}", @node.trace end %> ## # Bibliography # reference: toc: false lof: false index: false number: true silent: true cite: toc: false lof: false index: false number: false output: | <%= target = @types['reference'].find {|n| n.title == @node.args[0]} if target '[%s]' % [ '%s' % [ @node.type, target.here_frag, 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 $authors = {'$authors' => nil} unless defined? $authors $date = Time.now.strftime("%d %B %Y") unless defined? $date abstract = @types['abstract'].first references = @types['reference'] if references.empty? references = nil end # compute table of contents toc_builder = lambda do |n| if @spec['nodes'][n.type]['toc'] entry = '%s%s' % [ (n.index.to_s + '  ' if n.index), n.list_frag, n.here_frag, n.title.to_s.to_inline_html ] nested = n.children.inject('') {|s,c| s << toc_builder[c] } %{
  • #{entry}#{ "
      #{nested}
    " unless nested.empty? }
  • } 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| %{
  • #{n.title.to_s.to_inline_html}
  • } end label = type.capitalize << 's' # TODO: pluralize this properly lof_sections << label %{

    #{label}

      #{nested}
    } end %> <% $feeds.each_pair do |here_frag, fmt| %> <% end if $feeds %> <%= $title.to_s.to_inline_html %> <% if $use_icons %> <% end %> <% if defined? $icons_used and not $icons_used.empty? %> <% end %> <% styles = @spec['styles'] (styles.keys - %w[common]).each do |media| %> <% end %> <% # menu of links to link sections nav = [ ('Abstract' if abstract), 'Contents', lof_sections, ('References' if references) ].flatten.compact if nav.length > 1 %> <% end %>


    <%= node = @types['header_outside_above'].first and node.output %> <%= node = @types['header_outside_below'].first and node.output %> <%= abstract.output if abstract %>


    <% unless toc.empty? %>

    Contents

      <%= toc %> <% if references %>
    • References
    • <% end %>
    <% end %> <% unless lof.empty? %>
    <%= lof %>
    <% end %>


    <%= @content %>
    <% if references %>

    References

      <% references.each do |n| %>
    1. <%= n.content_html %>
    2. <% end %>
    <% end %>


    <%= node = @types['footer_outside_above'].first and node.output %> <%= node = @types['footer_outside_below'].first and node.output %> styles: common: | body { color : #000000; background-color : #FFFFFF; line-height : 1.5em; font-family : Calibri, Verdana, sans-serif; } /* emphasis */ blockquote { font-family : Georgia, serif; color : #444; } em { } hr { height : 0; border : 0; border-top : 2px solid #FF0000; } /* source code */ tt, code, pre { font-family : Monaco, Consolas, "Lucida Console", monospace; font-size : 100%; /* appears like "size: small" otherwise */ } /* hyperlinks */ a > img { border : none; } a img { _border : none; /* for IE6 */ } /* lists */ #content li:first-child { margin-top : 1em; } #content li { margin-bottom : 1em; } /* headings */ h1, h2, h3, h4, h5, h6, .title { font-weight : lighter; font-family : Constantia, "Book Antiqua", "URW Bookman L", serif; } #lof h1, #lof h2, #lof h3, #lof h4, #lof h5, #lof h6 { margin-top : 1.25em; } #content h1, #content h2, #content h3, #content h4, #content h5, #content h6 { margin-top : 2.5em; line-height : 1.25em; } #content h1 { font-size : 2.0em; } #content h2 { font-size : 1.8em; } #content h3 { font-size : 1.6em; } #content h4 { font-size : 1.4em; } #content h5 { font-size : 1.2em; } #content h6 { font-size : 1.0em; } /* tables */ table { border-collapse : collapse; /* no spacing between cell borders */ margin : auto; /* center horizontally */ margin-top : 1em; } th, td { padding : 1em; border : 1px solid #bbb; vertical-align : top; background-color : inherit; _background-color : #FFFFFF; /* for IE6 */ } th { background-color : #F5F5F5; } /* document structure */ #nav { text-align : center; margin-bottom : 4em; } #header { text-align : center; } .header_outside_above, #header, .header_outside_below { margin-bottom : 5em; } .footer_outside_above, #footer, .footer_outside_below { 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; } #Abstract { margin-bottom : 5em; } #toc li { list-style-type : none; } #toc li ul { padding-bottom : 1em; border-left : thick solid #F5F5F5; _border-left : none; /* for IE6 */ } #toc li ul:hover { border-color : #DCDCDC; } #toc > ul { padding-left : 1em; } #bib { margin-top : 5em; } #footer { border-top : thick dotted #DCDCDC; padding-top : 1em; text-align : center; } #footer-credits { margin-top : 1em; margin-bottom : 2em; } /* document nodes */ .part > .title, .chapter > .title { padding-bottom : 0.5em; } .part > .title > big, .chapter > .title > big { display : block; margin-top : 0.25em; } .part .title big, .chapter .title big { _display : block; /* for IE6 */ _margin-top : 0.25em; /* for IE6 */ _margin-bottom : 0.75em; /* for IE6 */ } .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; } .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; /* for IE6 */ _font-weight : bold; /* large is not bold in IE6 */ _margin-top : 2em; /* for IE6 */ } .tip , .note , .caution , .warning , .important, .figure , .table , .example , .equation , .procedure { margin : 3em; } .tip > .icon, .note > .icon, .caution > .icon, .warning > .icon, .important > .icon { float : left; margin : 0 1em 1em 0; /* top right bottom left */ } .tip .icon, .note .icon, .caution .icon, .warning .icon, .important .icon { _display : none; /* IE6 cannot display embedded images */ } .figure > .title { text-align : center; } .figure .title { _text-align : center; /* for IE6 */ } .figure > .content img { display : block; margin : auto; } .figure .content img { _display : block; /* for IE6 */ _margin : auto; /* for IE6 */ } screen: | body { margin : auto; max-width : 36em; padding : 0.5em; } /* source code */ tt { background-color : #F0F8FF; } pre { cursor : text; line-height : normal; border : 1px solid #b1d827; background-color : #F5FFDF; padding : 1em; overflow : auto; } /* output of the syntax coloring library */ pre.code { background-color : #FFFFE8; border-color : #EEDD88; } /* hyperlinks */ a { text-decoration : none; } a:hover { text-decoration : underline; } a:link { color : #0000FF; } a:visited { color : #C71585; } /* external hyperlinks */ a:not([href^="#"]):before { content : "\2660"; /* ♠ */ } a.here, a.list { color : #000000; } a:target, a:target *, *:target a.list { background-color : #FF4500 !important; color : #FFFFFF !important; } a:target, *:target a.list { padding : 0.1em; font-weight : bolder; text-decoration : none; } print: | /* source code */ tt { font-weight : normal; } pre { border : none; } /* headings */ h1, h2, h3, h4, h5, h6 { font-weight : normal; clear : both; } /* hyperlinks */ /* blend all hyperlinks with normal text */ a:link, a:visited { color : #000000; text-decoration : none; } /* emphasize external and cross-reference hyperlinks */ a:not([href^="#"]):link, a:not([href^="#"]):visited, a.xref[title]:link, a.xref[title]:visited { color : #0000FF; text-decoration : underline; font-weight : bolder; } /* show URL of destination for external hyperlinks */ a:not([href^="#"]):after { content : " " attr(href); font-family : Monaco, Consolas, "Lucida Console", monospace; } /* show name of destination for cross-references */ a.xref[title]:after { content : " " attr(title); } a:after { font-weight : normal; font-size : smaller; } /* document structure */ #nav, #lof { display : none; } #toc, .part, .chapter, #bib { page-break-before : always; } /* document nodes */ .part > .title > big, .chapter > .title > big { padding-bottom : 0.5em; } .part .title big, .chapter .title big { _padding-bottom : 0.5em; /* for IE6 */ }