SOLR-12746: Simplify the Ref Guide HTML structure and use semantic HTML tags where possible. Adds new template files for Asciidoctor HTML conversion.

This commit is contained in:
Cassandra Targett 2018-11-05 09:05:38 -06:00
parent 45b772f4a9
commit 1e3cc4861a
51 changed files with 1141 additions and 160 deletions

View File

@ -5,7 +5,7 @@
# under solr/solr-ref-guide: "ant clean build-site build-pdf".
#
# The following will be downloaded and installed into $HOME/.rvm/:
# RVM, Ruby, and Ruby gems jekyll, asciidoctor, jekyll-asciidoc,
# RVM, Ruby, and Ruby gems jekyll, asciidoctor, jekyll-asciidoc,
# and pygments.rb.
#
# The script expects to be run in the top-level project directory.
@ -54,7 +54,7 @@ function echoRun() {
echoRun "source $RVM_PATH/scripts/rvm" # Load RVM into a shell session *as a Bash function*
echoRun "rvm cleanup all" # Remove old stuff
echoRun "rvm autolibs disable" # Enable single-user mode
echoRun "rvm install $RUBY_VERSION" # Install Ruby
echoRun "rvm install $RUBY_VERSION" # Install Ruby
echoRun "rvm gemset create $GEMSET" # Create this project's gemset
echoRun "rvm $RUBY_VERSION@$GEMSET" # Activate this project's gemset
@ -64,6 +64,7 @@ echoRun "gem uninstall --all --ignore-dependencies asciidoctor" # Get rid of al
echoRun "gem install --force --version 1.5.6.2 asciidoctor"
echoRun "gem install --force --version 2.1.0 jekyll-asciidoc"
echoRun "gem install --force --version 1.1.2 pygments.rb"
echoRun "gem install --force --version 3.0.9 slim"
cd solr/solr-ref-guide

View File

@ -110,10 +110,13 @@ Other Changes
* SOLR-12423: Upgrade to Tika 1.19.1 when available (Tim Allison via Erick Erickson)
* SOLR-12793: Move TestCloudJSONFacetJoinDomain amd TestCloudJSONFacetSKG to the facet test package (Varun Thacker)
* SOLR-12793: Move TestCloudJSONFacetJoinDomain and TestCloudJSONFacetSKG to the facet test package (Varun Thacker)
* SOLR-12861: Add Solr factory for ByteBuffersDirectory.
* SOLR-12746: Simplify the Ref Guide HTML structure and use semantic HTML tags where possible. Adds new template files
for Asciidoctor HTML conversion. Building the HTML version now requires the Slim gem. (Cassandra Targett)
Bug Fixes
----------------------
@ -148,7 +151,7 @@ Bug Fixes
* SOLR-7557: Fix parsing of child documents using queryAndStreamResponse (Marvin Bredal Lillehaug/Stian Østerhaug via janhoy)
* SOLR-12875: fix ArrayIndexOutOfBoundsException when unique(field) or uniqueBlock(_root_) is
* SOLR-12875: fix ArrayIndexOutOfBoundsException when unique(field) or uniqueBlock(_root_) is
used with DVHASH method in json.facet. (Tim Underwood via Mikhail Khludnev)
* SOLR-12023: Autoscaling policy engine shuffles replicas needlessly (noble)

View File

@ -74,6 +74,10 @@ This project includes portions of the Jekyll Documentation Theme
Copyright (c) 2016 Tom Johnson
License: MIT https://github.com/tomjohnson1492/documentation-theme-jekyll/blob/gh-pages/licenses/LICENSE
This project includes templates from the Asciidoctor HTML5 backend converter
Copyright (c) 2014-2018 Jakub Jirutka
License: MIT https://github.com/jirutka/asciidoctor-html5s/blob/master/LICENSE
This project includes the Navgoco JQuery plugin
Copyright (c) 2013 Christopher Tsoulloftas, http://www.komposta.net
License: BSD https://github.com/tefra/navgoco/blob/master/LICENSE-BSD

View File

@ -29,6 +29,9 @@ These files are processed with AsciiDoctor in 2 different ways:
*** `asciidoctor`: v1.5.6.2, not 1.5.7 or higher. Use `gem install asciidoctor --force --version 1.5.6.2`. NOTE: You must do this before installing `jekyll-asciidoc` or you'll get a version of Asciidoctor that we can't use yet.
*** `jekyll-asciidoc`: v2.1 or higher. Use `gem install jekyll-asciidoc` to install.
*** `pygments.rb`: v1.1.2 or higher. Use `gem install pygments.rb` to install.
// The following is only necessary until we are on Asciidoctor 1.5.8 or higher.
// See https://github.com/asciidoctor/asciidoctor/issues/2928 for details of the problem with Slim 4.x and higher.
*** `slim`: v3.0.1 or higher, only to 3.0.9. Do *NOT* use Slim 4.x. Use `gem install slim --force --version 3.0.9` to install.
* Via `asciidoctor-ant` to build the officially released PDF version of the Ref Guide.
** Prerequisites: None beyond those required to use the main Lucene/Solr build: Java, and Ant.

View File

@ -86,9 +86,10 @@ solr-attributes: &solr-attributes-ref
ivy-tika-version: "${ivyversions.org.apache.tika.version}"
ivy-velocity-tools-version: "${ivyversions./org.apache.velocity/velocity-tools}"
ivy-zookeeper-version: "${ivyversions./org.apache.zookeeper/zookeeper}"
asciidoctor:
safe: 0
template_dir: _templates
attributes:
<<: *solr-attributes-ref
attribute-missing: "warn"

View File

@ -1,6 +0,0 @@
<!-- the google_analytics_id gets auto inserted from the config file -->
{% if site.google_analytics %}
<script>(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');ga('create','{{site.google_analytics}}','auto');ga('require','displayfeatures');ga('send','pageview');</script>
{% endif %}

View File

@ -17,7 +17,7 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js"></script>
<script src="{{ "js/jquery.navgoco.min.js" }}"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/anchor-js/2.0.0/anchor.min.js"></script>
<script src="{{ "js/toc.js" }}"></script>
<script src="{{ "js/customscripts.js" }}"></script>

View File

@ -18,7 +18,7 @@
<script>
Prince.addScriptFunc("datestamp", function() {
return "PDF last generated: {{ site.time | date: '%B %d, %Y' }}";
return "Page last generated: {{ site.time | date: '%B %d, %Y' }}";
});
</script>
@ -27,7 +27,3 @@
return "{{site.print_title}} User Guide";
});
</script>

View File

@ -6,4 +6,4 @@
// based on page variables, build up the list of headers for the top level toc (and any sub-section tocs)
do_tocs({{ page.toclevels | default:2 }})
</script>
<div id="toc" class="toc toc-{{ page.tocclass | default:'normal' }}"></div>
<nav id="toc" class="toc toc-{{ page.tocclass | default:'normal' }}"></nav>

View File

@ -41,15 +41,16 @@
<!-- Content Row -->
<div class="row">
<!-- Sidebar Column -->
<div class="col-md-3">
<nav class="col-md-3">
{% include sidebar.html %}
</div>
</nav>
<!-- Content Column -->
<div class="col-md-9">
<article class="col-md-9 post-content">
{{content}}
</div>
</article>
<!-- /.row -->
</div>
{% include footer.html %}
<!-- /.container -->
</div>

View File

@ -3,42 +3,17 @@ layout: default
---
{% comment %}NOTE: page_id is also definied in default.html{% endcomment %}
{% assign page_id = page.url | split: '/' | last | remove: '.html' %}
<div class="post-header">
<h1 class="post-title-main">{{ page.title }}</h1>
</div>
<!-- This adds a workflow map, to a page
See http://idratherbewriting.com/documentation-theme-jekyll/mydoc_workflow_maps.html
Leaving it here commented out in case we want to implement this in the future
{% if page.simple_map == true %}
<script>
$(document).ready ( function(){
$('.box{{page.box_number}}').addClass('active');
});
</script>
{% include custom/{{page.map_name}}.html %}
{% elsif page.complex_map == true %}
<script>
$(document).ready ( function(){
$('.modalButton{{page.box_number}}').addClass('active');
});
</script>
{% include custom/{{page.map_name}}.html %}
{% endif %} -->
<div class="post-content">
{% if page.summary %}
<div class="summary">{{ page.summary }}</div>
{% endif %}
<header class="header">
<h1 class="title-main">{{ page.title }}</h1>
</header>
{% unless page.toc == false %}
{% include toc.html %}
{% endunless %}
<div class="main-content">
{{content}}
</div>
<section class="content">
{{content}}
</section>
<!-- Adds tags, if any -->
<div class="tags">
@ -56,16 +31,12 @@ layout: default
<!-- Adds nav links on each page -->
{% assign scrollnav = site.data.scrollnav[page_id] %}
{% if scrollnav %}
<div class="scrollnav row">
<nav class="scrollnav row">
{% if scrollnav.prev %}
<a class="btn btn-primary prev" href="{{ scrollnav.prev.url }}">{{ scrollnav.prev.title }}</a>
{% endif %}
{% if scrollnav.next %}
<a class="btn btn-primary next" href="{{ scrollnav.next.url }}">{{ scrollnav.next.title }}</a>
{% endif %}
</div>
</nav>
{% endif %}
</div>
{% include footer.html %}

View File

@ -0,0 +1,4 @@
footer
'&#8212;
cite
=[(attr :attribution), (attr :citetitle)].compact.join(', ')

View File

@ -0,0 +1,8 @@
#footer-text
- if attr? :revnumber
| #{attr 'version-label'} #{attr :revnumber}
- if attr? 'last-update-label'
br
| #{attr 'last-update-label'} #{attr :docdatetime}
- unless (docinfo_content = (docinfo :footer)).empty?
=docinfo_content

View File

@ -0,0 +1,11 @@
section.footnotes aria-label='Footnotes' role='doc-endnotes'
hr
ol.footnotes
- footnotes.each do |fn|
li.footnote id=(footnote_id fn.index) role='doc-endnote'
="#{fn.text} "
a.footnote-backref [
href="##{footnoteref_id fn.index}"
role='doc-backlink'
title='Jump to the first occurrence in the text' ]
| &#8617;

View File

@ -0,0 +1,20 @@
= block_with_title :class=>'hdlist'
table
- if (attr? :labelwidth) || (attr? :itemwidth)
colgroup
col style=style_value(width: [(attr :labelwidth), '%'])
col style=style_value(width: [(attr :itemwidth), '%'])
- items.each do |terms, dd|
tr
th.hdlist1 class=('strong' if option? 'strong')
- terms = [*terms]
- terms.each_with_index do |dt, idx|
=dt.text
- unless idx >= terms.count - 1
br
td.hdlist2
- unless dd.nil?
- if dd.text?
p =dd.text
- if dd.blocks?
=dd.content

View File

@ -0,0 +1,27 @@
- if has_header?
- unless notitle
h1 =header.title
- if [:author, :revnumber, :revdate, :revremark].any? {|a| attr? a }
.details
- if attr? :author
span.author#author =(attr :author)
br
- if attr? :email
span.email#email =sub_macros(attr :email)
br
- if (authorcount = (attr :authorcount).to_i) > 1
- (2..authorcount).each do |idx|
span.author id="author#{idx}" =(attr "author_#{idx}")
br
- if attr? "email_#{idx}"
span.email id="email#{idx}" =sub_macros(attr "email_#{idx}")
- if attr? :revnumber
span#revnumber #{((attr 'version-label') || '').downcase} #{attr :revnumber}#{',' if attr? :revdate}
'
- if attr? :revdate
time#revdate datetime=revdate_iso =(attr :revdate)
- if attr? :revremark
br
span#revremark =(attr :revremark)
- if (attr? :toc) && (attr? 'toc-placement', 'auto')
include _toc.html

View File

@ -0,0 +1,12 @@
= block_with_title :class=>'qlist qanda', :role=>'doc-qna'
dl.qanda
- items.each do |questions, answer|
- [*questions].each do |question|
dt.qanda-question =question.text
- unless answer.nil?
dd.qanda-answer
- if answer.text?
= html_tag_if answer.blocks?, :p
=answer.text
- if answer.blocks?
=answer.content

View File

@ -0,0 +1,4 @@
nav#toc class=(attr 'toc-class', 'toc') role='doc-toc'
h2#toc-title =(attr 'toc-title')
/ Renders block_outline.html.
= converter.convert document, 'outline'

View File

@ -0,0 +1,4 @@
/ Note: We ignore title on callout list here.
ol.callout-list id=id class=[style, role]
- items.each do |item|
li =item.text

View File

@ -0,0 +1,13 @@
- case style
- when 'qanda'
include _qanda.html
- when 'horizontal'
include _hdlist.html
- else
= block_with_title :class=>['dlist', style]
dl
- items.each do |terms, dd|
- [*terms].each do |dt|
dt =dt.text
- unless dd.nil?
dd =(print_item_content dd)

View File

@ -0,0 +1,30 @@
doctype 5
html lang=(attr :lang, 'en' unless attr? :nolang)
head
meta charset=(attr :encoding, 'UTF-8')
/[if IE]
meta http-equiv="X-UA-Compatible" content="IE=edge"
meta name='viewport' content='width=device-width, initial-scale=1.0'
meta name='generator' content="Asciidoctor #{attr 'asciidoctor-version'}"
= html_meta_if 'application-name', (attr 'app-name')
= html_meta_if 'author', (attr :authors)
= html_meta_if 'copyright', (attr :copyright)
= html_meta_if 'description', (attr :description)
= html_meta_if 'keywords', (attr :keywords)
title=((doctitle sanitize: true) || (attr 'untitled-label'))
= styles_and_scripts
- unless (docinfo_content = docinfo).empty?
=docinfo_content
body [
id=id
class=[(attr :doctype), ("#{attr 'toc-class'} toc-#{attr 'toc-position', 'left'}" if (attr? 'toc-class') && (attr? :toc) && (attr? 'toc-placement', 'auto'))]
style=style_value(max_width: (attr 'max-width')) ]
- unless noheader
header
include _header.html
#content =content
- unless !footnotes? || (attr? :nofootnotes)
include _footnotes.html
- unless nofooter
footer
include _footer.html

View File

@ -0,0 +1,3 @@
= block_with_caption :top, :class=>'exampleblock'
.example
=content

View File

@ -0,0 +1,670 @@
require 'date' unless RUBY_PLATFORM == 'opal'
# Add custom functions to this module that you want to use in your Slim
# templates. Within the template you can invoke them as top-level functions
# just like in Haml.
module Slim::Helpers
# URIs of external assets.
FONT_AWESOME_URI = '//cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css'
HIGHLIGHTJS_BASE_URI = '//cdn.jsdelivr.net/gh/highlightjs/cdn-release@9.12.0/build/'
KATEX_CSS_URI = '//cdn.jsdelivr.net/npm/katex@0.8.3/dist/katex.min.css'
KATEX_JS_URI = '//cdn.jsdelivr.net/npm/katex@0.8.3/dist/katex.min.js'
# Defaults
DEFAULT_HIGHLIGHTJS_THEME = 'github'
DEFAULT_SECTNUMLEVELS = 3
DEFAULT_TOCLEVELS = 2
KATEX_RENDER_CODE = <<-JS.gsub(/\s+/, ' ')
document.addEventListener("DOMContentLoaded", function() {
var elements = document.getElementsByClassName("math");
for (var i = 0; i < elements.length; i++) {
var el = elements[i];
if (el.getAttribute("data-lang") !== "tex") {
continue;
}
katex.render(el.textContent.slice(2, -2), el, {
"displayMode": el.nodeName.toUpperCase() !== "SPAN",
"throwOnError": false,
});
}
});
JS
VOID_ELEMENTS = %w(area base br col command embed hr img input keygen link
meta param source track wbr)
# @return [Logger]
def log
@_html5s_logger ||= ::Asciidoctor::Html5s::Logging.default_logger
end
##
# Captures the given block for later yield.
#
# @example Basic capture usage.
# - capture
# img src=image_uri
# - if title?
# figure.image
# - yield_capture
# figcaption =captioned_title
# - else
# - yield_capture
#
# @example Capture with passing parameters.
# - capture do |id|
# img src=image_uri
# - if title?
# figure id=@id
# - yield_capture
# figcaption =caption
# - else
# - yield_capture @id
#
# @see yield_capture
def capture(&block)
@_html5s_capture = block
nil
end
##
# Yields the captured block (see {#capture}).
#
# @param *params parameters to pass to the block.
# @return A content of the captured block.
# @see capture
def yield_capture(*params)
@_html5s_capture.call(*params) if @_html5s_capture
end
##
# Creates an HTML tag with the given name and optionally attributes. Can take
# a block that will run between the opening and closing tags.
#
# @param name [#to_s] the name of the tag.
# @param attributes [Hash] (default: {})
# @param content [#to_s] the content; +nil+ to call the block. (default: nil).
# @yield The block of Slim/HTML code within the tag (optional).
# @return [String] a rendered HTML element.
#
def html_tag(name, attributes = {}, content = nil)
attrs = attributes.inject([]) do |attrs, (k, v)|
next attrs if !v || v.nil_or_empty?
v = v.compact.join(' ') if v.is_a? Array
attrs << (v == true ? k : %(#{k}="#{v}"))
end
attrs_str = attrs.empty? ? '' : ' ' + attrs.join(' ')
if VOID_ELEMENTS.include? name.to_s
%(<#{name}#{attrs_str}>)
else
content ||= yield if block_given?
%(<#{name}#{attrs_str}>#{content}</#{name}>)
end
end
##
# Conditionally wraps a block in an element. If condition is +true+ then it
# renders the specified tag with optional attributes and the given
# block inside, otherwise it just renders the block.
#
# For example:
#
# = html_tag_if link?, 'a', {class: 'image', href: (attr :link)}
# img src='./img/tux.png'
#
# will produce:
#
# <a href="http://example.org" class="image">
# <img src="./img/tux.png">
# </a>
#
# if +link?+ is truthy, and just
#
# <img src="./img/tux.png">
#
# otherwise.
#
# @param condition [Boolean] the condition to test to determine whether to
# render the enclosing tag.
# @param name (see #html_tag)
# @param attributes (see #html_tag)
# @param content (see #html_tag)
# @yield (see #html_tag)
# @return [String] a rendered HTML fragment.
#
def html_tag_if(condition, name, attributes = {}, content = nil, &block)
if condition
html_tag name, attributes, content, &block
else
content || yield
end
end
##
# Wraps a block in a div element with the specified class and optionally
# the node's +id+ and +role+(s). If the node's +title+ is not empty, then a
# nested div with the class "title" and the title's content is added as well.
#
# @example When @id, @role and @title attributes are set.
# = block_with_title :class=>['quote-block', 'center']
# blockquote =content
#
# <section id="myid" class="quote-block center myrole1 myrole2">
# <h6>Block Title</h6>
# <blockquote>Lorem ipsum</blockquote>
# </section>
#
# @example When @id, @role and @title attributes are empty.
# = block_with_title :class=>'quote-block center', :style=>style_value(float: 'left')
# blockquote =content
#
# <div class="quote-block center" style="float: left;">
# <blockquote>Lorem ipsum</blockquote>
# </div>
#
# @example When shorthand style for class attribute is used.
# = block_with_title 'quote-block center'
# blockquote =content
#
# <div class="quote-block center">
# <blockquote>Lorem ipsum</blockquote>
# </div>
#
# @param attrs [Hash, String] the tag's attributes as Hash),
# or the tag's class if it's not a Hash.
# @param title [String, nil] the title.
# @yield The block of Slim/HTML code within the tag (optional).
# @return [String] a rendered HTML fragment.
#
def block_with_title(attrs = {}, title = @title, &block)
if (klass = attrs[:class]).is_a? String
klass = klass.split(' ')
end
attrs[:class] = [klass, role].flatten.uniq
attrs[:id] = id
if title.nil_or_empty?
# XXX quick hack
nested = is_a?(::Asciidoctor::List) &&
(parent.is_a?(::Asciidoctor::ListItem) || parent.is_a?(::Asciidoctor::List))
html_tag_if !nested, :div, attrs, yield
else
html_tag :section, attrs do
[html_tag(:h6, {class: 'block-title'}, title), yield].join("\n")
end
end
end
def block_with_caption(position = :bottom, attrs = {}, &block)
if (klass = attrs[:class]).is_a? String
klass = klass.split(' ')
end
attrs[:class] = [klass, role].flatten.uniq
attrs[:id] = id
if title.nil_or_empty?
html_tag :div, attrs, yield
else
html_tag :figure, attrs do
ary = [yield, html_tag(:figcaption) { captioned_title }]
ary.reverse! if position == :top
ary.compact.join("\n")
end
end
end
##
# Delimite the given equation as a STEM of the specified type.
#
# Note: This is not needed nor used for KaTeX, but keep this for the case
# user wants to use a different method.
#
# @param equation [String] the equation to delimite.
# @param type [#to_sym] the type of the STEM renderer (latexmath, or asciimath).
# @return [String] the delimited equation.
#
def delimit_stem(equation, type)
if (@_html5s_stem_type ||= document.attr('html5s-force-stem-type'))
type = @_html5s_stem_type
end
if is_a? ::Asciidoctor::Block
open, close = ::Asciidoctor::BLOCK_MATH_DELIMITERS[type.to_sym]
else
open, close = ::Asciidoctor::INLINE_MATH_DELIMITERS[type.to_sym]
end
if !equation.start_with?(open) || !equation.end_with?(close)
equation = [open, equation, close].join
end
equation
end
##
# Formats the given hash as CSS declarations for an inline style.
#
# @example
# style_value(text_align: 'right', float: 'left')
# => "text-align: right; float: left;"
#
# style_value(text_align: nil, float: 'left')
# => "float: left;"
#
# style_value(width: [90, '%'], height: '50px')
# => "width: 90%; height: 50px;"
#
# style_value(width: ['120px', 'px'])
# => "width: 90px;"
#
# style_value(width: [nil, 'px'])
# => nil
#
# @param declarations [Hash]
# @return [String, nil]
#
def style_value(declarations)
decls = []
declarations.each do |prop, value|
next if value.nil?
if value.is_a? Array
value, unit = value
next if value.nil?
value = value.to_s + unit unless value.end_with? unit
end
prop = prop.to_s.gsub('_', '-')
decls << "#{prop}: #{value}"
end
decls.empty? ? nil : decls.join('; ') + ';'
end
def urlize(*segments)
path = segments * '/'
if path.start_with? '//'
@_html5s_uri_scheme ||= document.attr('asset-uri-scheme', 'https')
path = "#{@_html5s_uri_scheme}:#{path}" unless @_html5s_uri_scheme.empty?
end
normalize_web_path path
end
##
# Gets the value of the specified attribute in this node.
#
# This is just an alias for +attr+ method with disabled _inherit_ to make it
# more clear.
#
# @param name [String, Symbol] the name of the attribute to lookup.
# @param default_val the value to return if the attribute is not found.
# @return value of the attribute or +default_val+ if not found.
#
def local_attr(name, default_val = nil)
attr(name, default_val, false)
end
##
# Checks if the attribute is defined on this node, optionally performing
# a comparison of its value if +expect_val+ is not nil.
#
# This is just an alias for +attr?+ method with disabled _inherit_ to make it
# more clear.
#
# @param name [String, Symbol] the name of the attribute to lookup.
# @param default_val the expected value of the attribute.
# @return [Boolean] whether the attribute exists and, if +expect_val+ is
# specified, whether the value of the attribute matches the +expect_val+.
#
def local_attr?(name, expect_val = nil)
attr?(name, expect_val, false)
end
##
# @param index [Integer] the footnote's index.
# @return [String] footnote id to be used in a link.
def footnote_id(index = local_attr(:index))
"_footnote_#{index}"
end
##
# @param index (see #footnote_id)
# @return [String] footnoteref id to be used in a link.
def footnoteref_id(index = local_attr(:index))
"_footnoteref_#{index}"
end
def nowrap?
'nowrap' if !document.attr?(:prewrap) || option?('nowrap')
end
def print_item_content(item)
wrap = item.blocks? && !item.blocks.all? { |b| b.is_a? ::Asciidoctor::List }
[ (html_tag_if(wrap, :p) { item.text } if item.text?), item.content ].join
end
##
# Returns corrected section level.
#
# @param sec [Asciidoctor::Section] the section node (default: self).
# @return [Integer]
#
def section_level(sec = self)
(sec.level == 0 && sec.special) ? 1 : sec.level
end
##
# Returns the captioned section's title, optionally numbered.
#
# @param sec [Asciidoctor::Section] the section node (default: self).
# @return [String]
#
def section_title(sec = self)
sectnumlevels = document.attr(:sectnumlevels, DEFAULT_SECTNUMLEVELS).to_i
if sec.numbered && !sec.caption && sec.level <= sectnumlevels
[sec.sectnum, sec.captioned_title].join(' ')
else
sec.captioned_title
end
end
##
# @return [String] language of STEM block or inline node (tex or asciimath).
def stem_lang
value = (inline? ? type : style).to_s
value == 'latexmath' ? 'tex' : value
end
def link_rel
'noopener' if option?('noopener') || attr(:window) == '_blank'
end
#--------------------------------------------------------
# block_admonition
#
##
# @return [Boolean] should be this admonition wrapped in aside element?
def admonition_aside?
%w[note tip].include? attr(:name)
end
##
# @return [String, nil] WAI-ARIA role of this admonition.
def admonition_aria
case attr(:name)
when 'note'
'note' # https://www.w3.org/TR/wai-aria/roles#note
when 'tip'
'doc-tip' # https://www.w3.org/TR/dpub-aria-1.0/#doc-tip
when 'caution', 'important', 'warning'
'doc-notice' # https://www.w3.org/TR/dpub-aria-1.0/#doc-notice
end
end
#--------------------------------------------------------
# block_listing
#
##
# @return [String] a canonical name of the source-highlighter to be used as
# a style class.
def highlighter
@_html5s_highlighter ||=
case (highlighter = document.attr('source-highlighter'))
when 'coderay'; 'CodeRay'
when 'highlight.js'; 'highlightjs'
else highlighter
end
end
##
# Returns the callout list attached to this listing node, or +nil+ if none.
#
# Note: This variable is set by extension
# {Asciidoctor::Html5s::AttachedColistTreeprocessor}.
#
# @return [Asciidoctor::List, nil]
def callout_list
@html5s_colist
end
def source_lang
local_attr :language, false
end
#--------------------------------------------------------
# block_open
#
##
# Returns +true+ if an abstract block is allowed in this document type,
# otherwise prints warning and returns +false+.
def abstract_allowed?
if result = (parent == document && document.doctype == 'book')
log.warn 'asciidoctor: WARNING: abstract block cannot be used in a document
without a title when doctype is book. Excluding block content.'
end
!result
end
##
# Returns +true+ if a partintro block is allowed in this context, otherwise
# prints warning and returns +false+.
def partintro_allowed?
if result = (level != 0 || parent.context != :section || document.doctype != 'book')
log.warn "asciidoctor: ERROR: partintro block can only be used when doctype
is book and it's a child of a book part. Excluding block content."
end
!result
end
#--------------------------------------------------------
# block_table
#
def autowidth?
option? :autowidth
end
def spread?
if !autowidth? || local_attr?('width')
'spread' if attr? :tablepcwidth, 100
end
end
#--------------------------------------------------------
# block_video
#
# @return [Boolean] +true+ if the video should be embedded in an iframe.
def video_iframe?
['vimeo', 'youtube'].include? attr(:poster)
end
def video_uri
case attr(:poster, '').to_sym
when :vimeo
params = {
autoplay: (1 if option? 'autoplay'),
loop: (1 if option? 'loop')
}
start_anchor = "#at=#{attr :start}" if attr? :start
"//player.vimeo.com/video/#{attr :target}#{start_anchor}#{url_query params}"
when :youtube
video_id, list_id = attr(:target).split('/', 2)
params = {
rel: 0,
start: (attr :start),
end: (attr :end),
list: (attr :list, list_id),
autoplay: (1 if option? 'autoplay'),
loop: (1 if option? 'loop'),
controls: (0 if option? 'nocontrols')
}
"//www.youtube.com/embed/#{video_id}#{url_query params}"
else
anchor = [attr(:start), attr(:end)].join(',').chomp(',')
anchor = '#t=' + anchor unless anchor.empty?
media_uri "#{attr :target}#{anchor}"
end
end
# Formats URL query parameters.
def url_query(params)
str = params.map { |k, v|
next if v.nil? || v.to_s.empty?
[k, v] * '='
}.compact.join('&amp;')
'?' + str unless str.empty?
end
#--------------------------------------------------------
# document
#
##
# @return [String, nil] the revision date in ISO 8601, or nil if not
# available or in invalid format.
def revdate_iso
::Date.parse(revdate).iso8601 if defined? ::Date
rescue ArgumentError
nil
end
##
# Returns HTML meta tag if the given +content+ is not +nil+.
#
# @param name [#to_s] the name for the metadata.
# @param content [#to_s, nil] the value of the metadata, or +nil+.
# @return [String, nil] the meta tag, or +nil+ if the +content+ is +nil+.
#
def html_meta_if(name, content)
%(<meta name="#{name}" content="#{content}">) if content
end
# Returns formatted style/link and script tags for header.
def styles_and_scripts
scripts = []
styles = []
tags = []
stylesheet = attr :stylesheet
stylesdir = attr :stylesdir, ''
default_style = ::Asciidoctor::DEFAULT_STYLESHEET_KEYS.include? stylesheet
linkcss = attr?(:linkcss) || safe >= ::Asciidoctor::SafeMode::SECURE
ss = ::Asciidoctor::Stylesheets.instance
if linkcss
path = default_style ? ::Asciidoctor::DEFAULT_STYLESHEET_NAME : stylesheet
styles << { href: [stylesdir, path] }
elsif default_style
styles << { text: ss.primary_stylesheet_data }
else
styles << { text: read_asset(normalize_system_path(stylesheet, stylesdir), true) }
end
if attr? :icons, 'font'
if attr? 'iconfont-remote'
styles << { href: attr('iconfont-cdn', FONT_AWESOME_URI) }
else
styles << { href: [stylesdir, "#{attr 'iconfont-name', 'font-awesome'}.css"] }
end
end
if attr? 'stem'
styles << { href: KATEX_CSS_URI }
scripts << { src: KATEX_JS_URI }
scripts << { text: KATEX_RENDER_CODE }
end
case attr 'source-highlighter'
when 'coderay'
if attr('coderay-css', 'class') == 'class'
if linkcss
styles << { href: [stylesdir, ss.coderay_stylesheet_name] }
else
styles << { text: ss.coderay_stylesheet_data }
end
end
when 'highlightjs'
hjs_base = attr :highlightjsdir, HIGHLIGHTJS_BASE_URI
hjs_theme = attr 'highlightjs-theme', DEFAULT_HIGHLIGHTJS_THEME
scripts << { src: [hjs_base, 'highlight.min.js'] }
scripts << { text: 'hljs.initHighlightingOnLoad()' }
styles << { href: [hjs_base, "styles/#{hjs_theme}.min.css"] }
end
styles.each do |item|
if item.key?(:text)
tags << html_tag(:style) { item[:text] }
else
tags << html_tag(:link, rel: 'stylesheet', href: urlize(*item[:href]))
end
end
scripts.each do |item|
if item.key? :text
tags << html_tag(:script, type: item[:type]) { item[:text] }
else
tags << html_tag(:script, type: item[:type], src: urlize(*item[:src]))
end
end
tags.join("\n")
end
#--------------------------------------------------------
# inline_anchor
#
# @return [String] text of the xref anchor.
def xref_text
str =
if text
text
elsif (path = local_attr :path)
path
elsif document.respond_to? :catalog # Asciidoctor >=1.5.6
ref = document.catalog[:refs][attr :refid]
if ref.kind_of? Asciidoctor::AbstractNode
ref.xreftext((@_html5s_xrefstyle ||= document.attributes['xrefstyle']))
end
else # Asciidoctor < 1.5.6
document.references[:ids][attr :refid || target]
end
(str || "[#{attr :refid}]").tr_s("\n", ' ')
end
# @return [String, nil] text of the bibref anchor, or +nil+ if not found.
def bibref_text
if document.respond_to? :catalog # Asciidoctor >=1.5.6
# NOTE: Technically it should be `reftext`, but subs have already been applied to text.
text
else
"[#{target}]"
end
end
#--------------------------------------------------------
# inline_image
#
# @return [Array] style classes for a Font Awesome icon.
def icon_fa_classes
[ "fa fa-#{target}",
("fa-#{attr :size}" if attr? :size),
("fa-rotate-#{attr :rotate}" if attr? :rotate),
("fa-flip-#{attr :flip}" if attr? :flip)
].compact
end
end

View File

@ -0,0 +1,3 @@
= block_with_caption(:bottom, :class=>'imageblock', :style=>style_value(text_align: (attr :align), float: (attr :float)))
= html_tag_if(attr?(:link), :a, :class=>'image', :href=>(attr :link), :target=>(attr :window), :rel=>link_rel)
img src=image_uri(attr :target) alt=(attr :alt) width=(attr :width) height=(attr :height)

View File

@ -0,0 +1,12 @@
- case type
- when :xref
a href=target =xref_text
- when :ref
/ "target" is for backward compat. with Asciidoctor <1.5.6
a id=(id || target) aria-hidden='true'
- when :bibref
/ "target" is for backward compat. with Asciidoctor <1.5.6
a id=(id || target) aria-hidden='true'
=bibref_text
- else
a id=id class=role href=target target=(attr :window) rel=link_rel title=(attr :title) =text

View File

@ -0,0 +1,2 @@
=text
br

View File

@ -0,0 +1 @@
b.button =text

View File

@ -0,0 +1 @@
i.conum data-value=text

View File

@ -0,0 +1,9 @@
- if (index = local_attr :index)
a.footnote-ref [
id=(footnoteref_id unless type == :xref)
href="##{footnote_id}"
title="View footnote #{index}"
role='doc-noteref' ]
| [#{index}]
- else
a.footnote-ref.broken title="Unresolved footnote reference." [#{text}]

View File

@ -0,0 +1,10 @@
= html_tag_if((attr? :link), :a, :class=>'image', :href=>(attr :link), :target=>(attr :window), :rel=>link_rel)
- if type == 'icon' && (document.attr? :icons, 'font')
i class=[*icon_fa_classes, role] title=(attr :title)
- elsif type == 'icon' && !(document.attr? :icons)
b class=['icon', role] title=(attr :title)
| [#{attr :alt}]
- else
img (src=(type == 'icon' ? (icon_uri target) : (image_uri target))
alt=(attr :alt) width=(attr :width) height=(attr :height) title=(attr :title)
class=[(type if type != 'image'), role] style=style_value(float: (attr :float)))

View File

@ -0,0 +1,2 @@
- if type == :visible
=text

View File

@ -0,0 +1,7 @@
- if (keys = attr 'keys').size == 1
kbd =keys.first
- else
kbd.keyseq
- keys.each_with_index do |key, idx|
="+" unless idx.zero?
kbd =key

View File

@ -0,0 +1,15 @@
- if local_attr :menuitem
- capture
| &#160;
b.caret &#8250;
span.menuseq
b.menu
=(attr :menu)
- yield_capture
- (attr 'submenus').each do |submenu|
b.submenu
=submenu
- yield_capture
b.menuitem =(local_attr :menuitem)
- else
b.menuref =(attr :menu)

View File

@ -0,0 +1,29 @@
- unless id.nil?
a id=id aria-hidden='true'
- case type
- when :emphasis
em class=role =text
- when :strong
strong class=role =text
- when :monospaced
code class=role =text
- when :superscript
sup class=role =text
- when :subscript
sub class=role =text
- when :mark
mark class=role =text
- when :double
= html_tag_if role?, :span, :class=>role
| &#8220;#{text}&#8221;
- when :single
= html_tag_if role?, :span, :class=>role
| &#8216;#{text}&#8217;
- when :asciimath, :latexmath
span.math data-lang=stem_lang =(delimit_stem text, type)
- else
- if role == 'line-through' || role == 'del'
del =text
- else
= html_tag_if role?, :span, :class=>role
=text

View File

@ -0,0 +1,15 @@
= block_with_caption :top, :class=>'listingblock'
- if style == 'source'
- if highlighter == 'html-pipeline'
pre: code data-lang=source_lang =content
- else
- unless highlighter == 'CodeRay'
- code_class = "language-#{source_lang}" if source_lang
pre class=[highlighter, 'highlight', ('linenums' if attr? :linenums), nowrap?]
code class=code_class data-lang=source_lang =content
- else
pre class=nowrap? =content
/ Note: This is a hack to embed callout list into the listing element.
/ See asciidoctor/html5s/attached_colist_treeprocessor.rb.
- if callout_list
= converter.convert callout_list, 'colist'

View File

@ -0,0 +1,2 @@
= block_with_title :class=>'literalblock'
pre class=nowrap? =content

View File

@ -0,0 +1,4 @@
= block_with_title :class=>['olist', style]
ol class=style start=(attr :start) type=list_marker_keyword reversed=(option? 'reversed')
- items.each do |item|
li =(print_item_content item)

View File

@ -0,0 +1,7 @@
- if style == 'abstract'
- if abstract_allowed?
= block_with_title :class=>'quoteblock abstract'
blockquote =content
- elsif style != 'partintro' || partintro_allowed?
= block_with_title :class=>['openblock', (style if style != 'open')]
.content =content

View File

@ -0,0 +1,6 @@
- if title?
section.paragraph id=id
h6.block-title =title
p class=role =content
- else
p id=id class=role =content

View File

@ -0,0 +1 @@
=content

View File

@ -0,0 +1,4 @@
section#preamble aria-label='Preamble'
=content
- if (attr? :toc) && (attr? 'toc-placement', 'preamble')
include _toc.html

View File

@ -0,0 +1,6 @@
= block_with_title :class=>'quoteblock'
blockquote
= html_tag_if !blocks?, :p
=content
- if attr?(:attribution) || attr?(:citetitle)
include _attribution.html

View File

@ -0,0 +1,13 @@
- sect0 = section_level == 0
= html_tag_if !sect0, :section, class: [%(sect#{section_level}), role]
*{tag: %(h#{section_level + 1}), id: id, class: ('sect0' if sect0)}
- if id
- if document.attr? :sectanchors
a.anchor href="##{id}" aria-hidden='true'
- if document.attr? :sectlinks
a.link href="##{id}" =section_title
- else
=section_title
- else
=section_title
=content

View File

@ -0,0 +1,4 @@
aside.sidebarblock id=id class=role
- if title?
h6.block-title =title
=content

View File

@ -0,0 +1,39 @@
= block_with_caption :top, :class=>'tableblock'
table [
class=["frame-#{attr :frame, 'all'}", "grid-#{attr :grid, 'all'}", spread?]
style=style_value(width: ("#{attr :tablepcwidth}%" if !autowidth? && !spread? || (local_attr :width)),
float: (attr :float)) ]
- unless (attr :rowcount).zero?
colgroup
- if autowidth?
- columns.each do
col
- else
- columns.each do |col|
col style="width: #{col.attr :colpcwidth}%;"
- [:head, :foot, :body].reject { |tblsec| rows[tblsec].empty? }.each do |tblsec|
<t#{tblsec}>
- rows[tblsec].each do |row|
tr
- row.each do |cell|
= html_tag(tblsec == :head || cell.style == :header ? 'th' : 'td',
:class=>["halign-#{cell.attr :halign}", "valign-#{cell.attr :valign}"],
:colspan=>cell.colspan,
:rowspan=>cell.rowspan,
:style=>style_value(background_color: (document.attr :cellbgcolor)))
- if tblsec == :head
=cell.text
- else
- case cell.style
- when :asciidoc
=cell.content
- when :verse
.verse: pre =cell.text
- when :literal
.literal: pre =cell.text
- else
- if cell.content.one?
=cell.content.first
- else
- cell.content.each do |text|
p =text

View File

@ -0,0 +1 @@
hr

View File

@ -0,0 +1,11 @@
/ This template is used only for toc::[] macro; for document and preamble TOC
/ see document.html, preamble.html and _toc.html.
- if document.attr?(:toc) && document.sections?
- toc_id = id || ('toc' if document.embedded? || !document.attr?('toc-placement'))
nav id=toc_id class=(attr :role, (document.attr 'toc-class', 'toc')) role='doc-toc'
h level=(level + 2) id=("#{toc_id}-title" if toc_id)
=(title || (document.attr 'toc-title'))
/ Renders outline.html.
= converter.convert document, 'outline', :toclevels=>((attr :levels).to_i if attr? :levels)
- else
/! toc disabled

View File

@ -0,0 +1,11 @@
- checklist = 'task-list' if option? 'checklist'
= block_with_title :class=>['ulist', style]
ul class=(checklist || style)
- items.each do |item|
- if checklist && (item.attr? :checkbox)
li.task-list-item
input.task-list-item-checkbox type='checkbox' disabled=true checked=(item.attr? :checked)
=<item.text
- else
li
=(print_item_content item)

View File

@ -26,7 +26,7 @@
}
/* Adds a custom "lead" style for use in index.html jumbotron box */
.paragraph.lead-homepage > p {
.lead-homepage {
font-size: 1.21875em;
line-height: 1.3;
text-align: center;
@ -172,6 +172,7 @@ li.dropdownActive a {
footer {
font-size: smaller;
padding-top: 10px;
}
/* FAQ page */
@ -461,12 +462,13 @@ a[data-toggle] {
font-weight: bold;
}
a.fa.fa-envelope-o.mailto {
font-weight: 600;
}
.nav-tabs > li.active > a, .nav-tabs > li.active > a:hover, .nav-tabs > li.active > a:focus {
.nav-tabs > li.active > a,
.nav-tabs > li.active > a:hover,
.nav-tabs > li.active > a:focus {
background-color: #248ec2;
color: white;
}
@ -476,10 +478,6 @@ ol li ul li {list-style-type: disc;}
li img {clear:both; }
div#toc ul li ul li {
list-style-type: none;
margin: 5px 0 0 0;
}
.tab-content {
padding: 0px;

View File

@ -1,12 +1,10 @@
/* Load Noto Sans for body and header text */
@font-face
{
@font-face {
font-family: 'Noto Sans';
src: url(../fonts/Noto_Sans/NotoSans-Regular.ttf);
}
@font-face
{
@font-face {
font-weight: bold;
font-family: 'Noto Sans';
src: url(../fonts/Noto_Sans/NotoSans-Bold.ttf);
@ -35,44 +33,37 @@ hgroup,
main,
nav,
section,
summary
{
summary {
display: block;
}
audio,
canvas,
video
{
video {
display: inline-block;
}
audio:not([controls])
{
audio:not([controls]) {
display: none;
height: 0;
}
[hidden],
template
{
template {
display: none;
}
script
{
script {
display: none!important;
}
html
{
html {
font-family: 'Noto Sans', sans-serif;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
body
{
body {
margin: 0;
}
@ -80,20 +71,17 @@ body.DRAFT {
background-image: url("../images/draft-background.png");
}
a
{
a {
background: transparent;
}
a:focus
{
a:focus {
outline: thin dotted;
outline-offset: -2px;
}
a:active,
a:hover
{
a:hover {
outline: 0;
}
@ -112,8 +100,7 @@ a[href^="https://"]:after {
/* Strip the outbound icon when this class is present */
a[href].noCrossRef::after,
a.no_icon:after
{
a.no_icon:after {
content:"" !important;
padding-left: 0;
}
@ -128,6 +115,7 @@ ul#mysidebar li.sb-level3 a {
ul#mysidebar li.sb-level4 a {
padding-left: 40px;
}
/* we can style the 'current-tree' hierarchy in the sidebar independently of the 'active' page as
the user clicks around expanding/collapsing the nav menus w/o clicking a link to load a diff page
@ -147,14 +135,12 @@ ul#mysidebar li.current.active > a {
}
abbr[title]
{
abbr[title] {
border-bottom: 1px dotted;
}
b,
strong
{
strong {
font-weight: bold;
}
@ -461,6 +447,7 @@ p.lead
.exampleblock > .title,
.hdlist > .title,
.imageblock > .title,
.imageblock > figcaption,
.listingblock > .title,
.literalblock > .title,
.olist > .title,
@ -483,7 +470,7 @@ table.tableblock > .title
}
#toctitle,
.sidebarblock > .content > .title,
.sidebarblock > .title,
blockquote,
dd,
div,
@ -538,7 +525,7 @@ p aside
}
#toctitle,
.sidebarblock > .content > .title,
.sidebarblock > .title,
h1,
h2,
h3,
@ -560,7 +547,7 @@ h6
}
#toctitle small,
.sidebarblock > .content > .title small,
.sidebarblock > .title small,
h1 small,
h2 small,
h3 small,
@ -574,7 +561,7 @@ h6 small
}
/* Pad the page title and sidebar header */
h1.post-title-main,
h1.title-main,
li.sidebarTitle {
padding-top: 20px;
}
@ -590,7 +577,7 @@ h2
}
#toctitle,
.sidebarblock > .content > .title,
.sidebarblock > .title,
h3
{
font-size: 1.375em;
@ -660,8 +647,9 @@ ul li ol,
ul li ul
{
margin-bottom: 0;
margin-left: 1.25em;
margin-left: .25em;
font-size: 1em;
padding-left: 10px;
}
ul.circle li ul,
@ -761,7 +749,7 @@ blockquote p
and (min-width : 768px)
{
#toctitle,
.sidebarblock > .content > .title,
.sidebarblock > .title,
h1,
h2,
h3,
@ -783,7 +771,7 @@ blockquote p
}
#toctitle,
.sidebarblock > .content > .title,
.sidebarblock > .title,
h3
{
font-size: 1.6875em;
@ -846,7 +834,7 @@ table tr td
}
#toctitle strong,
.sidebarblock > .content > .title strong,
.sidebarblock > .title strong,
h1 strong,
h2 strong,
h3 strong,
@ -1162,32 +1150,36 @@ body.toc2 #header > h1:nth-last-child(2)
font-size: 1.2em;
}
div.toc ul li {
nav.toc ul li {
margin: 8px 0 8px 22px;
list-style: disc;
line-height: 1.25;
}
div.toc ul {
background-color: whitesmoke;
nav.toc ul {
background-color: #f1f1f1;;
padding: 5px;
border-radius: 5px;
color: gray;
}
div.toc ul li ul {
padding-left:8px;
nav.toc ul li ul {
padding-left: 8px;
}
div.toc ul li ul li::before {
content: " ";
nav.toc ul li ul li {
list-style: circle;
margin: 5px 0 0 0;
}
div.toc.section-toc >ul::before {
nav.toc ul li ul li ul li {
list-style: square;
}
nav.toc.section-toc >ul::before {
content: "In this section";
}
div.toc >ul::before {
nav.toc >ul::before {
content: "On this Page";
font-weight: bold;
color: #555;
@ -1364,7 +1356,7 @@ div.toc >ul::before {
#content h1 > a.anchor,
#toctitle > a.anchor,
.sidebarblock > .content > .title > a.anchor,
.sidebarblock > .title > a.anchor,
h2 > a.anchor,
h3 > a.anchor,
h4 > a.anchor,
@ -1384,7 +1376,7 @@ h6 > a.anchor
#content h1 > a.anchor:before,
#toctitle > a.anchor:before,
.sidebarblock > .content > .title > a.anchor:before,
.sidebarblock > .title > a.anchor:before,
h2 > a.anchor:before,
h3 > a.anchor:before,
h4 > a.anchor:before,
@ -1401,8 +1393,8 @@ h6 > a.anchor:before
#content h1 > a.anchor:hover,
#toctitle:hover > a.anchor,
#toctitle > a.anchor:hover,
.sidebarblock > .content > .title:hover > a.anchor,
.sidebarblock > .content > .title > a.anchor:hover,
.sidebarblock > .title:hover > a.anchor,
.sidebarblock > .title > a.anchor:hover,
h2:hover > a.anchor,
h2 > a.anchor:hover,
h3:hover > a.anchor,
@ -1419,7 +1411,7 @@ h6 > a.anchor:hover
#content h1 > a.link,
#toctitle > a.link,
.sidebarblock > .content > .title > a.link,
.sidebarblock > .title > a.link,
h2 > a.link,
h3 > a.link,
h4 > a.link,
@ -1432,7 +1424,7 @@ h6 > a.link
#content h1 > a.link:hover,
#toctitle > a.link:hover,
.sidebarblock > .content > .title > a.link:hover,
.sidebarblock > .title > a.link:hover,
h2 > a.link:hover,
h3 > a.link:hover,
h4 > a.link:hover,
@ -1512,24 +1504,25 @@ table.tableblock #preamble > .sectionbody > .paragraph:first-of-type p
margin-bottom: 0;
}
.exampleblock > .content
.exampleblock
{
margin-bottom: 1.25em;
padding: 0 1em 1em 1em;
border-width: 1px;
border-style: solid;
border-color: #e6e6e6;
-webkit-border-radius: 4px;
border-radius: 4px;
background-color: transparent;
-webkit-box-shadow: 0 1px 4px #e0e0dc;
box-shadow: 0 1px 4px #e0e0dc;
background: #fff;
}
.exampleblock > .content > :first-child
.exampleblock > :first-child
{
margin-top: 0;
}
.exampleblock > .content > :last-child
.exampleblock > :last-child
{
margin-bottom: 0;
}
@ -1556,22 +1549,23 @@ table.tableblock #preamble > .sectionbody > .paragraph:first-of-type p
margin-bottom: 0;
}
.sidebarblock > .content > .title
h6.block-title
{
margin-top: 0;
color: #7a2518;
text-align: center;
padding-bottom: 10px;
font-size: 1.6875em;
}
.exampleblock > .content > :last-child>:last-child,
.exampleblock > .content .olist > ol > li:last-child>:last-child,
.exampleblock > .content .qlist > ol > li:last-child>:last-child,
.exampleblock > .content .ulist > ul > li:last-child>:last-child,
.sidebarblock > .content > :last-child>:last-child,
.sidebarblock > .content .olist > ol > li:last-child>:last-child,
.sidebarblock > .content .qlist > ol > li:last-child>:last-child,
.sidebarblock > .content .ulist > ul > li:last-child>:last-child
.exampleblock > :last-child>:last-child,
.exampleblock > .olist > ol > li:last-child>:last-child,
.exampleblock > .qlist > ol > li:last-child>:last-child,
.exampleblock > .ulist > ul > li:last-child>:last-child,
.sidebarblock > :last-child>:last-child,
.sidebarblock > .olist > ol > li:last-child>:last-child,
.sidebarblock > .qlist > ol > li:last-child>:last-child,
.sidebarblock > .ulist > ul > li:last-child>:last-child
{
margin-bottom: 0;
}
@ -1666,7 +1660,7 @@ table.tableblock #preamble > .sectionbody > .paragraph:first-of-type p
border-width: 0;
}
.listingblock > .content
.listingblock
{
position: relative;
}
@ -2166,7 +2160,8 @@ ol.lowergreek
}
.colist > table > tbody>tr,
.hdlist > table > tbody > tr
.hdlist > table > tbody > tr,
th.hdlist1
{
background: none;
}
@ -2179,6 +2174,7 @@ td.hdlist1 > code
}
td.hdlist1,
th.hdlist1,
td.hdlist2
{
vertical-align: top;
@ -2660,14 +2656,6 @@ p.tableblock
font-size: 1em;
}
.exampleblock > .content
{
border-color: #e0e0dc;
background-color: transparent;
-webkit-box-shadow: 0 1px 4px #e0e0dc;
box-shadow: 0 1px 4px #e0e0dc;
}
.print-only
{
display: none!important;
@ -2743,7 +2731,7 @@ p.tableblock
}
#toc,
.exampleblock > .content,
.exampleblock,
.sidebarblock
{
background: none!important;

View File

@ -59,7 +59,7 @@ import org.jsoup.select.NodeVisitor;
* <li>
* Asciidoctor doesn't do a good job of rectifying situations where multiple documents are included in one
* massive (PDF) document may have identical anchors (either explicitly defined, or implicitly defined because of
* section headings). Asciidoctor also doesn't support linking directly to another (included) asciidoc
* section headings). Asciidoctor also doesn't support linking directly to another (included) asciidoc
* document by name, unless there is an explicit '#fragement' used in the link.
* </li>
* <li>
@ -83,39 +83,39 @@ import org.jsoup.select.NodeVisitor;
* </p>
* <ul>
* <li><b>-check-all-relative-links</b><br />
* <p>By default, only relative links to files in the same directory (ie: not startin with
* <code>"../"</code> are checked for existence. This means that we can do a "quick" validatation of
* links to other ref-guide files, but ignore relative links to things outside of the ref-guide --
* such as javadocs that we may not currently have built. If this option is specified then we
* <p>By default, only relative links to files in the same directory (ie: not startin with
* <code>"../"</code> are checked for existence. This means that we can do a "quick" validatation of
* links to other ref-guide files, but ignore relative links to things outside of the ref-guide --
* such as javadocs that we may not currently have built. If this option is specified then we
* <em>also</em> check relative links where the path starts with <code>"../"</code>
* </p>
* </li>
* <li><b>-bare-bones</b><br/>
* <p>By default, this tool assumes it is analyzing Jekyll generated files. If this option is specified,
* <p>By default, this tool assumes it is analyzing Jekyll generated files. If this option is specified,
* then it instead assumes it's checking "bare bones" HTML files...
* </p>
* <ul>
* <li>Jekyll Mode:
* <ul>
* <li>Requires all html pages have a "main-content" div; ignores all DOM Nodes that are
* <em>not</em> decendents of this div (to exclude redundent template based header, footer,
* <li>Requires all html pages have a "content" div; ignores all DOM Nodes that are
* <em>not</em> decendents of this div (to exclude redundent template based header, footer,
* &amp; sidebar links)
* </li>
* <li>Expects that the <code>&lt;body/&gt;</code> tag will have an <code>id</code> matching
* <li>Expects that the <code>&lt;body/&gt;</code> tag will have an <code>id</code> matching
* the page shortname.</li>
* </ul>
* </li>
* <li>Bare Bones Mode:
* <ul>
* <li>Checks all links &amp; anchors in the page.</li>
* <li>"Fakes" the existence of a <code>&lt;body id="..."&gt;</code> tag containing the
* <li>"Fakes" the existence of a <code>&lt;body id="..."&gt;</code> tag containing the
* page shortname.</li>
* </ul>
* </li>
* </ul>
* </li>
* </ul>
*
*
* TODO: build a list of all known external links so that some other tool could (optionally) ping them all for 200 status?
*
* @see https://github.com/asciidoctor/asciidoctor/issues/1865
@ -175,15 +175,15 @@ public class CheckLinksAndAnchors { // TODO: rename this class now that it does
final String fileContents = readFile(file.getPath());
final Document doc = Jsoup.parse(fileContents);
// For Jekyll, we only care about class='main-content' -- we don't want to worry
// For Jekyll, we only care about class='content' -- we don't want to worry
// about ids/links duplicated in the header/footer of every page,
final String mainContentSelector = bareBones ? "body" : ".main-content";
final String mainContentSelector = bareBones ? "body" : ".content";
final Element mainContent = doc.select(mainContentSelector).first();
if (mainContent == null) {
throw new RuntimeException(file.getName() + " has no main content: " + mainContentSelector);
}
// Add all of the IDs in (the main-content of) this doc to idsToFiles (and idsInMultiFiles if needed)
// Add all of the IDs in (the content of) this doc to idsToFiles (and idsInMultiFiles if needed)
final Elements nodesWithIds = mainContent.select("[id]");
if (bareBones) {