├── .editorconfig ├── .github ├── FUNDING.yml └── workflows │ └── ci.yml ├── .gitignore ├── Gemfile ├── LICENSE ├── README.adoc ├── Rakefile ├── asciidoctor-html5s.gemspec ├── data └── templates │ ├── _attribution.html.slim │ ├── _footer.html.slim │ ├── _footnotes.html.slim │ ├── _header.html.slim │ ├── _toc.html.slim │ ├── admonition.html.slim │ ├── audio.html.slim │ ├── colist.html.slim │ ├── dlist.html.slim │ ├── document.html.slim │ ├── embedded.html.slim │ ├── empty.html.slim │ ├── example.html.slim │ ├── floating_title.html.slim │ ├── helpers.rb │ ├── image.html.slim │ ├── inline_anchor.html.slim │ ├── inline_break.html.slim │ ├── inline_button.html.slim │ ├── inline_callout.html.slim │ ├── inline_footnote.html.slim │ ├── inline_image.html.slim │ ├── inline_indexterm.html.slim │ ├── inline_kbd.html.slim │ ├── inline_menu.html.slim │ ├── inline_quoted.html.slim │ ├── listing.html.slim │ ├── literal.html.slim │ ├── olist.html.slim │ ├── open.html.slim │ ├── outline.html.slim │ ├── page_break.html.slim │ ├── paragraph.html.slim │ ├── pass.html.slim │ ├── preamble.html.slim │ ├── quote.html.slim │ ├── section.html.slim │ ├── sidebar.html.slim │ ├── stem.html.slim │ ├── table.html.slim │ ├── thematic_break.html.slim │ ├── toc.html.slim │ ├── ulist.html.slim │ ├── verse.html.slim │ └── video.html.slim ├── lib ├── asciidoctor-html5s.rb └── asciidoctor │ ├── html5s.rb │ └── html5s │ ├── attached_colist_treeprocessor.rb │ ├── html_pipeline_highlighter.rb │ ├── replacements.rb │ └── version.rb ├── package.json ├── src └── asciidoctor-html5s.tmpl.js └── test └── examples ├── asciidoc-html ├── README ├── example.adoc ├── image.adoc ├── inline_image.adoc ├── inline_quoted.adoc ├── listing.adoc ├── outline.adoc ├── regressions.adoc ├── replacements.adoc └── video.adoc └── html5 ├── admonition.html ├── audio.html ├── colist.html ├── dlist.html ├── document.html ├── embedded.html ├── example.html ├── floating_title.html ├── image.html ├── inline_anchor.html ├── inline_break.html ├── inline_button.html ├── inline_callout.html ├── inline_footnote.html ├── inline_image.html ├── inline_kbd.html ├── inline_menu.html ├── inline_quoted.html ├── listing.html ├── literal.html ├── olist.html ├── open.html ├── outline.html ├── page_break.html ├── paragraph.html ├── pass.html ├── preamble.html ├── quote.html ├── regressions.html ├── replacements.html ├── section.html ├── sidebar.html ├── stem.html ├── table.html ├── thematic_break.html ├── toc.html ├── ulist.html ├── verse.html └── video.html /.editorconfig: -------------------------------------------------------------------------------- 1 | # top-most editorconfig file 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | indent_style = space 10 | indent_size = 2 11 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: jirutka 4 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | - push 4 | - pull_request 5 | 6 | jobs: 7 | test: 8 | name: Test with Asciidoctor ${{ matrix.asciidoctor }} on Ruby ${{ matrix.ruby }} 9 | runs-on: ubuntu-latest 10 | strategy: 11 | fail-fast: false 12 | matrix: 13 | ruby: 14 | - '3.1' 15 | - '3.0' 16 | - '2.7' 17 | #- head TODO: Uncomment after asciidoctor fixes compatibility with Ruby >=3.5 18 | - jruby-head 19 | asciidoctor: [2.0.17] 20 | include: 21 | - { asciidoctor: 'git:main', ruby: 3.1 } 22 | - { asciidoctor: 2.0.10 , ruby: 2.7 } 23 | - { asciidoctor: 2.0.0 , ruby: 2.7 } 24 | - { asciidoctor: 1.5.8 , ruby: 2.7 } 25 | - { asciidoctor: 1.5.7.1 , ruby: 2.7 } 26 | - { asciidoctor: 1.5.7 , ruby: 2.7 } 27 | env: 28 | CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }} 29 | ASCIIDOCTOR_VERSION: ${{ matrix.asciidoctor }} 30 | continue-on-error: ${{ endsWith(matrix.ruby, 'head') || matrix.asciidoctor == 'git:main' }} 31 | steps: 32 | - uses: actions/checkout@v2 33 | 34 | - run: sudo apt-get install pandoc 35 | 36 | - uses: ruby/setup-ruby@v1 37 | with: 38 | ruby-version: ${{ matrix.ruby }} 39 | bundler-cache: false # XXX: problems with nokogiri on ruby 3.1+ 40 | 41 | - run: bundle install 42 | 43 | - run: bundle exec rake test 44 | 45 | - if: matrix.ruby != 'jruby-head' 46 | run: bundle exec rake build:js 47 | 48 | - run: bundle exec rake readme2md 49 | 50 | publish: 51 | name: Publish to RubyGems and npmjs 52 | needs: [test] 53 | if: startsWith(github.ref, 'refs/tags/v') 54 | runs-on: ubuntu-latest 55 | steps: 56 | - uses: actions/checkout@v2 57 | 58 | - run: sudo apt-get install pandoc 59 | 60 | - uses: ruby/setup-ruby@v1 61 | with: 62 | ruby-version: 2.7 63 | bundler-cache: true 64 | 65 | - uses: actions/setup-node@v2 66 | with: 67 | node-version: 12 68 | registry-url: https://registry.npmjs.org 69 | 70 | - run: bundle exec rake build 71 | - run: bundle exec rake build:js 72 | - run: bundle exec rake readme2md 73 | 74 | - name: Publish to RubyGems 75 | run: | 76 | install -D -m 0600 /dev/null $HOME/.gem/credentials 77 | printf -- '---\n:rubygems_api_key: %s\n' "$RUBYGEMS_API_KEY" > $HOME/.gem/credentials 78 | gem build *.gemspec 79 | gem push *.gem 80 | env: 81 | RUBYGEMS_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }} # c9a4......f34d 82 | 83 | - name: Publish to npmjs 84 | run: npm publish 85 | env: 86 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} # d0e3......b2a6 87 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /dist/ 2 | /pkg/ 3 | node_modules/ 4 | *.gem 5 | *.log 6 | Gemfile.lock 7 | README.md 8 | package-lock.json 9 | yarn.lock 10 | lib/asciidoctor/html5s/converter.rb 11 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | gemspec 3 | 4 | unless ENV.fetch('ASCIIDOCTOR_VERSION', '').empty? 5 | if (match = ENV['ASCIIDOCTOR_VERSION'].match(/^git:(\w+)/)) 6 | gem 'asciidoctor', github: 'asciidoctor/asciidoctor', ref: match[1] 7 | else 8 | gem 'asciidoctor', ENV['ASCIIDOCTOR_VERSION'] 9 | end 10 | end 11 | 12 | group :development do 13 | # Keep in sync with version used in opal-node-runtime <- asciidoctor.js. 14 | # TODO: Maybe replace with JS version after 15 | # https://github.com/Mogztter/opal-node-compiler/issues/6 is resolved. 16 | gem 'opal', github: 'opal/opal', ref: 'v1.7.3' 17 | end 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright 2014-2020 Jakub Jirutka . 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.adoc: -------------------------------------------------------------------------------- 1 | = Semantic HTML5 Backend For Asciidoctor 2 | // custom 3 | :gem-name: asciidoctor-html5s 4 | :gh-name: jirutka/{gem-name} 5 | :gh-branch: master 6 | 7 | ifdef::env-github[] 8 | image:https://github.com/{gh-name}/workflows/CI/badge.svg[CI Status, link=https://github.com/{gh-name}/actions?query=workflow%3A%22CI%22] 9 | image:https://img.shields.io/gem/v/{gem-name}.svg?style=flat[Gem Version, link="https://rubygems.org/gems/{gem-name}"] 10 | image:https://img.shields.io/npm/v/{gem-name}.svg?style=flat[npm Version, link="https://www.npmjs.org/package/{gem-name}"] 11 | endif::env-github[] 12 | 13 | This project provides alternative HTML5 converter (backend) for http://asciidoctor.org/[Asciidoctor] that focuses on correct semantics, accessibility and compatibility with common typographic CSS styles. 14 | 15 | 16 | == Goals 17 | 18 | * Clean markup with correct HTML5 semantics. 19 | * Good accessibility for people with disabilities. 20 | * Compatibility with common typographic CSS styles when possible and especially with GitHub and GitLab. 21 | * Full standalone converter without fallback to the built-in Asciidoctor converters. 22 | * Easy to use and integrate into third-party projects. 23 | * Well readable and maintainable code – this should be never sacrificed for performance (I’m looking at you, Asciidoctor!). 24 | 25 | 26 | == Non-goals 27 | 28 | * Compatibility with existing Asciidoctor CSS styles. 29 | 30 | 31 | == Text Substitutions 32 | 33 | === Quotes 34 | 35 | Asciidoctor provides syntax for so-called https://asciidoctor.org/docs/user-manual/#curved[“curved quotation marks”] (which are actually just the _correct_ quotation marks), but the built-in converters outputs only one (hard-coded) type of the single/double quotation marks -- that one used in English and few other languages. 36 | This converter outputs the correct type of the quotation marks based on the specified language (using standard `lang` attribute). 37 | 38 | 39 | [cols="2,^1l,3,^1l,^1"] 40 | |=== 41 | | Name | Syntax | Languages (:lang:) | HTML | Rendered 42 | 43 | .4+| double quotes 44 | .4+| "`word`" 45 | | af, en, eo, ga, hi, ia, id, ko, mt, th, tr, zh 46 | | “word” 47 | | “word” 48 | 49 | | bs, fi, sv 50 | | ”word” 51 | | ”word” 52 | 53 | | cs, da, de, is, lt, sl, sk, sr 54 | | „word“ 55 | | „word“ 56 | 57 | | hu, pl, nl, ro 58 | | „word” 59 | | „word” 60 | 61 | .5+| single quotes 62 | .5+| '`word`' 63 | | af, en, eo, ga, hi, ia, id, ko, mt, th, tr, zh 64 | | ‘word’ 65 | | ‘word’ 66 | 67 | | bs, fi, sv 68 | | ’word’ 69 | | ’word’ 70 | 71 | | cs, da, de, is, lt, sl, sk, sr 72 | | ‚word‘ 73 | | ‚word‘ 74 | 75 | | nl 76 | | ‚word’ 77 | | ‚word’ 78 | 79 | | hu, pl, ro 80 | | «word» 81 | | «word» 82 | |=== 83 | 84 | The default (fallback) type is the first one. 85 | 86 | 87 | === Replacements 88 | 89 | Asciidoctor replaces `--` with em dash (—) and does not provide any replacement for en dash (–). 90 | That’s not very convenient, because en dash is more common than em dash; at least in (British) English and Czech (actually we don’t use em dash at all). 91 | So this extension also modifies the https://asciidoctor.org/docs/user-manual/#replacements[replacements table]: changes `--` to en dash and adds `---` for em dash. 92 | 93 | [cols="2,^1l,^1l,^1,2"] 94 | |=== 95 | | Name | Syntax | Unicode | Rendered | Notes 96 | 97 | | En dash 98 | | -- 99 | | – 100 | | – 101 | .2+| Only replaced if between two word characters, between a word character and a line boundary, or flanked by spaces. 102 | 103 | When flanked by space characters (e.g. `+a -- b+` or `+a --- b+`), the normal spaces are replaced by thin spaces (\ ). 104 | 105 | | Em dash 106 | | --- 107 | | — 108 | | — 109 | 110 | |=== 111 | 112 | 113 | == Other Enhancements 114 | 115 | === Image Block 116 | 117 | The `link` attribute recognizes few special values: 118 | 119 | link=self:: 120 | Make the image a link with URL of the image itself – to open it in full size. 121 | 122 | link=none / link=false:: 123 | Suppress the effect of `:html5s-image-default-link: self`, i.e. remove the default image link. 124 | 125 | Both block image and inline image supports additional attribute `loading` (see https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading#Images[Lazy loading] on MDN for more information). 126 | 127 | 128 | === Additional Inline Formatting Roles 129 | 130 | del:: 131 | `++[del]#deleted text#++` is rendered as `deleted text`. 132 | 133 | ins:: 134 | `++[ins]#inserted text#++` is rendered as `inserted text`. 135 | 136 | strike:: 137 | `++[strike]#inserted text#++` is rendered as `inserted text`. 138 | This is an alias for `line-through`. 139 | 140 | 141 | == Requirements 142 | 143 | Note: This converter consists of https://github.com/slim-template/slim/[Slim] templates, but they are precompiled into pure Ruby code using https://github.com/jirutka/asciidoctor-templates-compiler/[asciidoctor-templates-compiler], so you don’t need Slim to use it! 144 | 145 | ifndef::npm-readme[] 146 | === Ruby 147 | 148 | * https://www.ruby-lang.org/[Ruby] 2.0+ or http://jruby.org/[JRuby] 9.1+ 149 | * https://rubygems.org/gems/asciidoctor/[Asciidoctor] 1.5.7+ 150 | * https://rubygems.org/gems/thread_safe/[thread_safe] (not required, but recommended for Ruby MRI) 151 | 152 | 153 | === Node.js 154 | endif::npm-readme[] 155 | 156 | * https://nodejs.org/[Node.js] 157 | * https://www.npmjs.com/package/@asciidoctor/core[@asciidoctor/core] >=3.0.0 <4.0.0 158 | 159 | 160 | == Installation 161 | 162 | ifndef::npm-readme[] 163 | === Ruby 164 | 165 | Install {gem-name} from Rubygems: 166 | 167 | [source, sh, subs="+attributes"] 168 | gem install {gem-name} 169 | 170 | or to get the latest development version: 171 | 172 | [source, sh, subs="+attributes"] 173 | gem install --pre {gem-name} 174 | 175 | 176 | === Node.js 177 | endif::npm-readme[] 178 | 179 | Install {gem-name} from npmjs.com: 180 | 181 | [source, sh, subs="+attributes"] 182 | npm install --save {gem-name} 183 | 184 | 185 | == Usage 186 | 187 | ifndef::npm-readme[] 188 | === CLI 189 | 190 | [source, sh, subs="+attributes"] 191 | asciidoctor -r {gem-name} -b html5s FILE... 192 | 193 | 194 | === Node.js 195 | endif::npm-readme[] 196 | 197 | [source, js, subs="+attributes"] 198 | ---- 199 | // Load asciidoctor.js and {gem-name}. 200 | const asciidoctor = require('@asciidoctor/core')() 201 | const asciidoctorHtml5s = require('{gem-name}') 202 | 203 | // Register the HTML5s converter and supporting extension. 204 | asciidoctorHtml5s.register() 205 | 206 | // Convert the content to HTML using html5s converter. 207 | const content = "Hello, *world!*!" 208 | const html = asciidoctor.convert(content, { backend: 'html5s' }) 209 | console.log(html) 210 | ---- 211 | 212 | 213 | === Attributes 214 | 215 | Extra attributes accepted by the {gem-name}: 216 | 217 | html5s-force-stem-type:: 218 | Ignore declared (e.g. `:stem: asciimath`, `asciimath:[]`, ...) and default type of the stem macro/block and always use the one specified by this attribute. + 219 | Asciidoctor hard-codes the default stem type to “asciimath”, which is not supported by KaTeX. 220 | 221 | html5s-image-default-link: self:: 222 | Make every block image a link with the image’s source URL (i.e. user can click on the image to open it in full size), unless the link attribute is defined and is not `none` or `false`. 223 | 224 | html5s-image-self-link-label:: 225 | The link title and ARIA label for the block image link that points to the image file (i.e. `href` equals the image’s `src`). 226 | Default is `Open the image in full size`. 227 | 228 | 229 | == License 230 | 231 | This project is licensed under http://opensource.org/licenses/MIT/[MIT License]. 232 | For the full text of the license, see the link:LICENSE[LICENSE] file. 233 | 234 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | require 'bundler/gem_tasks' 3 | require 'rake/clean' 4 | 5 | BACKEND_NAME = 'html5s' 6 | CONVERTER_FILE = 'lib/asciidoctor/html5s/converter.rb' 7 | JS_FILE = 'dist/asciidoctor-html5s.js' 8 | TEMPLATES_DIR = 'data/templates' 9 | 10 | 11 | file CONVERTER_FILE => FileList["#{TEMPLATES_DIR}/*"] do 12 | build_converter :fast 13 | end 14 | 15 | namespace :build do 16 | desc 'Compile Slim templates and generate converter.rb' 17 | task :converter do 18 | build_converter 19 | end 20 | 21 | desc 'Compile Slim templates and generate converter.rb for Opal' 22 | task 'converter:opal' do 23 | build_converter :opal 24 | end 25 | 26 | desc "Transcompile to JavaScript and generate #{JS_FILE}" 27 | task :js => 'converter:opal' do 28 | require 'opal' 29 | 30 | builder = Opal::Builder.new(compiler_options: { 31 | dynamic_require_severity: :error, 32 | }) 33 | builder.append_paths 'lib' 34 | builder.build 'asciidoctor/html5s' 35 | 36 | mkdir_p File.dirname(JS_FILE) 37 | File.open(JS_FILE, 'w') do |file| 38 | template = File.read('src/asciidoctor-html5s.tmpl.js') 39 | file << template.sub('//OPAL-GENERATED-CODE//') { builder.to_s } 40 | end 41 | File.binwrite "#{JS_FILE}.map", builder.source_map 42 | end 43 | end 44 | 45 | task :build => 'build:converter' 46 | 47 | task :readme2md do 48 | require 'asciidoctor' 49 | require 'pandoc-ruby' 50 | 51 | docbook = Asciidoctor 52 | .load_file('README.adoc', header_footer: true, backend: 'docbook', attributes: 'npm-readme') 53 | .convert 54 | markdown = PandocRuby 55 | .convert(docbook, from: :docbook, to: :markdown_github, 'base-header-level': 2) 56 | 57 | File.write('README.md', markdown) 58 | end 59 | 60 | task :clean do 61 | rm_rf CONVERTER_FILE 62 | rm_rf Dir['*.gem'] 63 | rm_rf Dir['asciidoctor-html5s-*.tgz'] 64 | rm_rf Dir['dist/*.js'] 65 | rm_rf Dir['dist/*.js.map'] 66 | rm_rf Dir['pkg/*.gem'] 67 | rm_rf 'README.md' 68 | end 69 | 70 | begin 71 | require 'asciidoctor/doctest' 72 | 73 | DocTest::RakeTasks.new(:doctest) do |t| 74 | t.output_examples :html, path: 'test/examples/html5' 75 | t.input_examples :asciidoc, path: [ 76 | *DocTest.examples_path, 77 | 'test/examples/asciidoc-html' 78 | ] 79 | t.converter = DocTest::HTML::Converter 80 | t.converter_opts = { backend_name: BACKEND_NAME } 81 | end 82 | 83 | task '.prepare-converter' do 84 | # Run as an external process to ensure that it will not affect tests 85 | # environment with extra loaded modules (especially slim). 86 | `bundle exec rake #{CONVERTER_FILE}` 87 | 88 | require_relative 'lib/asciidoctor-html5s' 89 | end 90 | 91 | task 'doctest:test' => '.prepare-converter' 92 | task 'doctest:generate' => '.prepare-converter' 93 | task :test => 'doctest:test' 94 | task :default => :test 95 | rescue LoadError => e 96 | warn "#{e.path} is not available" 97 | end 98 | 99 | 100 | def build_converter(mode = :pretty) 101 | require 'asciidoctor-templates-compiler' 102 | require 'slim-htag' 103 | 104 | generator = if mode == :opal 105 | Temple::Generators::ArrayBuffer.new(freeze_static: false) 106 | else 107 | Temple::Generators::StringBuffer 108 | end 109 | 110 | File.open(CONVERTER_FILE, 'w') do |file| 111 | puts "Generating #{file.path} (mode: #{mode})." 112 | 113 | Asciidoctor::TemplatesCompiler::Slim.compile_converter( 114 | templates_dir: TEMPLATES_DIR, 115 | class_name: 'Asciidoctor::Html5s::Converter', 116 | register_for: [BACKEND_NAME], 117 | backend_info: { 118 | basebackend: 'html', 119 | outfilesuffix: '.html', 120 | filetype: 'html', 121 | supports_templates: true, 122 | }, 123 | engine_opts: { 124 | generator: generator, 125 | }, 126 | ignore_convert_opts: (mode == :opal), 127 | pretty: (mode == :pretty), 128 | output: file 129 | ) 130 | end 131 | end 132 | -------------------------------------------------------------------------------- /asciidoctor-html5s.gemspec: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | require File.expand_path('lib/asciidoctor/html5s/version', __dir__) 3 | 4 | Gem::Specification.new do |s| 5 | s.name = 'asciidoctor-html5s' 6 | s.version = Asciidoctor::Html5s::VERSION 7 | s.author = 'Jakub Jirutka' 8 | s.email = 'jakub@jirutka.cz' 9 | s.homepage = 'https://github.com/jirutka/asciidoctor-html5s' 10 | s.license = 'MIT' 11 | 12 | s.summary = 'Semantic HTML5 backend (converter) for Asciidoctor' 13 | s.description = <<-EOF 14 | #{s.summary} 15 | 16 | This converter focuses on correct semantics, accessibility and compatibility 17 | with common typographic CSS styles. 18 | EOF 19 | 20 | s.files = Dir['data/**/*', 'lib/**/*', '*.gemspec', 'LICENSE*', 'README.adoc'] 21 | 22 | s.required_ruby_version = '>= 2.0' 23 | 24 | s.add_runtime_dependency 'asciidoctor', '>= 1.5.7', '< 3.0' 25 | s.add_runtime_dependency 'thread_safe', '~> 0.3.4' 26 | 27 | s.add_development_dependency 'asciidoctor-doctest', '= 2.0.0.rc.1' 28 | s.add_development_dependency 'asciidoctor-templates-compiler', '~> 0.6.0' 29 | s.add_development_dependency 'bundler', '>= 1.6' 30 | s.add_development_dependency 'pandoc-ruby', '~> 2.0' 31 | s.add_development_dependency 'rake', '~> 13.0' 32 | s.add_development_dependency 'slim', '~> 3.0' 33 | s.add_development_dependency 'slim-htag', '~> 0.1.0' 34 | end 35 | -------------------------------------------------------------------------------- /data/templates/_attribution.html.slim: -------------------------------------------------------------------------------- 1 | footer 2 | '— 3 | cite 4 | =[(attr :attribution), (attr :citetitle)].compact.join(', ') 5 | -------------------------------------------------------------------------------- /data/templates/_footer.html.slim: -------------------------------------------------------------------------------- 1 | #footer-text 2 | - if attr? :revnumber 3 | | #{attr 'version-label'} #{attr :revnumber} 4 | - if attr? 'last-update-label' 5 | br 6 | | #{attr 'last-update-label'} #{attr :docdatetime} 7 | - unless (docinfo_content = (docinfo :footer)).empty? 8 | =docinfo_content 9 | -------------------------------------------------------------------------------- /data/templates/_footnotes.html.slim: -------------------------------------------------------------------------------- 1 | section.footnotes aria-label='Footnotes' role='doc-endnotes' 2 | hr 3 | ol.footnotes 4 | - footnotes.each do |fn| 5 | li.footnote id=(footnote_id fn.index) role='doc-endnote' 6 | ="#{fn.text} " 7 | a.footnote-backref [ 8 | href="##{footnoteref_id fn.index}" 9 | role='doc-backlink' 10 | title='Jump to the first occurrence in the text' ] 11 | | ↩ 12 | -------------------------------------------------------------------------------- /data/templates/_header.html.slim: -------------------------------------------------------------------------------- 1 | - if header? 2 | - unless notitle 3 | h1 =header.title 4 | - if [:author, :revnumber, :revdate, :revremark].any? {|a| attr? a } 5 | .details 6 | - if attr? :author 7 | span.author#author =(attr :author) 8 | br 9 | - if attr? :email 10 | span.email#email =sub_macros(attr :email) 11 | br 12 | - if (authorcount = (attr :authorcount).to_i) > 1 13 | - (2..authorcount).each do |idx| 14 | span.author id="author#{idx}" =(attr "author_#{idx}") 15 | br 16 | - if attr? "email_#{idx}" 17 | span.email id="email#{idx}" =sub_macros(attr "email_#{idx}") 18 | - if attr? :revnumber 19 | span#revnumber #{((attr 'version-label') || '').downcase} #{attr :revnumber}#{',' if attr? :revdate} 20 | ' 21 | - if attr? :revdate 22 | time#revdate datetime=revdate_iso =(attr :revdate) 23 | - if attr? :revremark 24 | br 25 | span#revremark =(attr :revremark) 26 | - if (attr? :toc) && (attr? 'toc-placement', 'auto') 27 | include _toc.html 28 | -------------------------------------------------------------------------------- /data/templates/_toc.html.slim: -------------------------------------------------------------------------------- 1 | nav#toc class=(document.attr 'toc-class', 'toc') role='doc-toc' 2 | h2#toc-title =(document.attr 'toc-title') 3 | / Renders block_outline.html. 4 | = converter.convert document, 'outline' 5 | -------------------------------------------------------------------------------- /data/templates/admonition.html.slim: -------------------------------------------------------------------------------- 1 | - capture 2 | h6.block-title class=('label-only' unless title?) 3 | span.title-label ="#{local_attr :textlabel}: " 4 | =title 5 | = html_tag_if !blocks?, :p 6 | =content 7 | - if admonition_aside? 8 | aside.admonition-block id=id class=[(attr :name), role] role=admonition_aria 9 | - yield_capture 10 | - else 11 | section.admonition-block id=id class=[(attr :name), role] role=admonition_aria 12 | - yield_capture 13 | -------------------------------------------------------------------------------- /data/templates/audio.html.slim: -------------------------------------------------------------------------------- 1 | = block_with_caption :bottom, :class=>'audio-block' 2 | audio [ 3 | src=media_uri(attr :target) 4 | autoplay=(option? 'autoplay') 5 | controls=!(option? 'nocontrols') 6 | loop=(option? 'loop') ] 7 | | Your browser does not support the audio tag. 8 | -------------------------------------------------------------------------------- /data/templates/colist.html.slim: -------------------------------------------------------------------------------- 1 | / Note: We ignore title on callout list here. 2 | ol.callout-list id=id class=[style, role] 3 | - items.each do |item| 4 | li =item.text 5 | -------------------------------------------------------------------------------- /data/templates/dlist.html.slim: -------------------------------------------------------------------------------- 1 | = block_with_title :class=>['dlist', style], :role=>('doc-qna' if style == 'qanda') 2 | dl class=style 3 | - items.each do |terms, dd| 4 | - [*terms].each do |dt| 5 | dt =dt.text 6 | - unless dd.nil? 7 | dd =(print_item_content dd) 8 | -------------------------------------------------------------------------------- /data/templates/document.html.slim: -------------------------------------------------------------------------------- 1 | doctype 5 2 | html lang=(attr :lang, 'en' unless attr? :nolang) 3 | / Render the document content before styles_and_scripts - 4 | / SyntaxHighlighter#docinfo must be called after SyntaxHighlighter#highlight 5 | / because some highlighter plugins emit style/script tags only when 6 | / #highlight was called at least once. 7 | - document_content = content 8 | head 9 | meta charset=(attr :encoding, 'UTF-8') 10 | meta http-equiv="X-UA-Compatible" content="IE=edge" 11 | meta name='viewport' content='width=device-width, initial-scale=1.0' 12 | meta name='generator' content="Asciidoctor #{attr 'asciidoctor-version'}" 13 | = html_meta_if 'application-name', (attr 'app-name') 14 | = html_meta_if 'author', (attr :authors) 15 | = html_meta_if 'copyright', (attr :copyright) 16 | = html_meta_if 'description', (attr :description) 17 | = html_meta_if 'keywords', (attr :keywords) 18 | title=((doctitle sanitize: true) || (attr 'untitled-label')) 19 | = styles_and_scripts 20 | - unless (docinfo_content = docinfo).empty? 21 | =docinfo_content 22 | body [ 23 | id=id 24 | class=[(attr :doctype), 25 | ("#{attr 'toc-class'} toc-#{attr 'toc-position', 'left'}" if (attr? 'toc-class') && (attr? :toc) && (attr? 'toc-placement', 'auto')), 26 | (attr :docrole) || (attr :role)] 27 | style=style_value(max_width: (attr 'max-width')) ] 28 | - unless (docinfo_content = (docinfo :header)).empty? 29 | =docinfo_content 30 | - unless noheader 31 | header 32 | include _header.html 33 | #content =document_content 34 | - unless !footnotes? || (attr? :nofootnotes) 35 | include _footnotes.html 36 | - unless nofooter 37 | footer 38 | include _footer.html 39 | -------------------------------------------------------------------------------- /data/templates/embedded.html.slim: -------------------------------------------------------------------------------- 1 | - if !notitle && header? 2 | h1 id=id =header.title 3 | - if node.sections? && (attr? :toc) && (attr 'toc-placement', 'auto') == 'auto' 4 | include _toc.html 5 | =content 6 | - if footnotes? && !(attr? :nofootnotes) 7 | include _footnotes.html 8 | -------------------------------------------------------------------------------- /data/templates/empty.html.slim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jirutka/asciidoctor-html5s/84d5ab3605691e0d29c9b324b074788677361279/data/templates/empty.html.slim -------------------------------------------------------------------------------- /data/templates/example.html.slim: -------------------------------------------------------------------------------- 1 | - if option? :collapsible 2 | details id=id class=role open=(option? :open) 3 | - if title 4 | summary 5 | =title 6 | .content 7 | =content 8 | - else 9 | = block_with_caption :top, :class=>'example-block' 10 | .example 11 | =content 12 | -------------------------------------------------------------------------------- /data/templates/floating_title.html.slim: -------------------------------------------------------------------------------- 1 | h level=(level + 1) id=id class=[style, role] 2 | =title 3 | -------------------------------------------------------------------------------- /data/templates/helpers.rb: -------------------------------------------------------------------------------- 1 | require 'asciidoctor/html5s' 2 | require 'date' unless RUBY_PLATFORM == 'opal' 3 | 4 | # Add custom functions to this module that you want to use in your Slim 5 | # templates. Within the template you can invoke them as top-level functions 6 | # just like in Haml. 7 | module Slim::Helpers 8 | 9 | # URIs of external assets. 10 | CDN_BASE_URI = 'https://cdnjs.cloudflare.com/ajax/libs' # for highlighters in Asciidoctor >=2.0.0 11 | FONT_AWESOME_URI = 'https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css' 12 | HIGHLIGHTJS_BASE_URI = 'https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@9.15.1/build/' 13 | KATEX_CSS_URI = 'https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.css' 14 | KATEX_JS_URI = 'https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.js' 15 | 16 | # Defaults 17 | DEFAULT_HIGHLIGHTJS_THEME = 'github' 18 | DEFAULT_LANG = 'en' 19 | DEFAULT_SECTNUMLEVELS = 3 20 | DEFAULT_TOCLEVELS = 2 21 | 22 | CURLY_QUOTES = [ 23 | [%w[af en eo ga hi ia id ko mt th tr zh], ['‘', '’', '“', '”']], # ‘…’ “…” 24 | [%w[bs fi sv], ['’', '’', '”', '”']], # ’…’ ”…” 25 | [%w[cs da de is lt sl sk sr], ['‚', '‘', '„', '“']], # ‚…‘ „…“ 26 | [%w[nl], ['‚', '’', '„', '”']], # ‚…’ „…” 27 | [%w[hu pl ro], ['«', '»', '„', '”']], # «…» „…” 28 | ].reduce({}) do |hsh, (langs, codes)| 29 | langs.each { |lang| hsh[lang] = codes } 30 | hsh 31 | end 32 | CURLY_QUOTES.default = CURLY_QUOTES[DEFAULT_LANG] 33 | 34 | KATEX_RENDER_CODE = <<-JS.gsub(/\s+/, ' ') 35 | document.addEventListener("DOMContentLoaded", function() { 36 | var elements = document.getElementsByClassName("math"); 37 | for (var i = 0; i < elements.length; i++) { 38 | var el = elements[i]; 39 | if (el.getAttribute("data-lang") !== "tex") { 40 | continue; 41 | } 42 | katex.render(el.textContent.slice(2, -2), el, { 43 | "displayMode": el.nodeName.toUpperCase() !== "SPAN", 44 | "throwOnError": false, 45 | }); 46 | } 47 | }); 48 | JS 49 | 50 | VOID_ELEMENTS = %w(area base br col command embed hr img input keygen link 51 | meta param source track wbr) 52 | 53 | 54 | # @return [Logger] 55 | def log 56 | ::Asciidoctor::LoggerManager.logger 57 | end 58 | 59 | ## 60 | # Captures the given block for later yield. 61 | # 62 | # @example Basic capture usage. 63 | # - capture 64 | # img src=image_uri 65 | # - if title? 66 | # figure.image 67 | # - yield_capture 68 | # figcaption =captioned_title 69 | # - else 70 | # - yield_capture 71 | # 72 | # @example Capture with passing parameters. 73 | # - capture do |id| 74 | # img src=image_uri 75 | # - if title? 76 | # figure id=@id 77 | # - yield_capture 78 | # figcaption =caption 79 | # - else 80 | # - yield_capture @id 81 | # 82 | # @see yield_capture 83 | def capture(&block) 84 | @_html5s_capture = block 85 | nil 86 | end 87 | 88 | ## 89 | # Yields the captured block (see {#capture}). 90 | # 91 | # @param *params parameters to pass to the block. 92 | # @return A content of the captured block. 93 | # @see capture 94 | def yield_capture(*params) 95 | @_html5s_capture.call(*params) if @_html5s_capture 96 | end 97 | 98 | ## 99 | # Creates an HTML tag with the given name and optionally attributes. Can take 100 | # a block that will run between the opening and closing tags. 101 | # 102 | # @param name [#to_s] the name of the tag. 103 | # @param attributes [Hash] (default: {}) 104 | # @param content [#to_s] the content; +nil+ to call the block. (default: nil). 105 | # @yield The block of Slim/HTML code within the tag (optional). 106 | # @return [String] a rendered HTML element. 107 | # 108 | def html_tag(name, attributes = {}, content = nil) 109 | attrs = attributes.inject([]) do |attrs, (k, v)| 110 | next attrs if !v || v.nil_or_empty? 111 | v = v.compact.join(' ') if v.is_a? Array 112 | attrs << (v == true ? k : %(#{k}="#{v}")) 113 | end 114 | attrs_str = attrs.empty? ? '' : ' ' + attrs.join(' ') 115 | 116 | if VOID_ELEMENTS.include? name.to_s 117 | %(<#{name}#{attrs_str}>) 118 | else 119 | content ||= yield if block_given? 120 | %(<#{name}#{attrs_str}>#{content}) 121 | end 122 | end 123 | 124 | ## 125 | # Conditionally wraps a block in an element. If condition is +true+ then it 126 | # renders the specified tag with optional attributes and the given 127 | # block inside, otherwise it just renders the block. 128 | # 129 | # For example: 130 | # 131 | # = html_tag_if link?, 'a', {class: 'image', href: (attr :link)} 132 | # img src='./img/tux.png' 133 | # 134 | # will produce: 135 | # 136 | # 137 | # 138 | # 139 | # 140 | # if +link?+ is truthy, and just 141 | # 142 | # 143 | # 144 | # otherwise. 145 | # 146 | # @param condition [Boolean] the condition to test to determine whether to 147 | # render the enclosing tag. 148 | # @param name (see #html_tag) 149 | # @param attributes (see #html_tag) 150 | # @param content (see #html_tag) 151 | # @yield (see #html_tag) 152 | # @return [String] a rendered HTML fragment. 153 | # 154 | def html_tag_if(condition, name, attributes = {}, content = nil, &block) 155 | if condition 156 | html_tag name, attributes, content, &block 157 | else 158 | content || yield 159 | end 160 | end 161 | 162 | ## 163 | # Wraps a block in a div element with the specified class and optionally 164 | # the node's +id+ and +role+(s). If the node's +title+ is not empty, then a 165 | # nested div with the class "title" and the title's content is added as well. 166 | # 167 | # @example When @id, @role and @title attributes are set. 168 | # = block_with_title :class=>['quote-block', 'center'] 169 | # blockquote =content 170 | # 171 | #
172 | #
Block Title
173 | #
Lorem ipsum
174 | #
175 | # 176 | # @example When @id, @role and @title attributes are empty. 177 | # = block_with_title :class=>'quote-block center', :style=>style_value(float: 'left') 178 | # blockquote =content 179 | # 180 | #
181 | #
Lorem ipsum
182 | #
183 | # 184 | # @example When shorthand style for class attribute is used. 185 | # = block_with_title 'quote-block center' 186 | # blockquote =content 187 | # 188 | #
189 | #
Lorem ipsum
190 | #
191 | # 192 | # @param attrs [Hash, String] the tag's attributes as Hash), 193 | # or the tag's class if it's not a Hash. 194 | # @param title [String, nil] the title. 195 | # @yield The block of Slim/HTML code within the tag (optional). 196 | # @return [String] a rendered HTML fragment. 197 | # 198 | def block_with_title(attrs = {}, title = @title, &block) 199 | if (klass = attrs[:class]).is_a? String 200 | klass = klass.split(' ') 201 | end 202 | attrs[:class] = [klass, role].flatten.uniq 203 | attrs[:id] = id 204 | 205 | if title.nil_or_empty? 206 | # XXX quick hack 207 | nested = is_a?(::Asciidoctor::List) && 208 | (parent.is_a?(::Asciidoctor::ListItem) || parent.is_a?(::Asciidoctor::List)) 209 | html_tag_if !nested, :div, attrs, yield 210 | else 211 | html_tag :section, attrs do 212 | [html_tag(:h6, {class: 'block-title'}, title), yield].join("\n") 213 | end 214 | end 215 | end 216 | 217 | def block_with_caption(position = :bottom, attrs = {}, &block) 218 | if (klass = attrs[:class]).is_a? String 219 | klass = klass.split(' ') 220 | end 221 | attrs[:class] = [klass, role].flatten.uniq 222 | attrs[:id] = id 223 | 224 | if title.nil_or_empty? 225 | html_tag :div, attrs, yield 226 | else 227 | html_tag :figure, attrs do 228 | ary = [yield, html_tag(:figcaption) { captioned_title }] 229 | ary.reverse! if position == :top 230 | ary.compact.join("\n") 231 | end 232 | end 233 | end 234 | 235 | ## 236 | # Delimite the given equation as a STEM of the specified type. 237 | # 238 | # Note: This is not needed nor used for KaTeX, but keep this for the case 239 | # user wants to use a different method. 240 | # 241 | # @param equation [String] the equation to delimite. 242 | # @param type [#to_sym] the type of the STEM renderer (latexmath, or asciimath). 243 | # @return [String] the delimited equation. 244 | # 245 | def delimit_stem(equation, type) 246 | if (@_html5s_stem_type ||= document.attr('html5s-force-stem-type')) 247 | type = @_html5s_stem_type 248 | end 249 | 250 | if is_a? ::Asciidoctor::Block 251 | open, close = ::Asciidoctor::BLOCK_MATH_DELIMITERS[type.to_sym] 252 | else 253 | open, close = ::Asciidoctor::INLINE_MATH_DELIMITERS[type.to_sym] 254 | end 255 | 256 | if !equation.start_with?(open) || !equation.end_with?(close) 257 | equation = [open, equation, close].join 258 | end 259 | equation 260 | end 261 | 262 | ## 263 | # Formats the given hash as CSS declarations for an inline style. 264 | # 265 | # @example 266 | # style_value(text_align: 'right', float: 'left') 267 | # => "text-align: right; float: left;" 268 | # 269 | # style_value(text_align: nil, float: 'left') 270 | # => "float: left;" 271 | # 272 | # style_value(width: [90, '%'], height: '50px') 273 | # => "width: 90%; height: 50px;" 274 | # 275 | # style_value(width: ['120px', 'px']) 276 | # => "width: 90px;" 277 | # 278 | # style_value(width: [nil, 'px']) 279 | # => nil 280 | # 281 | # @param declarations [Hash] 282 | # @return [String, nil] 283 | # 284 | def style_value(declarations) 285 | decls = [] 286 | 287 | declarations.each do |prop, value| 288 | next if value.nil? 289 | 290 | if value.is_a? Array 291 | value, unit = value 292 | next if value.nil? 293 | value = value.to_s + unit unless value.end_with? unit 294 | end 295 | prop = prop.to_s.gsub('_', '-') 296 | decls << "#{prop}: #{value}" 297 | end 298 | 299 | decls.empty? ? nil : decls.join('; ') + ';' 300 | end 301 | 302 | def urlize(*segments) 303 | path = segments * '/' 304 | if path.start_with? '//' 305 | @_html5s_uri_scheme ||= document.attr('asset-uri-scheme', 'https') 306 | path = "#{@_html5s_uri_scheme}:#{path}" unless @_html5s_uri_scheme.empty? 307 | end 308 | normalize_web_path path 309 | end 310 | 311 | 312 | ## 313 | # Gets the value of the specified attribute in this node. 314 | # 315 | # This is just an alias for +attr+ method with disabled _inherit_ to make it 316 | # more clear. 317 | # 318 | # @param name [String, Symbol] the name of the attribute to lookup. 319 | # @param default_val the value to return if the attribute is not found. 320 | # @return value of the attribute or +default_val+ if not found. 321 | # 322 | def local_attr(name, default_val = nil) 323 | attr(name, default_val, false) 324 | end 325 | 326 | ## 327 | # Checks if the attribute is defined on this node, optionally performing 328 | # a comparison of its value if +expect_val+ is not nil. 329 | # 330 | # This is just an alias for +attr?+ method with disabled _inherit_ to make it 331 | # more clear. 332 | # 333 | # @param name [String, Symbol] the name of the attribute to lookup. 334 | # @param default_val the expected value of the attribute. 335 | # @return [Boolean] whether the attribute exists and, if +expect_val+ is 336 | # specified, whether the value of the attribute matches the +expect_val+. 337 | # 338 | def local_attr?(name, expect_val = nil) 339 | attr?(name, expect_val, false) 340 | end 341 | 342 | ## 343 | # @param index [Integer] the footnote's index. 344 | # @return [String] footnote id to be used in a link. 345 | def footnote_id(index = local_attr(:index)) 346 | "_footnote_#{index}" 347 | end 348 | 349 | ## 350 | # @param index (see #footnote_id) 351 | # @return [String] footnoteref id to be used in a link. 352 | def footnoteref_id(index = local_attr(:index)) 353 | "_footnoteref_#{index}" 354 | end 355 | 356 | def nowrap? 357 | 'nowrap' if !document.attr?(:prewrap) || option?('nowrap') 358 | end 359 | 360 | def print_item_content(item) 361 | wrap = item.blocks? && !item.blocks.all? { |b| b.is_a? ::Asciidoctor::List } 362 | [ (html_tag_if(wrap, :p) { item.text } if item.text?), item.content ].join 363 | end 364 | 365 | ## 366 | # Returns corrected section level. 367 | # 368 | # @param sec [Asciidoctor::Section] the section node (default: self). 369 | # @return [Integer] 370 | # 371 | def section_level(sec = self) 372 | (sec.level == 0 && sec.special) ? 1 : sec.level 373 | end 374 | 375 | ## 376 | # Returns the captioned section's title, optionally numbered. 377 | # 378 | # @param sec [Asciidoctor::Section] the section node (default: self). 379 | # @param drop_anchors [Boolean] Remove ++ tags from the title? 380 | # @return [String] 381 | # 382 | def section_title(sec = self, drop_anchors: false) 383 | title = 384 | if sec.caption 385 | sec.captioned_title 386 | elsif sec.numbered && sec.level <= document.attr(:sectnumlevels, DEFAULT_SECTNUMLEVELS).to_i 387 | if sec.level < 2 && document.doctype == 'book' && %w[chapter part].include?(sec.sectname) 388 | signifier = document.attr("#{sec.sectname}-signifier") 389 | sectnum = sec.sectname == 'part' ? sec.sectnum(nil, ':') : sec.sectnum 390 | "#{signifier&.+ ' '}#{sectnum} #{sec.title}" 391 | else 392 | "#{sec.sectnum} #{sec.title}" 393 | end 394 | else 395 | sec.title 396 | end 397 | 398 | if drop_anchors && title.include?('+]+|\/a)>/, '') 400 | else 401 | title 402 | end 403 | end 404 | 405 | ## 406 | # @return [String] language of STEM block or inline node (tex or asciimath). 407 | def stem_lang 408 | value = (inline? ? type : style).to_s 409 | value == 'latexmath' ? 'tex' : value 410 | end 411 | 412 | def link_rel 413 | rel = [ 414 | ('nofollow' if option?('nofollow')), 415 | ('noopener' if option?('noopener') || local_attr(:window) == '_blank') 416 | ].compact 417 | 418 | rel.empty? ? nil : rel.join(' ') 419 | end 420 | 421 | #-------------------------------------------------------- 422 | # block_admonition 423 | # 424 | 425 | ## 426 | # @return [Boolean] should be this admonition wrapped in aside element? 427 | def admonition_aside? 428 | %w[note tip].include? attr(:name) 429 | end 430 | 431 | ## 432 | # @return [String, nil] WAI-ARIA role of this admonition. 433 | def admonition_aria 434 | case attr(:name) 435 | when 'note' 436 | 'note' # https://www.w3.org/TR/wai-aria/roles#note 437 | when 'tip' 438 | 'doc-tip' # https://www.w3.org/TR/dpub-aria-1.0/#doc-tip 439 | when 'caution', 'important', 'warning' 440 | 'doc-notice' # https://www.w3.org/TR/dpub-aria-1.0/#doc-notice 441 | end 442 | end 443 | 444 | #-------------------------------------------------------- 445 | # block_image 446 | # 447 | 448 | ## 449 | # @return [String, nil] an URL for the image's link. 450 | def image_link 451 | @_html5s_image_link ||= 452 | case (link = attr(:link)) 453 | when 'none', 'false' 454 | return 455 | when 'self' 456 | image_uri(attr(:target)) 457 | when nil, '' 458 | image_uri(attr(:target)) if document.attr?('html5s-image-default-link', 'self') 459 | else 460 | link 461 | end 462 | end 463 | 464 | ## 465 | # @return [String, nil] a label/title of the image link. 466 | def image_link_label 467 | if image_uri(attr(:target)) == image_link 468 | document.attr('html5s-image-self-link-label', 'Open the image in full size') 469 | end 470 | end 471 | 472 | #-------------------------------------------------------- 473 | # block_listing 474 | # 475 | 476 | ## 477 | # See {Asciidoctor::SyntaxHighlighter#format}. 478 | # 479 | # @return [String, nil] a rendered HTML. 480 | def formatted_source 481 | hl = document.syntax_highlighter or return nil 482 | 483 | opts = { nowrap: nowrap? } 484 | if hl.highlight? 485 | opts[:css_mode] = document.attr("#{hl.name}-css", :class).to_sym 486 | opts[:style] = document.attr("#{hl.name}-style") 487 | end 488 | 489 | hl.format(self, source_lang, opts) 490 | end 491 | 492 | ## 493 | # Returns the callout list attached to this listing node, or +nil+ if none. 494 | # 495 | # Note: This variable is set by extension 496 | # {Asciidoctor::Html5s::AttachedColistTreeprocessor}. 497 | # 498 | # @return [Asciidoctor::List, nil] 499 | def callout_list 500 | @html5s_colist 501 | end 502 | 503 | def source_lang 504 | local_attr :language, false 505 | end 506 | 507 | # This is needed only for Asciidoctor <2.0.0. 508 | def source_code_class 509 | if document.attr? 'source-highlighter', 'highlightjs' 510 | "language-#{source_lang || 'none'} hljs" 511 | elsif source_lang 512 | "language-#{source_lang}" 513 | end 514 | end 515 | 516 | #-------------------------------------------------------- 517 | # block_open 518 | # 519 | 520 | ## 521 | # Returns +true+ if an abstract block is allowed in this document type, 522 | # otherwise prints warning and returns +false+. 523 | def abstract_allowed? 524 | if result = (parent == document && document.doctype == 'book') 525 | log.warn 'asciidoctor: WARNING: abstract block cannot be used in a document 526 | without a title when doctype is book. Excluding block content.' 527 | end 528 | !result 529 | end 530 | 531 | ## 532 | # Returns +true+ if a partintro block is allowed in this context, otherwise 533 | # prints warning and returns +false+. 534 | def partintro_allowed? 535 | if result = (level != 0 || parent.context != :section || document.doctype != 'book') 536 | log.warn "asciidoctor: ERROR: partintro block can only be used when doctype 537 | is book and must be a child of a book part. Excluding block content." 538 | end 539 | !result 540 | end 541 | 542 | #-------------------------------------------------------- 543 | # block_table 544 | # 545 | 546 | def autowidth?(node = self) 547 | node.option? :autowidth 548 | end 549 | 550 | def stretch? 551 | if !autowidth? || local_attr?('width') 552 | 'stretch' if attr? :tablepcwidth, 100 553 | end 554 | end 555 | 556 | #-------------------------------------------------------- 557 | # block_video 558 | # 559 | 560 | # @return [Boolean] +true+ if the video should be embedded in an iframe. 561 | def video_iframe? 562 | ['vimeo', 'youtube'].include? attr(:poster) 563 | end 564 | 565 | def video_uri 566 | case attr(:poster, '').to_sym 567 | when :vimeo 568 | params = { 569 | autoplay: (1 if option? 'autoplay'), 570 | loop: (1 if option? 'loop'), 571 | muted: (1 if option? 'muted') 572 | } 573 | start_anchor = "#at=#{attr :start}" if attr? :start 574 | "//player.vimeo.com/video/#{attr :target}#{start_anchor}#{url_query params}" 575 | 576 | when :youtube 577 | video_id, list_id = attr(:target).split('/', 2) 578 | params = { 579 | rel: 0, 580 | start: (attr :start), 581 | end: (attr :end), 582 | list: (attr :list, list_id), 583 | autoplay: (1 if option? 'autoplay'), 584 | loop: (1 if option? 'loop'), 585 | muted: (1 if option? 'muted'), 586 | controls: (0 if option? 'nocontrols') 587 | } 588 | "//www.youtube.com/embed/#{video_id}#{url_query params}" 589 | else 590 | anchor = [attr(:start), attr(:end)].join(',').chomp(',') 591 | anchor = '' if anchor == ',' # XXX: https://github.com/opal/opal/issues/1902 592 | anchor = '#t=' + anchor unless anchor.empty? 593 | media_uri "#{attr :target}#{anchor}" 594 | end 595 | end 596 | 597 | # Formats URL query parameters. 598 | def url_query(params) 599 | str = params.map { |k, v| 600 | next if v.nil? || v.to_s.empty? 601 | [k, v] * '=' 602 | }.compact.join('&') 603 | 604 | '?' + str unless str.empty? 605 | end 606 | 607 | #-------------------------------------------------------- 608 | # document 609 | # 610 | 611 | ## 612 | # @return [String, nil] the revision date in ISO 8601, or nil if not 613 | # available or in invalid format. 614 | def revdate_iso 615 | ::Date.parse(revdate).iso8601 if defined? ::Date 616 | rescue ArgumentError 617 | nil 618 | end 619 | 620 | ## 621 | # Returns HTML meta tag if the given +content+ is not +nil+. 622 | # 623 | # @param name [#to_s] the name for the metadata. 624 | # @param content [#to_s, nil] the value of the metadata, or +nil+. 625 | # @return [String, nil] the meta tag, or +nil+ if the +content+ is +nil+. 626 | # 627 | def html_meta_if(name, content) 628 | %() if content 629 | end 630 | 631 | # Returns formatted style/link and script tags for header. 632 | def styles_and_scripts 633 | scripts = [] 634 | styles = [] 635 | tags = [] 636 | 637 | stylesheet = attr :stylesheet 638 | stylesdir = attr :stylesdir, '' 639 | default_style = ::Asciidoctor::DEFAULT_STYLESHEET_KEYS.include? stylesheet 640 | ss = ::Asciidoctor::Stylesheets.instance 641 | 642 | if attr?(:linkcss) 643 | path = default_style ? ::Asciidoctor::DEFAULT_STYLESHEET_NAME : stylesheet 644 | styles << { href: [stylesdir, path] } 645 | elsif default_style 646 | styles << { text: ss.primary_stylesheet_data } 647 | else 648 | styles << { text: read_asset(normalize_system_path(stylesheet, stylesdir), true) } 649 | end 650 | 651 | if attr? :icons, 'font' 652 | if attr? 'iconfont-remote' 653 | styles << { href: attr('iconfont-cdn', FONT_AWESOME_URI) } 654 | else 655 | styles << { href: [stylesdir, "#{attr 'iconfont-name', 'font-awesome'}.css"] } 656 | end 657 | end 658 | 659 | if attr? 'stem' 660 | styles << { href: KATEX_CSS_URI } 661 | scripts << { src: KATEX_JS_URI } 662 | scripts << { text: KATEX_RENDER_CODE } 663 | end 664 | 665 | if !defined?(::Asciidoctor::SyntaxHighlighter) # Asciidoctor <2.0.0 666 | if attr? 'source-highlighter', 'highlightjs' 667 | hjs_base = attr :highlightjsdir, HIGHLIGHTJS_BASE_URI 668 | hjs_theme = attr 'highlightjs-theme', DEFAULT_HIGHLIGHTJS_THEME 669 | 670 | scripts << { src: [hjs_base, 'highlight.min.js'] } 671 | scripts << { text: 'hljs.initHighlightingOnLoad()' } 672 | styles << { href: [hjs_base, "styles/#{hjs_theme}.min.css"] } 673 | end 674 | end 675 | 676 | styles.each do |item| 677 | if item.key?(:text) 678 | tags << html_tag(:style) { item[:text] } 679 | else 680 | tags << html_tag(:link, rel: 'stylesheet', href: urlize(*item[:href])) 681 | end 682 | end 683 | 684 | scripts.each do |item| 685 | if item.key? :text 686 | tags << html_tag(:script, type: item[:type]) { item[:text] } 687 | else 688 | tags << html_tag(:script, type: item[:type], src: urlize(*item[:src])) 689 | end 690 | end 691 | 692 | if defined?(::Asciidoctor::SyntaxHighlighter) && (hl = syntax_highlighter) # Asciidoctor >=2.0.0 693 | # XXX: We don't care about the declared location and put all to head. 694 | [:head, :footer].each do |location| 695 | if hl.docinfo?(location) 696 | tags << hl.docinfo(location, self, cdn_base_url: CDN_BASE_URI, linkcss: attr?(:linkcss)) 697 | end 698 | end 699 | end 700 | 701 | tags.join("\n") 702 | end 703 | 704 | #-------------------------------------------------------- 705 | # inline_anchor 706 | # 707 | 708 | # @return [String] text of the xref anchor. 709 | def xref_text 710 | str = 711 | if text 712 | text 713 | elsif (path = local_attr :path) 714 | path 715 | else 716 | ref = document.catalog[:refs][attr :refid] 717 | if ref.kind_of? Asciidoctor::AbstractNode 718 | ref.xreftext(attr(:xrefstyle, nil, true)) 719 | end 720 | end 721 | (str || "[#{attr :refid}]").tr_s("\n", ' ') 722 | end 723 | 724 | # @return [String, nil] text of the bibref anchor, or +nil+ if not found. 725 | def bibref_text 726 | if ::Asciidoctor::VERSION[0] == '1' 727 | text 728 | else # Asciidoctor >= 2.0.0 729 | "[#{reftext || id}]" 730 | end 731 | end 732 | 733 | #-------------------------------------------------------- 734 | # inline_image 735 | # 736 | 737 | # @return [Array] style classes for a Font Awesome icon. 738 | def icon_fa_classes 739 | [ "fa fa-#{target}", 740 | ("fa-#{attr :size}" if attr? :size), 741 | ("fa-rotate-#{attr :rotate}" if attr? :rotate), 742 | ("fa-flip-#{attr :flip}" if attr? :flip) 743 | ].compact 744 | end 745 | 746 | #-------------------------------------------------------- 747 | # inline_quoted 748 | # 749 | 750 | # @param text [String] the text to wrap in double quotes. 751 | # @return [String] quoted *text*. 752 | def double_quoted(text) 753 | quotes = CURLY_QUOTES[attr(:lang, DEFAULT_LANG, true)] 754 | "#{quotes[2]}#{text}#{quotes[3]}" 755 | end 756 | 757 | # @param text [String] the text to wrap in single quotes. 758 | # @return [String] quoted *text*. 759 | def single_quoted(text) 760 | quotes = CURLY_QUOTES[attr(:lang, DEFAULT_LANG, true)] 761 | "#{quotes[0]}#{text}#{quotes[1]}" 762 | end 763 | end 764 | -------------------------------------------------------------------------------- /data/templates/image.html.slim: -------------------------------------------------------------------------------- 1 | = block_with_caption(:bottom, :class=>'image-block', :style=>style_value(text_align: (attr :align), float: (attr :float))) 2 | - target_url = image_uri(attr :target) 3 | = html_tag_if(image_link, :a, 4 | :class=>['image', ('bare' if image_link == target_url)], 5 | :href=>image_link, 6 | :title=>image_link_label, 7 | 'aria-label'=>image_link_label, 8 | :target=>(attr :window), 9 | :rel=>link_rel) 10 | img src=target_url alt=(attr :alt) width=(attr :width) height=(attr :height) loading=(attr :loading) 11 | -------------------------------------------------------------------------------- /data/templates/inline_anchor.html.slim: -------------------------------------------------------------------------------- 1 | - case type 2 | - when :xref 3 | a href=target class=role =xref_text 4 | - when :ref 5 | a id=id aria-hidden='true' 6 | - when :bibref 7 | a id=id aria-hidden='true' 8 | =bibref_text 9 | - else 10 | a id=id class=role href=target target=(attr :window) rel=link_rel title=(attr :title) =text 11 | -------------------------------------------------------------------------------- /data/templates/inline_break.html.slim: -------------------------------------------------------------------------------- 1 | =text 2 | br 3 | -------------------------------------------------------------------------------- /data/templates/inline_button.html.slim: -------------------------------------------------------------------------------- 1 | kbd.button 2 | samp =text 3 | -------------------------------------------------------------------------------- /data/templates/inline_callout.html.slim: -------------------------------------------------------------------------------- 1 | b.conum data-value=text =text 2 | -------------------------------------------------------------------------------- /data/templates/inline_footnote.html.slim: -------------------------------------------------------------------------------- 1 | - if (index = local_attr :index) 2 | a.footnote-ref [ 3 | id=(footnoteref_id unless type == :xref) 4 | href="##{footnote_id}" 5 | title="View footnote #{index}" 6 | role='doc-noteref' ] 7 | | [#{index}] 8 | - else 9 | a.footnote-ref.broken title="Unresolved footnote reference." [#{text}] 10 | -------------------------------------------------------------------------------- /data/templates/inline_image.html.slim: -------------------------------------------------------------------------------- 1 | = html_tag_if((attr? :link), :a, :class=>'image', :href=>(attr :link), :target=>(attr :window), :rel=>link_rel) 2 | - if type == 'icon' && (document.attr? :icons, 'font') 3 | i class=[*icon_fa_classes, role] title=(attr :title) 4 | - elsif type == 'icon' && !(document.attr? :icons) 5 | b class=['icon', role] title=(attr :title) 6 | | [#{attr :alt}] 7 | - else 8 | img (src=(type == 'icon' ? (icon_uri target) : (image_uri target)) 9 | alt=(attr :alt) width=(attr :width) height=(attr :height) title=(attr :title) loading=(attr :loading) 10 | class=[(type if type != 'image'), role] style=style_value(float: (attr :float))) 11 | -------------------------------------------------------------------------------- /data/templates/inline_indexterm.html.slim: -------------------------------------------------------------------------------- 1 | - if type == :visible 2 | =text 3 | -------------------------------------------------------------------------------- /data/templates/inline_kbd.html.slim: -------------------------------------------------------------------------------- 1 | - if (keys = attr 'keys').size == 1 2 | kbd.key =keys.first 3 | - else 4 | kbd.keyseq 5 | - keys.each_with_index do |key, idx| 6 | ="+" unless idx.zero? 7 | kbd.key =key 8 | -------------------------------------------------------------------------------- /data/templates/inline_menu.html.slim: -------------------------------------------------------------------------------- 1 | - if local_attr :menuitem 2 | - capture 3 | |   4 | span.caret › 5 | | 6 | kbd.menuseq 7 | kbd.menu 8 | samp =(attr :menu) 9 | - yield_capture 10 | - (attr 'submenus').each do |submenu| 11 | kbd.menu 12 | samp =submenu 13 | - yield_capture 14 | kbd.menu 15 | samp =(local_attr :menuitem) 16 | - else 17 | kbd.menu 18 | samp =(attr :menu) 19 | -------------------------------------------------------------------------------- /data/templates/inline_quoted.html.slim: -------------------------------------------------------------------------------- 1 | - case type 2 | - when :emphasis 3 | em id=id class=role =text 4 | - when :strong 5 | strong id=id class=role =text 6 | - when :monospaced 7 | code id=id class=role =text 8 | - when :superscript 9 | sup id=id class=role =text 10 | - when :subscript 11 | sub id=id class=role =text 12 | - when :mark 13 | mark id=id class=role =text 14 | - when :double 15 | = html_tag_if role? || id, :span, :id=>id, :class=>role 16 | =(double_quoted text) 17 | - when :single 18 | = html_tag_if role? || id, :span, :id=>id, :class=>role 19 | =(single_quoted text) 20 | - when :asciimath, :latexmath 21 | span.math id=id data-lang=stem_lang =(delimit_stem text, type) 22 | - else 23 | - case role 24 | - when 'line-through', 'strike' 25 | s id=id =text 26 | - when 'del' 27 | del id=id =text 28 | - when 'ins' 29 | ins id=id =text 30 | - else 31 | = html_tag_if role? || id, :span, :id=>id, :class=>role 32 | =text 33 | -------------------------------------------------------------------------------- /data/templates/listing.html.slim: -------------------------------------------------------------------------------- 1 | = block_with_caption :top, :class=>'listing-block' 2 | - if style == 'source' 3 | - highlighter = document.attr('source-highlighter') 4 | / Asciidoctor >=2.0.0 5 | - if defined?(::Asciidoctor::SyntaxHighlighter) && document.syntax_highlighter 6 | = formatted_source 7 | / Asciidoctor <2.0.0 8 | - elsif highlighter == 'html-pipeline' 9 | pre: code data-lang=source_lang =content 10 | - else 11 | / The 1st and 3rd class element is for Asciidoctor <2.0.0 12 | pre class=[highlighter, 'highlight', ('linenums' if attr? :linenums), nowrap?] 13 | code class=source_code_class data-lang=source_lang =content 14 | - else 15 | pre class=nowrap? =content 16 | / Note: This is a hack to embed callout list into the listing element. 17 | / See asciidoctor/html5s/attached_colist_treeprocessor.rb. 18 | - if callout_list 19 | = converter.convert callout_list, 'colist' 20 | -------------------------------------------------------------------------------- /data/templates/literal.html.slim: -------------------------------------------------------------------------------- 1 | = block_with_title :class=>'literal-block' 2 | pre class=nowrap? =content 3 | -------------------------------------------------------------------------------- /data/templates/olist.html.slim: -------------------------------------------------------------------------------- 1 | = block_with_title :class=>['olist', style] 2 | ol class=style start=(attr :start) type=list_marker_keyword reversed=(option? 'reversed') 3 | - items.each do |item| 4 | li id=item.id class=item.role =(print_item_content item) 5 | -------------------------------------------------------------------------------- /data/templates/open.html.slim: -------------------------------------------------------------------------------- 1 | - if style == 'abstract' 2 | - if abstract_allowed? 3 | = block_with_title :class=>'quote-block abstract' 4 | blockquote =content 5 | - elsif style != 'partintro' || partintro_allowed? 6 | = block_with_title :class=>['open-block', (style if style != 'open')] 7 | .content =content 8 | -------------------------------------------------------------------------------- /data/templates/outline.html.slim: -------------------------------------------------------------------------------- 1 | - unless sections.empty? 2 | / XXX: opts[:toclevels] is workaround for Opal (see asciidoctor-templates-compiler) 3 | - toclevels ||= opts[:toclevels] || (document.attr 'toclevels', DEFAULT_TOCLEVELS).to_i 4 | - slevel = section_level sections.first 5 | ol.toc-list class="level-#{slevel}" 6 | - sections.each do |sec| 7 | li 8 | a href="##{sec.id}" =(section_title sec, drop_anchors: true) 9 | - if (sec.level < toclevels) && (child_toc = converter.convert sec, 'outline') 10 | = child_toc 11 | -------------------------------------------------------------------------------- /data/templates/page_break.html.slim: -------------------------------------------------------------------------------- 1 | div role='doc-pagebreak' style='page-break-after: always;' 2 | -------------------------------------------------------------------------------- /data/templates/paragraph.html.slim: -------------------------------------------------------------------------------- 1 | - if title? 2 | section.paragraph id=id 3 | h6.block-title =title 4 | p class=role =content 5 | - else 6 | p id=id class=role =content 7 | -------------------------------------------------------------------------------- /data/templates/pass.html.slim: -------------------------------------------------------------------------------- 1 | =content 2 | -------------------------------------------------------------------------------- /data/templates/preamble.html.slim: -------------------------------------------------------------------------------- 1 | section#preamble aria-label='Preamble' 2 | =content 3 | - if (document.attr? :toc) && (document.attr? 'toc-placement', 'preamble') 4 | include _toc.html 5 | -------------------------------------------------------------------------------- /data/templates/quote.html.slim: -------------------------------------------------------------------------------- 1 | = block_with_title :class=>'quote-block' 2 | blockquote 3 | = html_tag_if !blocks?, :p 4 | =content 5 | - if attr?(:attribution) || attr?(:citetitle) 6 | include _attribution.html 7 | -------------------------------------------------------------------------------- /data/templates/section.html.slim: -------------------------------------------------------------------------------- 1 | section.doc-section class=["level-#{section_level}", role] 2 | h level=(section_level + 1) id=id 3 | - if id 4 | - if document.attr? :sectanchors 5 | a.anchor href="##{id}" aria-hidden='true' 6 | - if document.attr? :sectlinks 7 | a.link href="##{id}" =section_title 8 | - else 9 | =section_title 10 | - else 11 | =section_title 12 | =content 13 | -------------------------------------------------------------------------------- /data/templates/sidebar.html.slim: -------------------------------------------------------------------------------- 1 | aside.sidebar id=id class=role 2 | - if title? 3 | h6.block-title =title 4 | =content 5 | -------------------------------------------------------------------------------- /data/templates/stem.html.slim: -------------------------------------------------------------------------------- 1 | = block_with_caption :top, :class=>'stem-block' 2 | .math data-lang=stem_lang =(delimit_stem content, style) 3 | -------------------------------------------------------------------------------- /data/templates/table.html.slim: -------------------------------------------------------------------------------- 1 | = block_with_caption :top, :class=>'table-block' 2 | table [ 3 | class=["frame-#{attr :frame, 'all'}", "grid-#{attr :grid, 'all'}", stretch?, ("stripes-#{attr :stripes}" if attr? :stripes)] 4 | style=style_value(width: ("#{attr :tablepcwidth}%" if !autowidth? && !stretch? || (local_attr :width)), 5 | float: (attr :float)) ] 6 | - unless (attr :rowcount).zero? 7 | colgroup 8 | - if autowidth? 9 | - columns.each do 10 | col 11 | - else 12 | - columns.each do |col| 13 | col style=style_value(width: ("#{col.attr :colpcwidth}%" if !autowidth? col)) 14 | - [:head, :foot, :body].reject { |tblsec| rows[tblsec].empty? }.each do |tblsec| 15 | 16 | - rows[tblsec].each do |row| 17 | tr 18 | - row.each do |cell| 19 | = html_tag(tblsec == :head || cell.style == :header ? 'th' : 'td', 20 | :class=>["halign-#{cell.attr :halign}", "valign-#{cell.attr :valign}"], 21 | :colspan=>cell.colspan, 22 | :rowspan=>cell.rowspan, 23 | :style=>style_value(background_color: (document.attr :cellbgcolor))) 24 | - if tblsec == :head 25 | =cell.text 26 | - else 27 | - case cell.style 28 | - when :asciidoc 29 | =cell.content 30 | - when :literal 31 | .literal: pre =cell.text 32 | - else 33 | - if (content = cell.content).one? 34 | =content.first 35 | - else 36 | - content.each do |text| 37 | p =text 38 | 39 | -------------------------------------------------------------------------------- /data/templates/thematic_break.html.slim: -------------------------------------------------------------------------------- 1 | hr 2 | -------------------------------------------------------------------------------- /data/templates/toc.html.slim: -------------------------------------------------------------------------------- 1 | / This template is used only for toc::[] macro; for document and preamble TOC 2 | / see document.html, preamble.html and _toc.html. 3 | - if document.attr?(:toc) && document.sections? 4 | - toc_id = id || ('toc' if document.embedded? || !document.attr?('toc-placement')) 5 | nav id=toc_id class=(attr :role, (document.attr 'toc-class', 'toc')) role='doc-toc' 6 | h level=(level + 2) id=("#{toc_id}-title" if toc_id) 7 | =(title || (document.attr 'toc-title')) 8 | / Renders outline.html. 9 | = converter.convert document, 'outline', :toclevels=>((attr :levels).to_i if attr? :levels) 10 | - else 11 | /! toc disabled 12 | -------------------------------------------------------------------------------- /data/templates/ulist.html.slim: -------------------------------------------------------------------------------- 1 | - checklist = 'task-list' if option? 'checklist' 2 | = block_with_title :class=>['ulist', style] 3 | ul class=(checklist || style) 4 | - items.each do |item| 5 | - if checklist && (item.attr? :checkbox) 6 | li.task-list-item id=item.id class=item.role 7 | input.task-list-item-checkbox type='checkbox' disabled=true checked=(item.attr? :checked) 8 | ='verse-block' 2 | - if attr?(:attribution) || attr?(:citetitle) 3 | blockquote.verse 4 | pre.verse =content 5 | include _attribution.html 6 | - else 7 | pre.verse =content 8 | -------------------------------------------------------------------------------- /data/templates/video.html.slim: -------------------------------------------------------------------------------- 1 | = block_with_caption :bottom, :class=>'video-block' 2 | - if video_iframe? 3 | iframe [ 4 | src=video_uri 5 | width=(attr :width) 6 | height=(attr :height) 7 | frameborder=0 8 | allowfullscreen=!(option? 'nofullscreen') ] 9 | - else 10 | video [ 11 | src=video_uri 12 | width=(attr :width) 13 | height=(attr :height) 14 | poster=(media_uri(attr :poster) if attr? :poster) 15 | autoplay=(option? 'autoplay') 16 | muted=(option? 'muted') 17 | controls=!(option? 'nocontrols') 18 | loop=(option? 'loop') ] 19 | | Your browser does not support the video tag. 20 | -------------------------------------------------------------------------------- /lib/asciidoctor-html5s.rb: -------------------------------------------------------------------------------- 1 | require 'asciidoctor/html5s' 2 | -------------------------------------------------------------------------------- /lib/asciidoctor/html5s.rb: -------------------------------------------------------------------------------- 1 | require 'asciidoctor/html5s/version' 2 | require 'asciidoctor/html5s/converter' 3 | require 'asciidoctor/html5s/replacements' 4 | require 'asciidoctor/html5s/attached_colist_treeprocessor' 5 | 6 | if defined? Asciidoctor::SyntaxHighlighter 7 | require 'asciidoctor/html5s/html_pipeline_highlighter' 8 | end 9 | 10 | unless RUBY_PLATFORM == 'opal' 11 | require 'asciidoctor/extensions' 12 | 13 | Asciidoctor::Extensions.register do 14 | treeprocessor Asciidoctor::Html5s::AttachedColistTreeprocessor 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/asciidoctor/html5s/attached_colist_treeprocessor.rb: -------------------------------------------------------------------------------- 1 | require 'asciidoctor/html5s/version' 2 | require 'asciidoctor/extensions' unless RUBY_PLATFORM == 'opal' 3 | 4 | module Asciidoctor::Html5s 5 | 6 | # This extension moves every callout list immediately following listing block 7 | # to instance variable +@html5s_colist+ inside the listing block. 8 | # The aim is to render callout list as part of the corresponding listing. 9 | class AttachedColistTreeprocessor < ::Asciidoctor::Extensions::Treeprocessor 10 | 11 | def process(document) 12 | return if document.backend != 'html5s' 13 | 14 | document.find_by(context: :colist) do |colist| 15 | blocks = colist.parent.blocks 16 | colist_idx = blocks.find_index(colist) 17 | prev_block = blocks[colist_idx - 1] if colist_idx 18 | 19 | if prev_block && prev_block.node_name == 'listing' 20 | prev_block.instance_variable_set(:@html5s_colist, colist) 21 | # XXX: This mutates node's blocks list! 22 | # :empty is our special block type that just outputs nothing. 23 | blocks[colist_idx] = create_block(colist.parent, :empty, '', {}) 24 | end 25 | end 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /lib/asciidoctor/html5s/html_pipeline_highlighter.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Asciidoctor::Html5s 4 | 5 | # Modification of Asciidoctor::SyntaxHighlighter::HtmlPipelineAdapter that 6 | # uses attribute `data-lang` instead of `lang`. 7 | # 8 | # Rationale: Attribute `lang` is defined for natural language of text, not 9 | # for programming languages. 10 | class HtmlPipelineHighlighter < ::Asciidoctor::SyntaxHighlighter::Base 11 | register_for 'html-pipeline' 12 | 13 | def initialize(name, backend, opts = {}) 14 | super 15 | # Use this version of the #format method only for our backend, otherwise 16 | # use the original variant. 17 | singleton_class.send(:alias_method, :format, :format_orig) if backend != 'html5s' 18 | end 19 | 20 | def format(node, lang, _opts) 21 | %(
#{node.content}
) 22 | end 23 | 24 | # Copied from Asciidoctor::SyntaxHighlighter::HtmlPipelineAdapter#format. 25 | # Note: HtmlPipelineAdapter is not available in asciidoctor.js, that's why 26 | # it's done like this instead of delegation or inheritance. 27 | def format_orig(node, lang, _opts) 28 | %(#{node.content}) 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /lib/asciidoctor/html5s/replacements.rb: -------------------------------------------------------------------------------- 1 | require 'asciidoctor' unless RUBY_PLATFORM == 'opal' 2 | 3 | module Asciidoctor 4 | # XXX: Modifies constant defined in Asciidoctor. 5 | REPLACEMENTS.unshift( 6 | # foo --- bar ->  —  7 | [/(^|\n| )---( |\n|$)/, ' — ', :none], 8 | # foo---bar -> —{ZERO WIDTH SPACE} 9 | [/(#{CG_WORD})---(?=#{CG_WORD})/, '—​', :leading], 10 | 11 | # foo -- bar -> &thinksp;–  12 | # Note: The regexp is copied from Asciidoctor. 13 | [/(^|\n|\\| )--( |\n|$)/, ' – ', :none], 14 | # foo--bar -> – 15 | # Note: The regexp is copied from Asciidoctor. 16 | [/(#{CG_WORD})\\?--(?=#{CG_WORD})/, '–', :leading], 17 | ) 18 | end 19 | -------------------------------------------------------------------------------- /lib/asciidoctor/html5s/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Asciidoctor 4 | module Html5s 5 | VERSION = '0.5.1' 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "asciidoctor-html5s", 3 | "version": "0.5.1", 4 | "description": "Semantic HTML5 backend (converter) for Asciidoctor", 5 | "author": "Jakub Jirutka ", 6 | "license": "MIT", 7 | "homepage": "https://github.com/jirutka/asciidoctor-html5s", 8 | "bugs": { 9 | "url": "https://github.com/jirutka/asciidoctor-html5s/issues" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/jirutka/asciidoctor-html5s.git" 14 | }, 15 | "keywords": [ 16 | "asciidoc", 17 | "asciidoctor", 18 | "template", 19 | "backend", 20 | "html5", 21 | "opal" 22 | ], 23 | "main": "dist/asciidoctor-html5s.js", 24 | "files": [ 25 | "dist/asciidoctor-html5s.js", 26 | "LICENSE", 27 | "README.md" 28 | ], 29 | "scripts": { 30 | "prepublishOnly": "bundle install && bundle exec rake build:js && bundle exec rake readme2md" 31 | }, 32 | "devDependencies": { 33 | "@asciidoctor/core": ">=3.0.0 <4.0.0" 34 | }, 35 | "peerDependencies": { 36 | "@asciidoctor/core": ">=3.0.0 <4.0.0" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/asciidoctor-html5s.tmpl.js: -------------------------------------------------------------------------------- 1 | (function (Opal) { 2 | function initialize (Opal) { 3 | //OPAL-GENERATED-CODE// 4 | } 5 | 6 | var mainModule 7 | 8 | function resolveModule (name) { 9 | if (!mainModule) { 10 | checkAsciidoctor() 11 | initialize(Opal) 12 | mainModule = Opal.const_get_qualified(Opal.Asciidoctor, 'Html5s') 13 | } 14 | if (!name) { 15 | return mainModule 16 | } 17 | return Opal.const_get_qualified(mainModule, name) 18 | } 19 | 20 | function checkAsciidoctor () { 21 | if (typeof Opal.Asciidoctor === 'undefined') { 22 | throw new TypeError('Asciidoctor.js is not loaded') 23 | } 24 | } 25 | 26 | /** 27 | * @return A new instance of `Asciidoctor::Html5s::AttachedColistTreeprocessor`. 28 | */ 29 | function AttachedColistTreeprocessor () { 30 | var processor = resolveModule('AttachedColistTreeprocessor').$new() 31 | processor.process = processor.$process 32 | 33 | return processor 34 | } 35 | 36 | /** 37 | * @param {string} backend The backend name. 38 | * @param {Object} opts The converter options. 39 | * @return A new instance of `Asciidoctor::Html5s::Converter`. 40 | */ 41 | function Converter (backend, opts) { 42 | var converter = resolveModule('Converter').$new(backend, Opal.hash(opts || {})) 43 | 44 | converter.convert = function (node, transform, opts) { 45 | return this.$convert(node, transform, Opal.hash(opts || {})) 46 | } 47 | return converter 48 | } 49 | 50 | /** 51 | * @return {string} Version of this extension. 52 | */ 53 | function getVersion () { 54 | return resolveModule().$$const.VERSION.toString() 55 | } 56 | 57 | /** 58 | * Registers the HTML5s converter and the supporting extension into Asciidoctor. 59 | * 60 | * @param registry The Asciidoctor extensions registry to register the 61 | * extension into. Defaults to the global Asciidoctor registry. 62 | * @throws {TypeError} if the *registry* is invalid or Asciidoctor.js is not loaded. 63 | */ 64 | function register (registry) { 65 | if (!registry) { 66 | checkAsciidoctor() 67 | registry = Opal.Asciidoctor.Extensions 68 | } 69 | var processor = AttachedColistTreeprocessor() 70 | 71 | // global registry 72 | if (typeof registry.register === 'function') { 73 | registry.register(function () { 74 | this.treeProcessor(processor) 75 | }) 76 | // custom registry 77 | } else if (typeof registry.block === 'function') { 78 | registry.treeProcessor(processor) 79 | } else { 80 | throw new TypeError('Invalid registry object') 81 | } 82 | } 83 | 84 | var facade = { 85 | AttachedColistTreeprocessor: AttachedColistTreeprocessor, 86 | Converter: Converter, 87 | getVersion: getVersion, 88 | register: register, 89 | } 90 | 91 | if (typeof module !== 'undefined' && module.exports) { 92 | module.exports = facade 93 | } 94 | return facade 95 | })(Opal); 96 | -------------------------------------------------------------------------------- /test/examples/asciidoc-html/README: -------------------------------------------------------------------------------- 1 | This directory contains additional testing examples for HTML-based backends. 2 | -------------------------------------------------------------------------------- /test/examples/asciidoc-html/example.adoc: -------------------------------------------------------------------------------- 1 | // .collapsible 2 | .Toggle *Me* 3 | [%collapsible] 4 | ==== 5 | This content is revealed when the user clicks the words "Toggle Me". 6 | ==== 7 | 8 | // .collapsible-open 9 | .Toggle Me 10 | [%collapsible%open] 11 | ==== 12 | This content is revealed when the user clicks the words "Toggle Me". 13 | ==== 14 | 15 | // .collapsible-with-id-and-role 16 | .Toggle Me 17 | [#lorem.ipsum%collapsible] 18 | ==== 19 | This content is revealed when the user clicks the words "Toggle Me". 20 | ==== 21 | 22 | // .collapsible-without-title 23 | [%collapsible] 24 | ==== 25 | This content is revealed when the user clicks the words "Details". 26 | ==== 27 | -------------------------------------------------------------------------------- /test/examples/asciidoc-html/image.adoc: -------------------------------------------------------------------------------- 1 | // .with-link-and-window-blank 2 | image::sunset.jpg[link="http://www.flickr.com/photos/javh/5448336655", window=_blank] 3 | 4 | // .with-link-and-noopener 5 | image::sunset.jpg[link="http://www.flickr.com/photos/javh/5448336655", opts=noopener] 6 | 7 | // .with-link-and-nofollow 8 | image::sunset.jpg[link="http://www.flickr.com/photos/javh/5448336655", opts=nofollow] 9 | 10 | // .with-link-self 11 | image::sunset.jpg[link=self] 12 | 13 | // .with-link-none 14 | image::sunset.jpg[link=none] 15 | 16 | // .with-loading-lazy 17 | image::sunset.jpg[loading=lazy] 18 | 19 | // .html5s-image-default-link-self 20 | :html5s-image-default-link: self 21 | image::sunset.jpg[] 22 | 23 | // .html5s-image-default-link-self-with-link-none 24 | :html5s-image-default-link: self 25 | image::sunset.jpg[link=none] 26 | 27 | // .html5s-image-default-link-self-with-link-url 28 | :html5s-image-default-link: self 29 | image::sunset.jpg[link="http://www.flickr.com/photos/javh/5448336655"] 30 | -------------------------------------------------------------------------------- /test/examples/asciidoc-html/inline_image.adoc: -------------------------------------------------------------------------------- 1 | // .image-with-link-and-window-blank 2 | image:linux.svg[link="http://inkscape.org/doc/examples/tux.svg", window=_blank] 3 | 4 | // .image-with-link-and-noopener 5 | image:linux.svg[link="http://inkscape.org/doc/examples/tux.svg", opts=noopener] 6 | 7 | // .with-link-and-nofollow 8 | image:linux.svg[link="http://inkscape.org/doc/examples/tux.svg", opts=nofollow] 9 | 10 | // .image-with-loading-lazy 11 | image:sunset.jpg[loading=lazy] 12 | 13 | // .icon-font 14 | :icons: font 15 | icon:heart[] 16 | 17 | // .icon-font-with-title 18 | :icons: font 19 | icon:heart[title="I <3 Asciidoctor"] 20 | 21 | // .icon-font-with-size 22 | :icons: font 23 | icon:shield[2x] 24 | 25 | // .icon-font-with-rotate 26 | :icons: font 27 | icon:shield[rotate=90] 28 | 29 | // .icon-font-with-flip 30 | :icons: font 31 | icon:shield[flip=vertical] 32 | -------------------------------------------------------------------------------- /test/examples/asciidoc-html/inline_quoted.adoc: -------------------------------------------------------------------------------- 1 | // .role-line-through 2 | [line-through]#striked text# 3 | 4 | // .role-strike 5 | [strike]#striked text# 6 | 7 | // .role-del 8 | [del]#deleted text# 9 | 10 | // .role-ins 11 | [ins]#inserted text# 12 | 13 | // .double-lang-cs 14 | :lang: cs 15 | "`chunky bacon`" 16 | 17 | // .double-lang-fi 18 | :lang: fi 19 | "`chunky bacon`" 20 | 21 | // .double-lang-nl 22 | :lang: nl 23 | "`chunky bacon`" 24 | 25 | // .double-lang-pl 26 | :lang: pl 27 | "`chunky bacon`" 28 | 29 | // .single-lang-cs 30 | :lang: cs 31 | '`chunky bacon`' 32 | 33 | // .single-lang-fi 34 | :lang: fi 35 | '`chunky bacon`' 36 | 37 | // .single-lang-nl 38 | :lang: nl 39 | '`chunky bacon`' 40 | 41 | // .single-lang-pl 42 | :lang: pl 43 | '`chunky bacon`' 44 | -------------------------------------------------------------------------------- /test/examples/asciidoc-html/listing.adoc: -------------------------------------------------------------------------------- 1 | // .source-highlighter-highlightjs 2 | :source-highlighter: highlightjs 3 | 4 | [source, ruby] 5 | ---- 6 | 5.times do 7 | print "Odelay!" 8 | end 9 | ---- 10 | 11 | // .source-highlighter-html-pipeline 12 | // nowrap should be ignored 13 | :source-highlighter: html-pipeline 14 | 15 | [source, ruby, options="nowrap"] 16 | ---- 17 | 5.times do 18 | print "Odelay!" 19 | end 20 | ---- 21 | -------------------------------------------------------------------------------- /test/examples/asciidoc-html/outline.adoc: -------------------------------------------------------------------------------- 1 | // .sections-with-ids 2 | = Document Title 3 | :toc: 4 | 5 | == [[un]]Section _One_ 6 | 7 | content one 8 | 9 | == [[two]][[deux]]Section Two 10 | 11 | content two 12 | 13 | == https://www.cvut.cz[*CTU* in Prague] 14 | 15 | content three 16 | -------------------------------------------------------------------------------- /test/examples/asciidoc-html/regressions.adoc: -------------------------------------------------------------------------------- 1 | // .issue-10-two-sources-with-collist 2 | [source] 3 | ---- 4 | source 1 line 1 // <1> 5 | source 1 line 2 // <2> 6 | ---- 7 | <1> source 1 callout 1 8 | <2> source 1 callout 2 9 | 10 | Some text in here. 11 | 12 | [source] 13 | ---- 14 | source 2 line 1 // <1> 15 | source 2 line 2 // <2> 16 | ---- 17 | <1> source 2 callout 1 18 | <2> source 2 callout 2 19 | 20 | Where is this? 21 | 22 | == Heading 23 | 24 | This is actually here. 25 | 26 | // .issue-14-duplicated-footnotes-in-table 27 | |=== 28 | 29 | |cell footnote:intable[first] 30 | 31 | |cell footnote:intable[] 32 | |=== 33 | 34 | paragraph footnote:notintable[second] 35 | 36 | another paragraph footnote:notintable[] 37 | -------------------------------------------------------------------------------- /test/examples/asciidoc-html/replacements.adoc: -------------------------------------------------------------------------------- 1 | // .en-dash 2 | chunky -- bacon 3 | 4 | // .en-dash-escaped 5 | chunky \-- bacon 6 | 7 | // .en-dash-at-bol 8 | -- bacon 9 | 10 | // .en-dash-at-eol 11 | chunky -- 12 | 13 | // .en-dash-no-spaces 14 | 1955--2011 15 | 16 | // .en-dash-no-spaces-escaped 17 | 1955\--2011 18 | 19 | // .em-dash 20 | chunky --- bacon 21 | 22 | // .em-dash-at-bol 23 | --- bacon 24 | 25 | // .em-dash-at-eol 26 | chunky --- 27 | 28 | // .em-dash-no-spaces 29 | 1955---2011 30 | -------------------------------------------------------------------------------- /test/examples/asciidoc-html/video.adoc: -------------------------------------------------------------------------------- 1 | // .youtube 2 | video::rPQoq7ThGAU[youtube] 3 | 4 | // .youtube-iframe-params 5 | video::rPQoq7ThGAU[youtube, width=640, height=480, options="nofullscreen"] 6 | 7 | // .youtube-url-params 8 | video::rPQoq7ThGAU[youtube, start=60, end=140, options="autoplay, loop, muted, nocontrol"] 9 | 10 | // .vimeo 11 | video::32255377[vimeo] 12 | 13 | // .vimeo-iframe-params 14 | video::32255377[vimeo, width=640, height=480, options="nofullscreen"] 15 | 16 | // .vimeo-url-params 17 | video::32255377[vimeo, start=60, options="autoplay, loop, muted"] 18 | -------------------------------------------------------------------------------- /test/examples/html5/admonition.html: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 16 | 17 | 18 | 24 | 25 | 26 | 37 | 38 | 39 | 45 | 46 | 47 | 53 | 54 | 55 | 61 | 62 | 63 | 74 | 75 | 76 |
77 |
78 | Important: 79 |
80 |

This is an important notice.

81 |
82 | 83 | 84 |
85 |
86 | Important: Title of important notice 87 |
88 |

This is an important notice with title.

89 |
90 | 91 | 92 |
93 |
94 | Important: 95 |
96 |

This is an important notice with id and role.

97 |
98 | 99 | 100 |
101 |
102 | Important: 103 |
104 |

This is an important notice with complex content.

105 |
106 |
    107 |
  • It contains a list.
  • 108 |
109 |
110 |
111 | 112 | 113 |
114 |
115 | Caution: 116 |
117 |

This is a caution.

118 |
119 | 120 | 121 |
122 |
123 | Caution: Title of caution 124 |
125 |

This is a caution with title.

126 |
127 | 128 | 129 |
130 |
131 | Caution: 132 |
133 |

This is a caution with id and role.

134 |
135 | 136 | 137 |
138 |
139 | Caution: 140 |
141 |

This is a caution with complex content.

142 |
143 |
    144 |
  • It contains a list.
  • 145 |
146 |
147 |
148 | 149 | 150 |
151 |
152 | Warning: 153 |
154 |

This is a warning.

155 |
156 | 157 | 158 |
159 |
160 | Warning: Title of warning 161 |
162 |

This is a warning with title.

163 |
164 | 165 | 166 |
167 |
168 | Warning: 169 |
170 |

This is a warning with id and role.

171 |
172 | 173 | 174 |
175 |
176 | Warning: 177 |
178 |

This is a warning with complex content.

179 |
180 |
    181 |
  • It contains a list.
  • 182 |
183 |
184 |
185 | -------------------------------------------------------------------------------- /test/examples/html5/audio.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 |
5 | 6 | 7 |
8 | 9 |
10 | 11 | 12 |
13 | 14 |
Waves!
15 |
16 | 17 | 18 |
19 | 20 |
21 | -------------------------------------------------------------------------------- /test/examples/html5/colist.html: -------------------------------------------------------------------------------- 1 | 4 |
    5 |
  1. Library import
  2. 6 |
  3. URL mapping
  4. 7 |
  5. Content for response
  6. 8 |
9 | 10 | 14 |
    15 |
  1. Library import
  2. 16 |
  3. URL mapping
  4. 17 |
  5. Content for response
  6. 18 |
19 | 20 | 23 |
    24 |
  1. Library import
  2. 25 |
  3. URL mapping
  4. 26 |
  5. Content for response
  6. 27 |
28 | -------------------------------------------------------------------------------- /test/examples/html5/dlist.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
Asciidoctor
5 |
An implementation of the AsciiDoc processor in Ruby.
6 |
Asciidoc
7 |
A text document format for writing notes, documentation, articles, books, 8 | ebooks, slideshows, web pages, man pages and blogs.
9 |
10 |
11 | 12 | 13 |
14 |
15 |
About
16 |
17 |
    18 |
  • An implementation of the AsciiDoc processor in Ruby.
  • 19 |
  • Fast text processor and publishing toolchain.
  • 20 |
21 |
22 |
Authors
23 |
24 |

Asciidoctor is lead by Dan Allen and Sarah White and has received contributions 25 | from many other individuals in Asciidoctor’s awesome community.

26 |

AsciiDoc was started by Stuart Rackham.

27 |
28 |
29 |
30 | 31 | 32 |
33 |
34 |
Definition without a description
35 |
36 |
37 | 38 | 39 |
40 |
Asciidoctor
41 |
42 |
License
43 |
MIT
44 |
45 |
46 | 47 | 48 |
49 |
50 |
License
51 |
MIT
52 |
53 |
54 | 55 | 56 |
57 |
58 |
What is Asciidoctor?
59 |
An implementation of the AsciiDoc processor in Ruby.
60 |
What is the answer to the Ultimate Question?
61 |
42
62 |
63 |
64 | 65 | 66 |
67 |
68 |
What is Asciidoctor?
69 |
70 |
    71 |
  • An implementation of the AsciiDoc processor in Ruby.
  • 72 |
  • Fast text processor and publishing toolchain.
  • 73 |
74 |
75 |
Who is behind Asciidoctor?
76 |
77 |

Asciidoctor is lead by Dan Allen and Sarah White and has received contributions from many other individuals in Asciidoctor’s awesome community.

78 |

AsciiDoc was started by Stuart Rackham.

79 |
80 |
81 |
82 | 83 | 84 |
85 |
86 |
Who knows the answer?
87 |
88 |
89 | 90 | 91 |
92 |
The most important questions
93 |
94 |
What is the answer to the Ultimate Question?
95 |
42
96 |
97 |
98 | 99 | 100 |
101 |
102 |
What is the answer to the Ultimate Question?
103 |
42
104 |
105 |
106 | 107 | 108 |
109 |
110 |
Hard drive
111 |
Permanent storage for operating system and/or user files.
112 |
RAM
113 |
Temporarily stores information the CPU uses during operation.
114 |
115 |
116 | 117 | 118 |
119 |
120 |
Hard drive
121 |
Permanent storage for operating system and/or user files.
122 |
RAM
123 |
Temporarily stores information the CPU uses during operation.
124 |
125 |
126 | 127 | 128 |
129 |
Computer terminology for noobs
130 |
131 |
Hard drive
132 |
Permanent storage for operating system and/or user files.
133 |
RAM
134 |
Temporarily stores information the CPU uses during operation.
135 |
136 |
137 | 138 | 139 |
140 |
141 |
Hard drive
142 |
Permanent storage for operating system and/or user files.
143 |
RAM
144 |
Temporarily stores information the CPU uses during operation.
145 |
146 |
147 | 148 | 149 |
150 |
151 |
Operating Systems
152 |
153 |
154 |
Linux
155 |
156 |
    157 |
  1. Fedora 158 |
      159 |
    • Desktop
    • 160 |
    161 |
  2. 162 |
  3. Ubuntu 163 |
      164 |
    • Desktop
    • 165 |
    • Server
    • 166 |
    167 |
  4. 168 |
169 |
170 |
BSD
171 |
172 |
    173 |
  1. FreeBSD
  2. 174 |
  3. NetBSD
  4. 175 |
176 |
177 |
178 |
179 |
Cloud Providers
180 |
181 |
182 |
PaaS
183 |
184 |
    185 |
  1. OpenShift
  2. 186 |
  3. CloudBees
  4. 187 |
188 |
189 |
IaaS
190 |
191 |
    192 |
  1. Amazon EC2
  2. 193 |
  3. Rackspace
  4. 194 |
195 |
196 |
197 |
198 |
199 |
200 | -------------------------------------------------------------------------------- /test/examples/html5/document.html: -------------------------------------------------------------------------------- 1 | 4 |
5 |

The Dangerous and Thrilling Documentation Chronicles

6 |
7 | 8 | 11 |
12 |

The Dangerous and Thrilling Documentation Chronicles

13 |
19 |
20 | 21 | 24 |
25 |

The Dangerous and Thrilling Documentation Chronicles

26 |
27 | Kismet Rainbow Chameleon 28 |
29 |
30 |
31 | 32 | 35 |
36 |

The Dangerous and Thrilling Documentation Chronicles

37 |
38 | Kismet Rainbow Chameleon 39 |
40 | 41 |
42 | Lazarus het Draeke 43 |
44 | 45 |
46 |
47 | 48 | 51 |
52 |

Document Title

53 |
54 | Kismet Chameleon 55 |
56 | version 1.0 57 |
58 |
59 | 60 | 63 |
64 |

Document Title

65 |
66 | Kismet Chameleon 67 |
68 | version 1.0, 69 |
70 |
71 | 72 | 75 |
76 |

Document Title

77 |
78 | Kismet Chameleon 79 |
80 | version 1.0, 81 |
82 | First incarnation 83 |
84 |
85 | 86 | 89 |
90 |
91 |
    92 |
  1. 93 | The double hail-and-rainbow level makes my toes tingle. 94 | 95 |
  2. 96 |
  3. 97 | Opinions are my own. 98 | 99 |
  4. 100 |
101 |
102 | 103 | 106 |
107 |

Document Title

108 | 114 |
115 | 116 | 119 |
120 |

Document Title

121 | 127 |
128 | -------------------------------------------------------------------------------- /test/examples/html5/embedded.html: -------------------------------------------------------------------------------- 1 | 2 |

The Dangerous and Thrilling Documentation Chronicles

3 | 4 | 7 |
8 |
9 |
    10 |
  1. 11 | The double hail-and-rainbow level makes my toes tingle. 12 | 13 |
  2. 14 |
  3. 15 | Opinions are my own. 16 | 17 |
  4. 18 |
19 |
20 | 21 | 24 | 30 | 31 | 34 | 40 | -------------------------------------------------------------------------------- /test/examples/html5/example.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor 5 | incididunt ut labore et dolore magna aliqua.

6 |
7 |
8 | 9 | 10 |
11 |
Example 1. Sample document
12 |
13 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor 14 | incididunt ut labore et dolore magna aliqua.

15 |

The document header is useful, but not required.

16 |
17 |
18 | 19 | 20 |
21 |
22 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor 23 | incididunt ut labore et dolore magna aliqua.

24 |
25 |
26 | 27 | 28 |
29 | Toggle Me 30 |
31 |

This content is revealed when the user clicks the words "Toggle Me".

32 |
33 |
34 | 35 | 36 |
37 | Toggle Me 38 |
39 |

This content is revealed when the user clicks the words "Toggle Me".

40 |
41 |
42 | 43 | 44 |
45 | Toggle Me 46 |
47 |

This content is revealed when the user clicks the words "Toggle Me".

48 |
49 |
50 | 51 | 52 |
53 |
54 |

This content is revealed when the user clicks the words "Details".

55 |
56 |
57 | -------------------------------------------------------------------------------- /test/examples/html5/floating_title.html: -------------------------------------------------------------------------------- 1 | 2 |

Discrete Title Level 1

3 | 4 | 5 |

Discrete Title Level 2

6 | 7 | 8 |

Discrete Title Level 3

9 | 10 | 11 |
Discrete Title Level 4
12 | 13 | 14 |
Discrete Title Level 5
15 | 16 | 17 |

Discrete Title Level 1

18 | 19 | 20 |

Discrete Title Level 2

21 | -------------------------------------------------------------------------------- /test/examples/html5/image.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | sunset 4 |
5 | 6 | 7 |
8 | Shining sun 9 |
10 | 11 | 12 |
13 | sunset 14 |
15 | 16 | 17 |
18 | sunset 19 |
20 | 21 | 22 |
23 | Shining sun 24 |
25 | 26 | 27 |
28 | 29 | sunset 30 | 31 |
32 | 33 | 34 |
35 | sunset 36 |
Figure 1. A mountain sunset
37 |
38 | 39 | 40 |
41 | sunset 42 |
43 | 44 | 45 |
46 | sunset 47 |
48 | 49 | 50 |
51 | 52 | sunset 53 | 54 |
55 | 56 | 57 |
58 | 59 | sunset 60 | 61 |
62 | 63 | 64 |
65 | 66 | sunset 67 | 68 |
69 | 70 | 71 |
72 | 73 | sunset 74 | 75 |
76 | 77 | 78 |
79 | sunset 80 |
81 | 82 | 83 |
84 | sunset 85 |
86 | 87 | 88 |
89 | 90 | sunset 91 | 92 |
93 | 94 | 95 |
96 | sunset 97 |
98 | 99 | 100 |
101 | 102 | sunset 103 | 104 |
105 | -------------------------------------------------------------------------------- /test/examples/html5/inline_anchor.html: -------------------------------------------------------------------------------- 1 | 2 | Inline anchors make arbitrary content referenceable. 3 | 4 | 5 | The section [page-break] describes how to add a page break. 6 | 7 | 8 | The section manual.html describes how to add a page break. 9 | 10 | 11 | The section Page break describes how to add a page break. 12 | 13 | 14 | Refer to Section A. 15 | 16 | 17 | Refer to Installation Procedure. 18 | 19 | 20 | Refer to Sec. 1. 21 | 22 | 25 | [prag] Andy Hunt & Dave Thomas. The Pragmatic Programmer 26 | 27 | 30 | [1] Andy Hunt & Dave Thomas. The Pragmatic Programmer 31 | 32 | 33 | http://www.asciidoctor.org 34 | 35 | 36 | Asciidoctor IRC channel 37 | 38 | 39 | Asciidoctor homepage 40 | 41 | 42 | mailing list 43 | -------------------------------------------------------------------------------- /test/examples/html5/inline_break.html: -------------------------------------------------------------------------------- 1 | 2 | Rubies are red,
3 | Topazes are blue. 4 | 5 | 6 | Ruby is red.
7 | Java is black. 8 | -------------------------------------------------------------------------------- /test/examples/html5/inline_button.html: -------------------------------------------------------------------------------- 1 | 2 | OK 3 | -------------------------------------------------------------------------------- /test/examples/html5/inline_callout.html: -------------------------------------------------------------------------------- 1 | 4 | "Hello world!" 1 5 | -------------------------------------------------------------------------------- /test/examples/html5/inline_footnote.html: -------------------------------------------------------------------------------- 1 | 4 | Apocalyptic party.[1] 5 | 6 | 9 | A bold statement.[1] 10 | Another outrageous statement.[1] 11 | 12 | 13 | A bold statement.[foobar] 14 | -------------------------------------------------------------------------------- /test/examples/html5/inline_image.html: -------------------------------------------------------------------------------- 1 | 2 | linux 3 | 4 | 5 | Tux 6 | 7 | 8 | Tux 9 | 10 | 11 | linux 12 | 13 | 14 | linux 15 | 16 | 17 | linux 18 | 19 | 20 | sunset 21 | 22 | 23 | tags 24 | 25 | 26 | tags 27 | 28 | 29 | heart 30 | 31 | 32 | download 33 | 34 | 35 | heart 36 | 37 | 38 | tags 39 | 40 | 41 | [tags] 42 | 43 | 44 | linux 45 | 46 | 47 | linux 48 | 49 | 50 | linux 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /test/examples/html5/inline_kbd.html: -------------------------------------------------------------------------------- 1 | 2 | F11 3 | 4 | 5 | Ctrl+Shift+N 6 | -------------------------------------------------------------------------------- /test/examples/html5/inline_menu.html: -------------------------------------------------------------------------------- 1 | 2 | File 3 | 4 | 5 | 6 | File  Save 7 | 8 | 9 | 10 | 11 | View  Zoom  Reset 12 | 13 | -------------------------------------------------------------------------------- /test/examples/html5/inline_quoted.html: -------------------------------------------------------------------------------- 1 | 2 | chunky bacon 3 | 4 | 5 | chunky bacon 6 | 7 | 8 | chunky bacon 9 | 10 | 11 | chunky bacon 12 | 13 | 14 | chunky bacon 15 | 16 | 17 | hello world! 18 | 19 | 20 | hello world! 21 | 22 | 23 | superchunky bacon 24 | 25 | 26 | superchunky bacon 27 | 28 | 29 | subchunky bacon 30 | 31 | 32 | subchunky bacon 33 | 34 | 35 | chunky bacon 36 | 37 | 38 | “chunky bacon” 39 | 40 | 41 | “chunky bacon” 42 | 43 | 44 | ‘chunky bacon’ 45 | 46 | 47 | ‘chunky bacon’ 48 | 49 | 50 | \$sqrt(4) = 2\$ 51 | 52 | 53 | \(C = \alpha + \beta Y^{\gamma} + \epsilon\) 54 | 55 | 56 | chunky bacon 57 | 58 | 59 | monospace bold italic phrase and letters 60 | 61 | 62 | striked text 63 | 64 | 65 | striked text 66 | 67 | 68 | deleted text 69 | 70 | 71 | inserted text 72 | 73 | 74 | „chunky bacon“ 75 | 76 | 77 | ”chunky bacon” 78 | 79 | 80 | „chunky bacon” 81 | 82 | 83 | „chunky bacon” 84 | 85 | 86 | ‚chunky bacon‘ 87 | 88 | 89 | ’chunky bacon’ 90 | 91 | 92 | ‚chunky bacon’ 93 | 94 | 95 | «chunky bacon» 96 | -------------------------------------------------------------------------------- /test/examples/html5/listing.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
echo -n "Please enter your name: "
 4 | read name
 5 | echo "Hello, $name!"
6 |
7 | 8 | 9 |
10 |
Reading user input
11 |
echo -n "Please enter your name: "
12 | read name
13 | echo "Hello, $name!"
14 | 15 | 16 | 17 |
18 |
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
19 |
20 | 21 | 22 |
23 |
echo -n "Please enter your name: "
24 | read name
25 | echo "Hello, $name!"
26 |
27 | 28 | 29 |
30 |
5.times do
31 |   print "Odelay!"
32 | end
33 |
34 | 35 | 36 |
37 |
Odelay!
38 |
5.times do
39 |   print "Odelay!"
40 | end
41 | 42 | 43 | 44 |
45 |
46 |     5.times do
47 |   print "Odelay!"
48 | end
49 |   
50 |
51 | 52 | 53 |
54 |
55 |     public class ApplicationConfigurationProvider extends HttpConfigurationProvider {
56 | 
57 |    public Configuration getConfiguration(ServletContext context) {
58 |       return ConfigurationBuilder.begin()
59 |                .addRule()
60 |                .when(Direction.isInbound().and(Path.matches("/{path}")))
61 |                .perform(Log.message(Level.INFO, "Client requested path: {path}"))
62 |                .where("path").matches(".*");
63 |    }
64 | }
65 |   
66 |
67 | 68 | 69 |
70 |
71 |     5.times do
72 |   print "Odelay!"
73 | end
74 |   
75 |
76 | 77 | 78 |
79 |
5.times do
80 |   print "Odelay!"
81 | end
82 |
83 | -------------------------------------------------------------------------------- /test/examples/html5/literal.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
error: The requested operation returned error: 1954 Forbidden search for defensive operations manual
 4 | absolutely fatal: operation initiation lost in the dodecahedron of doom
 5 | would you like to die again? y/n
6 |
7 | 8 | 9 |
10 |
Die again?
11 |
error: The requested operation returned error: 1954 Forbidden search for defensive operations manual
12 | absolutely fatal: operation initiation lost in the dodecahedron of doom
13 | would you like to die again? y/n
14 |
15 | 16 | 17 |
18 |
error: The requested operation returned error: 1954 Forbidden search for defensive operations manual
19 | absolutely fatal: operation initiation lost in the dodecahedron of doom
20 | would you like to die again? y/n
21 |
22 | 23 | 24 |
25 |
error: The requested operation returned error: 1954 Forbidden search for defensive operations manual
26 | absolutely fatal: operation initiation lost in the dodecahedron of doom
27 | would you like to die again? y/n
28 |
29 | -------------------------------------------------------------------------------- /test/examples/html5/olist.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
    4 |
  1. Step 1
  2. 5 |
  3. Step 2
  4. 6 |
  5. Step 3
  6. 7 |
8 |
9 | 10 | 11 |
12 |
    13 |
  1. Step 1
  2. 14 |
  3. Step 2
  4. 15 |
  5. Step 3
  6. 16 |
17 |
18 | 19 | 20 |
21 |
    22 |
  1. Step 1
  2. 23 |
  3. Step 2
  4. 24 |
  5. Step 3
  6. 25 |
26 |
27 | 28 | 29 |
30 |
    31 |
  1. level 1 32 |
      33 |
    1. level 2 34 |
        35 |
      1. level 3 36 |
          37 |
        1. level 4 38 |
            39 |
          1. level 5
          2. 40 |
          41 |
        2. 42 |
        43 |
      2. 44 |
      45 |
    2. 46 |
    47 |
  2. 48 |
49 |
50 | 51 | 52 |
53 |
Steps
54 |
    55 |
  1. Step 1
  2. 56 |
  3. Step 2
  4. 57 |
  5. Step 3
  6. 58 |
59 |
60 | 61 | 62 |
63 |
    64 |
  1. Step 1
  2. 65 |
  3. Step 2
  4. 66 |
  5. Step 3
  6. 67 |
68 |
69 | 70 | 71 |
72 |
    73 |
  1. level 1 74 |
      75 |
    1. level 2 76 |
        77 |
      1. level 3 78 |
          79 |
        1. level 4 80 |
            81 |
          1. level 5
          2. 82 |
          83 |
        2. 84 |
        85 |
      2. 86 |
      87 |
    2. 88 |
    3. level 2
    4. 89 |
    90 |
  2. 91 |
92 |
93 | 94 | 95 |
96 |
    97 |
  1. 98 |

    Every list item has at least one paragraph of content, 99 | which may be wrapped, even using a hanging indent.

    100 |

    Additional paragraphs or blocks are adjoined by putting 101 | a list continuation on a line adjacent to both blocks.

    102 |
    103 |
    list continuation
    104 |
    a plus sign (+) on a line by itself
    105 |
    106 |
  2. 107 |
  3. 108 |

    A literal paragraph does not require a list continuation.

    109 |
    110 |
    $ gem install asciidoctor
    111 |
    112 |
  4. 113 |
114 |
115 | -------------------------------------------------------------------------------- /test/examples/html5/open.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |

An open block can be an anonymous container, or it can masquerade as any other block.

5 |
6 |
7 | 8 | 9 |
10 |
An open block
11 |
12 |

An open block can be an anonymous container, or it can masquerade as any other block.

13 |
14 |
15 | 16 | 17 |
18 |
19 |

An open block can be an anonymous container, or it can masquerade as any other block.

20 |
21 |
22 | 23 | 24 |
25 |
26 |

This is an abstract quote block.

27 |
28 |
29 | 30 | 31 |
32 |
Abstract title is abstract
33 |
34 |

This is an abstract quote block. Who knows what it really means?

35 |
36 |
37 | 38 | 39 |
40 |
41 |

This is an abstract quote block. Who knows what it really means?

42 |
43 |
44 | -------------------------------------------------------------------------------- /test/examples/html5/outline.html: -------------------------------------------------------------------------------- 1 | 5 |
    6 |
  1. Section 1
  2. 7 |
  3. 8 | Section 2 9 |
      10 |
    1. Section 2.1
    2. 11 |
    12 |
  4. 13 |
  5. Section 3
  6. 14 |
15 | 16 | 20 |
    21 |
  1. Section 1
  2. 22 |
  3. Section 2
  4. 23 |
24 | 25 | 29 |
    30 |
  1. 1. Section 1
  2. 31 |
  3. Unnumbered Section
  4. 32 |
  5. 33 | 2. Section 2 34 |
      35 |
    1. 2.1. Section 2.1
    2. 36 |
    37 |
  6. 38 |
  7. 3. Section 3
  8. 39 |
40 | 41 | 45 |
    46 |
  1. 47 | 1. Section 1 48 |
      49 |
    1. 50 | Section 1.1 51 |
        52 |
      1. Section 1.1.1
      2. 53 |
      54 |
    2. 55 |
    56 |
  2. 57 |
  3. 2. Section 2
  4. 58 |
59 | 60 | 64 |
    65 |
  1. Section One
  2. 66 |
  3. Section Two
  4. 67 |
  5. CTU in Prague
  6. 68 |
69 | -------------------------------------------------------------------------------- /test/examples/html5/page_break.html: -------------------------------------------------------------------------------- 1 | 2 |

Text on the first page

3 |
4 |

was breaked!

5 | -------------------------------------------------------------------------------- /test/examples/html5/paragraph.html: -------------------------------------------------------------------------------- 1 | 2 |

Paragraphs don’t require any special markup in AsciiDoc. 3 | A paragraph is just one or more lines of consecutive text.

4 |

To begin a new paragraph, separate it by at least one blank line.

5 | 6 | 7 |
8 |
Paragraphs
9 |

Paragraphs don’t require any special markup in AsciiDoc. A paragraph is just one or more lines of consecutive text.

10 |
11 |

To begin a new paragraph, separate it by at least one blank line.

12 | 13 | 14 |

Paragraphs don’t require any special markup in AsciiDoc. 15 | A paragraph is just one or more lines of consecutive text.

16 | -------------------------------------------------------------------------------- /test/examples/html5/pass.html: -------------------------------------------------------------------------------- 1 | 2 |

Allons-y!

image:tiger.png[] 3 | -------------------------------------------------------------------------------- /test/examples/html5/preamble.html: -------------------------------------------------------------------------------- 1 | 5 |
6 |

This journey begins on a bleary Monday morning. 7 | Our intrepid team is in desperate need of double shot mochas, but the milk expired eight days ago.

8 |
9 | 10 | 14 |
15 |

This journey begins on a bleary Monday morning. 16 | Our intrepid team is in desperate need of double shot mochas, but the milk expired eight days ago.

17 |
18 | 24 | -------------------------------------------------------------------------------- /test/examples/html5/quote.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |

Four score and seven years ago our fathers brought forth 5 | on this continent a new nation…​

6 |
7 |
8 | 9 | 10 |
11 |
12 |

A person who never made a mistake never tried anything new.

13 |
Albert Einstein
14 |
15 |
16 | 17 | 18 |
19 |
20 |

Everybody remember where we parked.

21 |
Captain James T. Kirk, Star Trek IV: The Voyage Home
22 |
23 |
24 | 25 | 26 |
27 |
After landing the cloaked Klingon bird of prey in Golden Gate park:
28 |
29 |

Everybody remember where we parked.

30 |
31 |
32 | 33 | 34 |
35 |
36 |

Everybody remember where we parked.

37 |
38 |
39 | 40 | 41 |
42 |
43 |

Dennis: Come and see the violence inherent in the system. Help! Help! I’m being repressed!

44 |

King Arthur: Bloody peasant!

45 |

Dennis: Oh, what a giveaway! Did you hear that? Did you hear that, eh? That’s what I’m on about! Did you see him repressing me? You saw him, Didn’t you?

46 |
47 |
48 | -------------------------------------------------------------------------------- /test/examples/html5/regressions.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
source 1 line 1 1
 4 | source 1 line 2 2
5 |
    6 |
  1. source 1 callout 1
  2. 7 |
  3. source 1 callout 2
  4. 8 |
9 |
10 |

Some text in here.

11 |
12 |
source 2 line 1 1
13 | source 2 line 2 2
14 |
    15 |
  1. source 2 callout 1
  2. 16 |
  3. source 2 callout 2
  4. 17 |
18 |
19 |

Where is this?

20 |
21 |

Heading

22 |

This is actually here.

23 |
24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 36 | 37 | 38 | 41 | 42 | 43 |
34 | cell [1] 35 |
39 | cell [1] 40 |
44 |
45 |

paragraph [2]

46 |

another paragraph [2]

47 |
48 |
49 |
    50 |
  1. 51 | first 52 |
  2. 53 |
  3. 54 | second 55 |
  4. 56 |
57 |
58 | -------------------------------------------------------------------------------- /test/examples/html5/replacements.html: -------------------------------------------------------------------------------- 1 | 2 |

chunky – bacon

3 | 4 | 5 |

chunky — bacon

6 | 7 | 8 |

 – bacon

9 | 10 | 11 |

chunky – 

12 | 13 | 14 |

1955–2011

15 | 16 | 17 |

1955—​2011

18 | 19 | 20 |

chunky — bacon

21 | 22 | 23 |

 — bacon

24 | 25 | 26 |

chunky — 

27 | 28 | 29 |

1955—​2011

30 | -------------------------------------------------------------------------------- /test/examples/html5/section.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |

Section Level 1

4 |
5 | 6 | 7 |
8 |

Section Level 2

9 |
10 | 11 | 12 |
13 |

Section Level 3

14 |
15 | 16 | 17 |
18 |
Section Level 4
19 |
20 | 21 | 22 |
23 |
Section Level 5
24 |
25 | 26 | 27 |
28 |

Section Level 1

29 |
30 |

Section Level 2

31 |
32 |

Section Level 3

33 |
34 |
Section Level 4
35 |
36 |
Section Level 5
37 |
38 |
39 |
40 |
41 |
42 |

Section Level 2

43 |
44 |
45 | 46 | 47 |
48 |

Section Title

49 |
50 | 51 | 52 |
53 |

Section Title

54 |
55 | 56 | 57 |
58 |

59 | Title with anchor 60 |

61 |
62 | 63 | 64 |
65 |

66 | Linked title 67 |

68 |
69 | 70 | 71 |
72 |

73 | 74 | Linked title with anchor 75 |

76 |
77 | 78 | 79 |
80 |

1. Introduction to Asciidoctor

81 |
82 |
83 |

2. Quick Starts

84 |
85 |

2.1. Usage

86 |
87 |

2.1.1. Using the Command Line Interface

88 |
89 |
Processing Your Content
90 |
91 |
92 |
93 |
94 |

2.2. Syntax

95 |
96 |
97 |
98 |

3. Terms and Concepts

99 |
100 | 101 | 102 |
103 |

1. Introduction to Asciidoctor

104 |
105 |
106 |

2. Quick Starts

107 |
108 |

Usage

109 |
110 |

Using the Command Line Interface

111 |
112 |
113 |
114 |

Syntax

115 |
116 |
117 |
118 |

3. Terms and Concepts

119 |
120 | 121 | 122 |
123 |

Part Title

124 |
125 |

Section Level 1

126 |
127 |
128 | -------------------------------------------------------------------------------- /test/examples/html5/sidebar.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 15 | 16 | 17 | 22 | -------------------------------------------------------------------------------- /test/examples/html5/stem.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
\$sqrt(4) = 2\$
4 |
5 | 6 | 7 |
8 |
\[C = \alpha + \beta Y^{\gamma} + \epsilon\]
9 |
10 | 11 | 12 |
13 |
Equation
14 |
\$sqrt(4) = 2\$
15 |
16 | 17 | 18 |
19 |
\$sqrt(4) = 2\$
20 |
21 | -------------------------------------------------------------------------------- /test/examples/html5/table.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
Cell in column 1, row 1Cell in column 2, row 1
Cell in column 1, row 2Cell in column 2, row 2
19 |
20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
Cell in column 1, row 1Cell in column 2, row 1
35 |
36 | 37 | 38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 |
Cell in column 1, row 1Cell in column 2, row 1
51 |
52 | 53 | 54 |
55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 |
Cell in column 1, row 1Cell in column 2, row 1
67 |
68 | 69 | 70 |
71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 |
Cell in column 1, row 1Cell in column 2, row 1
83 |
84 | 85 | 86 |
87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 |
Cell in column 1, row 1Cell in column 2, row 1
99 |
100 | 101 | 102 |
103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 |
Cell in column 1, row 1Cell in column 2, row 1
115 |
116 | 117 | 118 |
119 |
Table 1. Table FTW!
120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 |
Cell in column 1, row 1Cell in column 2, row 1
132 |
133 | 134 | 135 |
136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 |
Cell in column 1, row 1Cell in column 2, row 1
148 |
149 | 150 | 151 |
152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 |
Name of Column 1Name of Column 2
Cell in column 1, row 1Cell in column 2, row 1
Cell in column 1, row 2Cell in column 2, row 2
174 |
175 | 176 | 177 |
178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 |
Footer in column 1, row 3Footer in column 2, row 3
Cell in column 1, row 1Cell in column 2, row 1
Cell in column 1, row 2Cell in column 2, row 2
200 |
201 | 202 | 203 |
204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 |
Cell in column 1, row 1Cell in column 2, row 1Cell in column 3, row 1
218 |
219 | 220 | 221 |
222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 |
Cell in column 1, row 1Cell in column 2, row 1Cell in column 3, row 1
236 |
237 | 238 | 239 |
240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 |
Cell in column 1, row 1Cell in column 2, row 1Cell in column 3, row 1
254 |
255 | 256 | 257 |
258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 274 | 277 | 280 | 285 | 288 | 291 | 292 | 293 |
270 |
271 | AsciiDoc content 272 |
273 |
275 | Emphasized text 276 | 278 | Styled like a header 279 | 281 |
282 |
Literal block
283 |
284 |
286 | Monospaced text 287 | 289 | Strong text 290 |
294 |
295 | 296 | 297 |
298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 311 | 312 | 313 |
Single paragraph on row 1
308 |

First paragraph on row 2

309 |

Second paragraph on row 2

310 |
314 |
315 | 316 | 317 |
318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 334 | 335 | 336 | 337 |
Cell in column 1, row 1Cell in column 2, row 1Cell in column 3, row 1
332 | Content in a single cell that spans columns 1 and 3 333 | Cell in column 3, row 1
338 |
339 | 340 | 341 |
342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 |
Cell in column 1, row 1Cell in column 2, row 1Cell in column 3, row 1
356 | Content in a single cell that spans rows 2 and 3 357 | Cell in column 2, row 2Cell in column 3, row 2
Cell in column 2, row 3Cell in column 3, row 3
367 |
368 | 369 | 370 |
371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 382 | 385 | 388 | 389 | 390 | 393 | 396 | 399 | 400 | 401 | 404 | 405 | 406 |
380 | Prefix the {vbar} with {caret} to center content horizontally 381 | 383 | Prefix the {vbar} with < to align the content to the left horizontally 384 | 386 | Prefix the {vbar} with > to align the content to the right horizontally 387 |
391 | Prefix the {vbar} with a . and {caret} to center the content in the cell vertically 392 | 394 | Prefix the {vbar} with a . and < to align the content to the top of the cell 395 | 397 | Prefix the {vbar} with a . and > to align the content to the bottom of the cell 398 |
402 | This content spans three columns (3{plus}) and is centered horizontally ({caret}) and vertically (.{caret}) within the cell. 403 |
407 |
408 | 409 | 410 |
411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 423 | 428 | 429 | 430 | 433 | 436 | 437 | 438 | 443 | 444 | 445 | 452 | 453 | 454 |
419 |

This content is duplicated across two columns.

420 |

It is aligned right horizontally.

421 |

And it is monospaced.

422 |
424 |

This content is duplicated across two columns.

425 |

It is aligned right horizontally.

426 |

And it is monospaced.

427 |
431 | This cell spans 3 rows. The content is centered horizontally, aligned to the bottom of the cell, and strong. 432 | 434 | This content is emphasized. 435 |
439 |
440 |
This content is aligned to the top of the cell and literal.
441 |
442 |
446 |
447 |
448 |               puts "This is a source block!"
449 |             
450 |
451 |
455 |
456 | -------------------------------------------------------------------------------- /test/examples/html5/thematic_break.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | -------------------------------------------------------------------------------- /test/examples/html5/toc.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |

Introduction

4 |
16 |
17 |

The Ravages of Writing

18 |
19 |

A Recipe for Potion

20 |
21 |
22 | 23 | 24 |
35 |
36 |

The Ravages of Writing

37 |
38 |

A Recipe for Potion

39 |
40 |
41 | 42 | 45 | 52 | 53 | 56 | 63 | 64 | 67 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /test/examples/html5/ulist.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
    4 |
  • Edgar Allen Poe
  • 5 |
  • Sheri S. Tepper
  • 6 |
  • Bill Bryson
  • 7 |
8 |
9 | 10 | 11 |
12 |
Writers
13 |
    14 |
  • Edgar Allen Poe
  • 15 |
  • Sheri S. Tepper
  • 16 |
  • Bill Bryson
  • 17 |
18 |
19 | 20 | 21 |
22 |
    23 |
  • Edgar Allen Poe
  • 24 |
  • Sheri S. Tepper
  • 25 |
  • Bill Bryson
  • 26 |
27 |
28 | 29 | 30 |
31 |
    32 |
  • level 1 33 |
      34 |
    • level 2 35 |
        36 |
      • level 3 37 |
          38 |
        • level 4 39 |
            40 |
          • level 5
          • 41 |
          42 |
        • 43 |
        44 |
      • 45 |
      46 |
    • 47 |
    • level 2
    • 48 |
    49 |
  • 50 |
51 |
52 | 53 | 54 |
55 |
    56 |
  • 57 |

    Every list item has at least one paragraph of content, 58 | which may be wrapped, even using a hanging indent.

    59 |

    Additional paragraphs or blocks are adjoined by putting 60 | a list continuation on a line adjacent to both blocks.

    61 |
    62 |
    list continuation
    63 |
    a plus sign (+) on a line by itself
    64 |
    65 |
  • 66 |
  • 67 |

    A literal paragraph does not require a list continuation.

    68 |
    69 |
    $ gem install asciidoctor
    70 |
    71 |
  • 72 |
73 |
74 | 75 | 76 |
77 |
    78 |
  • checked
  • 79 |
  • also checked
  • 80 |
  • not checked
  • 81 |
  • normal list item
  • 82 |
83 |
84 | -------------------------------------------------------------------------------- /test/examples/html5/verse.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
The fog comes
 4 | on little cat feet.
5 |
6 | 7 | 8 |
9 |
10 |
The fog comes
11 | on little cat feet.
12 |
Carl Sandburg
13 |
14 |
15 | 16 | 17 |
18 |
19 |
The fog comes
20 | on little cat feet.
21 |
Carl Sandburg, two lines from the poem Fog
22 |
23 |
24 | 25 | 26 |
27 |
Poetry
28 |
The fog comes
29 | on little cat feet.
30 |
31 | 32 | 33 |
34 |
The fog comes
35 | on little cat feet.
36 |
37 | 38 | 39 |
40 |
The fog comes
41 | on little cat feet.
42 | 
43 | It sits looking
44 | over harbor and city
45 | on silent haunches
46 | and then moves on.
47 |
48 | -------------------------------------------------------------------------------- /test/examples/html5/video.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 |
5 | 6 | 7 |
8 | 9 |
10 | 11 | 12 |
13 | 14 |
15 | 16 | 17 |
18 | 19 |
20 | 21 | 22 |
23 | 24 |
25 | 26 | 27 |
28 | 29 |
30 | 31 | 32 |
33 | 34 |
Must watch!
35 |
36 | 37 | 38 |
39 | 40 |
41 | 42 | 43 |
44 | 45 |
46 | 47 | 48 |
49 | 50 |
51 | 52 | 53 |
54 | 55 |
56 | 57 | 58 |
59 | 60 |
61 | 62 | 63 |
64 | 65 |
66 | 67 | 68 |
69 | 70 |
71 | --------------------------------------------------------------------------------