[DRE-commits] [asciidoctor] 01/06: New upstream version 1.5.5
Lucas Nussbaum
lucas at moszumanska.debian.org
Sun Jul 2 11:12:36 UTC 2017
This is an automated email from the git hooks/post-receive script.
lucas pushed a commit to branch master
in repository asciidoctor.
commit 45672bf538560b450d7fa5a2fb0ac9853c089429
Author: Lucas Nussbaum <lucas at debian.org>
Date: Sun Jul 2 11:24:27 2017 +0200
New upstream version 1.5.5
---
.travis.yml | 17 +-
CHANGELOG.adoc | 77 +++-
CONTRIBUTING.adoc | 6 +-
README-fr.adoc | 191 ++++++---
README-jp.adoc | 395 +++++++++++++++++
README-zh_CN.adoc | 414 ++++++++++++++++++
README.adoc | 206 +++++----
_settings-README.adoc | 7 +-
asciidoctor.gemspec | 38 +-
benchmark/benchmark.rb | 2 +-
data/locale/attributes.adoc | 470 +++++++++++++++++++++
data/stylesheets/asciidoctor-default.css | 11 +-
lib/asciidoctor.rb | 41 +-
lib/asciidoctor/abstract_block.rb | 30 +-
lib/asciidoctor/abstract_node.rb | 17 +-
lib/asciidoctor/cli/invoker.rb | 9 +-
lib/asciidoctor/cli/options.rb | 2 +-
lib/asciidoctor/converter/docbook5.rb | 2 +-
lib/asciidoctor/converter/factory.rb | 6 +-
lib/asciidoctor/converter/html5.rb | 67 +--
lib/asciidoctor/converter/manpage.rb | 23 +-
lib/asciidoctor/converter/template.rb | 12 +-
lib/asciidoctor/core_ext.rb | 13 +-
lib/asciidoctor/core_ext/{ => 1.8.7}/string/chr.rb | 2 +-
lib/asciidoctor/core_ext/1.8.7/string/limit.rb | 28 ++
.../core_ext/{ => 1.8.7}/symbol/length.rb | 2 +-
lib/asciidoctor/core_ext/nil_or_empty.rb | 23 +
lib/asciidoctor/core_ext/object/nil_or_empty.rb | 23 -
lib/asciidoctor/core_ext/string/limit.rb | 10 +
lib/asciidoctor/document.rb | 59 +--
lib/asciidoctor/extensions.rb | 32 +-
lib/asciidoctor/helpers.rb | 2 +-
lib/asciidoctor/list.rb | 3 +
lib/asciidoctor/parser.rb | 90 ++--
lib/asciidoctor/path_resolver.rb | 4 +-
lib/asciidoctor/reader.rb | 29 +-
lib/asciidoctor/section.rb | 4 +-
lib/asciidoctor/stylesheets.rb | 3 +-
lib/asciidoctor/substitutors.rb | 90 ++--
lib/asciidoctor/table.rb | 79 ++--
lib/asciidoctor/version.rb | 2 +-
man/asciidoctor.1 | 15 +-
man/asciidoctor.adoc | 8 +-
test/attributes_test.rb | 52 +++
test/blocks_test.rb | 16 +-
test/document_test.rb | 14 +-
test/extensions_test.rb | 38 ++
test/fixtures/circle.svg | 3 +-
test/invoker_test.rb | 15 +
test/lists_test.rb | 131 +++---
test/manpage_test.rb | 15 +
test/paths_test.rb | 3 +
test/reader_test.rb | 4 +-
test/sections_test.rb | 10 +
test/substitutions_test.rb | 18 +-
test/tables_test.rb | 78 +++-
56 files changed, 2380 insertions(+), 581 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 536ad5b..6a4f6aa 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,17 +3,18 @@ git:
depth: 1
language: ruby
rvm:
- - 2.3.0
- - 2.2.4
- - 2.1.8
+ - 2.3.1
+ - 2.2.5
+ - 2.1.10
- 2.0.0
- 1.9.3
- 1.8.7
- - jruby-9.0.4.0
- - jruby-19mode
- - jruby-18mode
- - rbx-2
+ - jruby-9.0.5.0
+ - jruby-9.1.2.0
+ - jruby-19mode # based on jruby-1.7.19
+ - jruby-18mode # based on jruby-1.7.19
+ #- rbx-3.60 # NOTE not working currently
script: bundle exec rake coverage test:all
notifications:
email: false
- irc: 'irc.freenode.org#asciidoctor'
+ #irc: 'irc.freenode.org#asciidoctor'
diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc
index c604982..7891f83 100644
--- a/CHANGELOG.adoc
+++ b/CHANGELOG.adoc
@@ -1,6 +1,8 @@
= Asciidoctor Changelog
-:uri-asciidoctor: https://github.com/asciidoctor/asciidoctor
-:uri-asciidoc: http://asciidoctor.org/docs/what-is-asciidoc
+:uri-asciidoctor: http://asciidoctor.org
+:uri-asciidoc: {uri-asciidoctor}/docs/what-is-asciidoc
+:uri-repo: https://github.com/asciidoctor/asciidoctor
+:icons: font
:star: icon:star[role=red]
ifndef::icons[]
:star: ★
@@ -9,9 +11,73 @@ endif::[]
{uri-asciidoctor}[Asciidoctor] is a _fast_, open source text processor and publishing toolchain for converting {uri-asciidoc}[AsciiDoc] content into HTML5, DocBook 5 (or 4.5) and other formats.
This document provides a high-level view of the changes introduced in Asciidoctor by release.
-For a detailed view of what has changed, refer to the https://github.com/asciidoctor/asciidoctor/commits/master[commit history] on GitHub.
+For a detailed view of what has changed, refer to the {uri-repo}/commits/master[commit history] on GitHub.
// tag::compact[]
+== 1.5.5 (2016-10-05) - @mojavelinux
+
+Enhancements::
+ * Add preference to limit the maximum size of an attribute value (#1861)
+ * Honor SOURCE_DATE_EPOCH environment variable to accomodate reproducible builds (@JojoBoulix) (#1721)
+ * Add reversed attribute to ordered list if reversed option is enabled (#1830)
+ * Add support for additional docinfo locations (e.g., :header)
+ * Configure default stylesheet to break monospace word if exceeds length of line; add roles to prevent breaks (#1814)
+ * Introduce translation file for built-in labels (@ciampix)
+ * Provide translations for built-in labels (@JmyL - kr, @ciampix - it, @ivannov - bg, @maxandersen - da, @radcortez - pt, @eddumelendez - es, @leathersole - jp, @aslakknutsen - no, @shahryareiv - fa, @AlexanderZobkov - ru, @dongwq - zh, @rmpestano - pt_BR, @ncomet - fr, @lgvz - fi, @patoi - hu, @BojanStipic - sr, @fwilhe - de, @rahmanusta - tr, @abelsromero - ca, @aboullaite - ar, @roelvs - nl)
+ * Translate README to Chinese (@diguage)
+ * Translate README to Japanese (@Mizuho32)
+
+Improvements::
+ * Style nested emphasized phrases properly when using default stylesheet (#1691)
+ * Honor explicit table width even when autowidth option is set (#1843)
+ * Only explicit noheader option on table should disable implicit table header (#1849)
+ * Support docbook orient="land" attribute on tables (#1815)
+ * Add alias named list to retrieve parent List of ListItem
+ * Update push_include method to support chaining (#1836)
+ * Enable font smoothing on Firefox on OSX (#1837)
+ * Support combined use of sectanchors and sectlinks in HTML5 output (#1806)
+ * fix API docs for find_by
+ * Upgrade to Font Awesome 4.6.3 (@allenan, @mogztter) (#1723)
+ * README: add install instructions for Alpine Linux
+ * README: Switch yum commands to dnf in README
+ * README: Mention Mint as a Debian distro that packages Asciidoctor
+ * README: Add caution advising against using gem update to update a system-managed gem (@oddhack)
+ * README: sync French version with English version (@flashcode)
+ * Add missing endline after title element when converting open block to HTML
+ * Move list_marker_keyword method from AbstractNode to AbstractBlock
+ * Rename definition list to description list internally
+
+Compliance::
+ * Support 6-digit decimal char refs, 5-digit hexidecimal char refs (#1824)
+ * Compatibility fixes for Opal
+ * Check for number using Integer instead of Fixnum class for compatibility with Ruby 2.4
+
+Bug fixes::
+ * Use method_defined? instead of respond_to? to check if method is already defined when patching (#1838)
+ * Fix invalid conditional in HTML5 converter when handling of SVG
+ * Processor#parse_content helper no longer shares attribute list between blocks (#1651)
+ * Fix infinite loop if unordered list marker is immediately followed by a dot (#1679)
+ * Don't break SVG source when cleaning if svg start tag name is immediately followed by endline (#1676)
+ * Prevent template converter from crashing if .rb file found in template directory (#1827)
+ * Fix crash when generating section ID when both idprefix & idseparator are blank (#1821)
+ * Use stronger CSS rule for general text color in Pygments stylesheet (#1802)
+ * Don't duplicate forward slash for path relative to root (#1822)
+
+Infrastructure::
+ * Build gem properly in the absense of a git workspace, make compatible with JRuby (#1779)
+ * Run tests in CI using latest versions of Ruby, including Ruby 2.3 (@ferdinandrosario)
+
+Distribution Packages::
+
+ * http://rubygems.org/gems/asciidoctor[RubyGem (asciidoctor)]
+ * https://apps.fedoraproject.org/packages/rubygem-asciidoctor[Fedora (rubygem-asciidoctor)]
+ * http://packages.debian.org/sid/asciidoctor[Debian (asciidoctor)]
+ * http://packages.ubuntu.com/saucy/asciidoctor[Ubuntu (asciidoctor)]
+
+https://github.com/asciidoctor/asciidoctor/issues?q=milestone%3Av1.5.5[issues resolved] |
+https://github.com/asciidoctor/asciidoctor/releases/tag/v1.5.5[git tag] |
+https://github.com/asciidoctor/asciidoctor/compare/v1.5.4...v1.5.5[full diff]
+
== 1.5.4 (2016-01-03) - @mojavelinux
Enhancements::
@@ -100,7 +166,7 @@ Improvements::
* restore attributes to header attributes after parse (#1255)
* allow docdate and doctime to be overridden (#1495)
* add CSS class `.center` for center block alignment (#1456)
- * recognize U+2022 as alternative marker for unordered lists (@mogztter) (#1177)
+ * recognize U+2022 (bullet) as alternative marker for unordered lists (@mogztter) (#1177)
* allow videos to work for local files by prepending asset-uri-scheme (Chris) (#1320)
* always assign playlist param when loop option is enabled for YouTube video
* parse isolated version in revision line (@bk2204) (#790)
@@ -125,6 +191,7 @@ Improvements::
* fix `+--help+` output text for `-I` (@bk2204)
* don't require open-uri-cached if already loaded
* do not attempt to scan pattern of non-existent directory in template converter
+ * prevent CodeRay from bolding every 10th line number
Compliance::
* use `<sup>` for footnote reference in text instead of `<span>` (#1523)
@@ -177,6 +244,7 @@ Distribution Packages::
https://github.com/asciidoctor/asciidoctor/issues?q=milestone%3Av1.5.3[issues resolved] |
https://github.com/asciidoctor/asciidoctor/releases/tag/v1.5.3[git tag] |
https://github.com/asciidoctor/asciidoctor/compare/v1.5.2...v1.5.3[full diff]
+// end::compact[]
== 1.5.2 (2014-11-27) - @mojavelinux
@@ -231,7 +299,6 @@ Distribution Packages::
https://github.com/asciidoctor/asciidoctor/issues?q=milestone%3Av1.5.2[issues resolved] |
https://github.com/asciidoctor/asciidoctor/releases/tag/v1.5.2[git tag] |
https://github.com/asciidoctor/asciidoctor/compare/v1.5.1...v1.5.2[full diff]
-// end::compact[]
== 1.5.1 (2014-09-29) - @mojavelinux
diff --git a/CONTRIBUTING.adoc b/CONTRIBUTING.adoc
index d729c53..64e1fe9 100644
--- a/CONTRIBUTING.adoc
+++ b/CONTRIBUTING.adoc
@@ -38,12 +38,12 @@ An ideal bug report would include a pull request with failing specs.
. {uri-branch-help}[Create a topic branch] (preferably using the pattern `issue-XYZ`, where `XYZ` is the issue number).
. Add tests for your unimplemented feature or bug fix. (See <<writing-and-executing-tests>>)
. Run `bundle exec rake` to run the tests.
-If your tests pass, return to step 3.
+If your tests pass, return to step 4.
. Implement your feature or bug fix.
. Run `bundle exec rake` to run the tests.
-If your tests fail, return to step 5.
+If your tests fail, return to step 6.
. Add documentation for your feature or bug fix.
-. If your changes are not 100% documented, go back to step 7.
+. If your changes are not 100% documented, go back to step 8.
. Add, commit, and push your changes.
. {uri-pr-help}[Submit a pull request].
diff --git a/README-fr.adoc b/README-fr.adoc
index 2594f8c..7440b08 100644
--- a/README-fr.adoc
+++ b/README-fr.adoc
@@ -1,6 +1,5 @@
= Asciidoctor
Dan Allen <https://github.com/mojavelinux[@mojavelinux]>; Sarah White <https://github.com/graphitefriction[@graphitefriction]>; Ryan Waldron <https://github.com/erebor[@erebor]>
-v1.5.4, 2016-01-03
// FIXME use build system to expand includes statically so document renders properly on GitHub
ifeval::[{safe-mode-level} < 20]
include::_settings-README.adoc[]
@@ -12,14 +11,14 @@ ifeval::[{safe-mode-level} >= 20]
:idseparator: -
:source-language: ruby
:language: {source-language}
-ifdef::env-github[:badges:]
+ifdef::env-github[:status:]
// URIs:
:uri-org: https://github.com/asciidoctor
:uri-repo: {uri-org}/asciidoctor
:uri-asciidoctorj: {uri-org}/asciidoctorj
:uri-asciidoctorjs: {uri-org}/asciidoctor.js
:uri-project: http://asciidoctor.org
-ifdef::awestruct-version[:uri-project: link:]
+ifdef::env-site[:uri-project: link:]
:uri-docs: {uri-project}/docs
:uri-news: {uri-project}/news
:uri-manpage: {uri-project}/man/asciidoctor
@@ -27,7 +26,7 @@ ifdef::awestruct-version[:uri-project: link:]
:uri-contributors: {uri-repo}/graphs/contributors
:uri-rel-file-base: link:
:uri-rel-tree-base: link:
-ifdef::awestruct-version[]
+ifdef::env-site[]
:uri-rel-file-base: {uri-repo}/blob/master/
:uri-rel-tree-base: {uri-repo}/tree/master/
endif::[]
@@ -40,7 +39,8 @@ endif::[]
:uri-rubygem: https://rubygems.org/gems/asciidoctor
:uri-what-is-asciidoc: {uri-docs}/what-is-asciidoc
:uri-user-manual: {uri-docs}/user-manual
-:uri-install-doc: {uri-docs}/install-toolchain
+:uri-install-docker: https://github.com/asciidoctor/docker-asciidoctor
+//:uri-install-doc: {uri-docs}/install-toolchain
:uri-install-osx-doc: {uri-docs}/install-asciidoctor-macosx
:uri-render-doc: {uri-docs}/render-documents
:uri-themes-doc: {uri-docs}/produce-custom-themes-using-asciidoctor-stylesheet-factory
@@ -56,10 +56,17 @@ endif::[]
{uri-project}/[Asciidoctor] est un processeur de texte _rapide_ et une chaîne de publication pour convertir du contenu {uri-what-is-asciidoc}[AsciiDoc] en HTML5, DocBook 5 (ou 4.5) et d'autres formats.
Asciidoctor est écrit en Ruby, packagé sous forme de RubyGem et publié sur {uri-rubygem}[RubyGems.org].
-La gem est aussi incluse dans plusieurs distributions Linux, dont Fedora, Debian et Ubuntu.
+La gemme est aussi incluse dans plusieurs distributions Linux, dont Fedora, Debian et Ubuntu.
Asciidoctor est open source, {uri-repo}[hébergé sur GitHub] et distribué sous {uri-license}[licence MIT].
-.Documentation clée
+ifndef::env-site[]
+.Ce document est traduit dans les langues suivantes :
+* {uri-rel-file-base}README.adoc[Anglais]
+* {uri-rel-file-base}README-zh_CN.adoc[Chinois]
+* {uri-rel-file-base}README-jp.adoc[Japonais]
+endif::[]
+
+.Documentation clé
[.compact]
* {uri-docs}/what-is-asciidoc[Qu'est ce qu'AsciiDoc ?]
* {uri-docs}/asciidoc-writers-guide[Guide pour Rédacteur AsciiDoc]
@@ -77,7 +84,7 @@ Nous utilisons http://opalrb.org[Opal] pour transcrire le code source Ruby en Ja
Asciidoctor.js est utilisé pour faire fonctionner les extensions AsciiDoc Preview pour Chrome, Atom, Brackets et autres outils web.
****
-ifdef::badges[]
+ifdef::status[]
.*Santé du projet*
image:https://img.shields.io/travis/asciidoctor/asciidoctor/master.svg[Build Status (Travis CI), link=https://travis-ci.org/asciidoctor/asciidoctor]
image:https://ci.appveyor.com/api/projects/status/ifplu67oxvgn6ceq/branch/master?svg=true&passingText=green%20bar&failingText=%23fail&pendingText=building%2E%2E%2E[Build Status (AppVeyor), link=https://ci.appveyor.com/project/asciidoctor/asciidoctor]
@@ -99,111 +106,155 @@ Asciidoctor lit et analyse la syntaxe du texte écrit en AsciiDoc afin de créer
Vous avez la possibilité d'écrire votre propre convertisseur ou de fournir des templates supportant {uri-tilt}[Tilt] pour personnaliser le résultat généré ou pour produire des formats alternatifs.
-NOTE: Asciidoctor est un remplaçant du processeur AsciiDoc orginal écrit en Python (`asciidoc.py`).
+NOTE: Asciidoctor est un remplaçant du processeur AsciiDoc original écrit en Python (`asciidoc.py`).
La suite de tests Asciidoctor possède {uri-tests}[> 1,600 tests] pour garantir la compatibilité avec la syntaxe AsciiDoc.
-En plus de la syntaxe AsciiDoc standard, Asciidoctor reconnait des balises additionnelles ainsi que des options de formatage, comme les polices d'icônes (e.g., `+icon:fire[]+`) et des éléments d'interface (e.g., `+button:[Enregistrer]+`).
-Asciidoctor offre aussi un thème moderne et responsive basé sur {uri-foundation}[Foundation] pour styliser le document HTML5 généré.
+En plus de la syntaxe AsciiDoc standard, Asciidoctor reconnaît des balises additionnelles ainsi que des options de formatage, comme les polices d'icônes (par exemple `+icon:fire[]+`) et des éléments d'interface (par exemple `+button:[Enregistrer]+`).
+Asciidoctor offre aussi un thème moderne et « responsive » basé sur {uri-foundation}[Foundation] pour styliser le document HTML5 généré.
== Prérequis
-Asciidoctor fonctionne sur Linux, OSX (Mac), Windows et requiert une des implémentations suivantes :
+Asciidoctor fonctionne sur Linux, OS X (Mac), Windows et requiert une des implémentations suivantes :
-* MRI (Ruby 1.8.7, 1.9.3, 2.0, 2.1 & 2.2)
-* JRuby 1.7 (Ruby 1.8 and 1.9 modes) & 9000
+* MRI (Ruby 1.8.7, 1.9.3, 2.0, 2.1, 2.2 & 2.3)
+* JRuby (1.7 dans les modes Ruby 1.8 et 1.9, 9000)
* Rubinius 2.2.x
* Opal (JavaScript)
Votre aide est appréciée pour tester Asciidoctor sur l'une de ces plateformes.
-Référez-vous au paragraphe <<{idprefix}contributions,Contributions>> si vous souhaitez vous impliquer dans ce projet.
+Référez-vous au paragraphe <<Contributions>> si vous souhaitez vous impliquer dans ce projet.
+
+[CAUTION]
+====
+Si vous utilisez un environnement Windows dans une autre langue que l'anglais, vous pourriez tomber sur l'erreur `Encoding::UndefinedConversionError` lors du lancement d'Asciidoctor.
+Pour corriger ce problème, nous recommandons de changer la page de code en UTF-8 dans votre console :
+
+ chcp 65001
+
+Après ce changement, tous les maux de tête liés à l'Unicode seront derrière vous.
+Si vous utilisez un environnement de développement comme Eclipse, assurez-vous de définir l'encodage en UTF-8.
+Asciidoctor fonctionne mieux lorsque vous utilisez UTF-8 partout.
+====
== Installation
Asciidoctor peut être installé en utilisant la commande (a) `gem install`, (b) Bundler ou (c) les gestionnaires de paquets pour les distributions Linux populaires.
-TIP: L'avantage d'utiliser le gestionnaire de paquets pour installer la gem est que l'installation englobe celle des librairies Ruby et RubyGems si elles ne sont pas déjà installés.
-L'inconvénient est que le paquet n'est pas forcément mis à jour immédiatement après la release de la gem.
+TIP: L'avantage d'utiliser le gestionnaire de paquets pour installer la gemme est que l'installation englobe celle des librairies Ruby et RubyGems si elles ne sont pas déjà installés.
+L'inconvénient est que le paquet n'est pas forcément mis à jour immédiatement après la mise à disposition de la gemme.
Si vous avez besoin de la dernière version, vous devez passer par la commande `gem`.
-=== (a) Installation de la gem
+=== (a) Installation de la gemme
-Ouvrir un terminal et taper (en excluant le `$`) :
+Ouvrir un terminal et taper (en excluant le `$`) :
$ gem install asciidoctor
-Si vous souhaitez installer une version pre-release (càd, une release candidate), utilisez :
+Si vous souhaitez installer une version pre-release (c'est-à-dire, une « release candidate »), utilisez :
$ gem install asciidoctor --pre
.Mettre à jour votre installation
[TIP]
====
-Si vous avez une précédente version d'Asciidoctor installée, vous pouvez la mettre à jour en utilisant :
+Si vous avez une précédente version d'Asciidoctor installée, vous pouvez la mettre à jour en utilisant :
$ gem update asciidoctor
-Si vous installez une nouvelle version de la gem en utilisant `gem install` au lieu de `gem update`, vous aurez plusieurs versions d'installées.
-Si c'est le cas, utilisez la commande gem suivante pour supprimer la vieille version :
+Si vous installez une nouvelle version de la gemme en utilisant `gem install` au lieu de `gem update`, vous aurez plusieurs versions d'installées.
+Si c'est le cas, utilisez la commande gem suivante pour supprimer la vieille version :
$ gem cleanup asciidoctor
====
=== (b) Bundler
-. Créez un fichier Gemfile à la racine de votre projet (ou du répertoire courant),
-. Ajoutez la gem `asciidoctor` dans votre fichier Gemfile comme ci-dessous :
+. Créez un fichier Gemfile à la racine de votre projet (ou du répertoire courant)
+. Ajoutez la gemme `asciidoctor` dans votre fichier Gemfile comme ci-dessous :
+
[source]
----
source 'https://rubygems.org'
gem 'asciidoctor'
# ou spécifier la version explicitement
-# gem 'asciidoctor', '1.5.3'
+# gem 'asciidoctor', '1.5.4'
----
-. Sauvegardez le fichier Gemfile,
-. Ouvrez un terminal et installez la gem en utilisant :
+. Sauvegardez le fichier Gemfile
+. Ouvrez un terminal et installez la gemme en utilisant :
$ bundle
-Pour mettre à jour la gem, spécifiez la nouvelle version dans le fichier Gemfile et exécutez `bundle` à nouveau.
-Utiliser `bundle update` *n*'est *pas* recommandé car les autres gems seront également mises à jour, ce qui n'est pas forcément le résultat attendu.
+Pour mettre à jour la gemme, spécifiez la nouvelle version dans le fichier Gemfile et exécutez `bundle` à nouveau.
+Utiliser `bundle update` *n*'est *pas* recommandé car les autres gemmes seront également mises à jour, ce qui n'est pas forcément le résultat voulu.
=== (c) Gestionnaire de paquets Linux
-==== Yum (Fedora 21 ou supérieure)
+==== DNF (Fedora 21 ou supérieure)
-Pour installer la gem sur Fedora 21 ou supérieure en utilisant yum, ouvrez un terminal et tapez :
+Pour installer la gemme sur Fedora 21 ou supérieure en utilisant dnf, ouvrez un terminal et tapez :
- $ sudo yum install -y asciidoctor
+ $ sudo dnf install -y asciidoctor
-Pour mettre à jour la gem, utilisez :
+Pour mettre à jour la gemme, utilisez :
- $ sudo yum update -y asciidoctor
+ $ sudo dnf update -y asciidoctor
-TIP: Votre système Fedora peut être configuré pour mettre à jour les paquets automatiquement, auquel cas aucune action de votre part ne sera nécessaire pour mettre à jour la gem.
+TIP: Votre système peut être configuré pour mettre à jour automatiquement les paquets rpm, auquel cas aucune action de votre part ne sera nécessaire pour mettre à jour la gemme.
-==== apt-get (Debian Sid, Ubuntu Saucy ou supérieure)
+==== apt-get (Debian, Ubuntu, Mint)
-Pour installer la gem sur Debian ou Ubuntu, ouvrez un terminal et tapez :
+Pour installer la gemme sur Debian, Ubuntu ou Mint, ouvrez un terminal et tapez :
$ sudo apt-get install -y asciidoctor
-Pour mettre à jour la gem, utilisez :
+Pour mettre à jour la gemme, utilisez :
$ sudo apt-get upgrade -y asciidoctor
-TIP: Votre système Debian ou Ubuntu peut être configuré pour mettre à jour les paquets automatiquement, auquel cas aucune action de votre part ne sera nécessaire pour mettre à jour la gem.
+TIP: Votre système peut être configuré pour mettre à jour automatiquement les paquets deb, auquel cas aucune action de votre part ne sera nécessaire pour mettre à jour la gemme.
+
+La version d'Asciidoctor installé par le gestionnaire de paquets (apt-get) peut ne pas correspondre à la dernière version d'Asciidoctor.
+Consultez le dépôt de paquets de votre distribution pour trouver quelle version est disponible par version de distribution.
+
+* https://packages.debian.org/search?keywords=asciidoctor&searchon=names&exact=1&suite=all§ion=all[Paquet asciidoctor par version de Debian]
+* http://packages.ubuntu.com/search?keywords=asciidoctor&searchon=names&exact=1&suite=all§ion=all[Paquet asciidoctor par version d'Ubuntu]
+* https://community.linuxmint.com/software/view/asciidoctor[Paquet asciidoctor par version de Mint]
+
+[CAUTION]
+====
+Il est déconseillé d'utiliser la commande `gem update` pour mettre à jour la gemme gérée par le gestionnaire de paquets.
+Le faire mettrait la système dans un état incohérent car le gestionnaire de paquets ne pourrait plus gérer les fichiers (qui sont installés dans /usr/local).
+En résumé, les gemmes du système doivent être gérées seulement par le gestionnaire de paquets.
+
+Si vous souhaitez utiliser une version d'Asciidoctor qui est plus récente que celle installée par votre gestionnaire de paquets, vous devriez utiliser http://rvm.io[RVM] pour installer Ruby dans votre répertoire personnel (dans votre espace utilisateur).
+Vous pouvez alors utiliser la commande `gem` pour installer ou mettre à jour la gemme Asciidoctor.
+En utilisant RVM, les gemmes sont installées dans un emplacement isolé du système.
+====
+
+==== apk (Alpine Linux)
+
+Pour installer la gemme sur Alpine Linux, ouvrez un terminal et tapez :
+
+ $ sudo apk add asciidoctor
+
+Pour mettre à jour la gemme, utilisez :
+
+ $ sudo apk add -u asciidoctor
+
+TIP: Votre système peut être configuré pour mettre à jour automatiquement les paquets apk, auquel cas aucune action de votre part ne sera nécessaire pour mettre à jour la gemme.
=== Autres options d'installation
-* {uri-install-doc}[Installation de l'outillage Asciidoctor]
+* {uri-install-docker}[Installation d'Asciidoctor avec Docker]
* {uri-install-osx-doc}[Installation d'Asciidoctor sur Mac OS X]
+// pour l'instant, l'entrée suivante est juste une répétition de l'information dans ce README
+//* {uri-install-doc}[Installation de l'outillage Asciidoctor]
== Utilisation
-Si la gem Asciidoctor s'est installée correctement, la ligne de commande (CLI) `asciidoctor` sera disponible dans votre PATH.
-Pour vérifier sa disponibilité, exécutez la commande suivante dans votre terminal :
+Si la gemme Asciidoctor s'est installée correctement, la ligne de commande (CLI) `asciidoctor` sera disponible dans votre PATH.
+Pour vérifier sa disponibilité, exécutez la commande suivante dans votre terminal :
$ asciidoctor --version
@@ -211,7 +262,7 @@ Vous devriez voir les informations concernant la version d'Asciidoctor et celle
[.output]
....
-Asciidoctor 1.5.3 [http://asciidoctor.org]
+Asciidoctor 1.5.4 [http://asciidoctor.org]
Runtime Environment (ruby 2.2.2p95 [x86_64-linux]) (lc:UTF-8 fs:UTF-8 in:- ex:UTF-8)
....
@@ -220,22 +271,22 @@ Cette API permet une intégration avec d'autres logiciels Ruby, comme Rails, Sin
=== Interface de Ligne de Commande (CLI)
-La commande `asciidoctor` vous permet d'invoquer Asciidoctor à partir de la ligne de commande (càd, un terminal).
+La commande `asciidoctor` vous permet d'invoquer Asciidoctor à partir de la ligne de commande (c'est-à-dire, un terminal).
-La commande suivante convertit le fichier README.adoc en HTML et sauvegarde le résultat dans le fichier README.html dans le même dossier.
+La commande suivante convertit le fichier README.adoc en HTML et sauvegarde le résultat dans le fichier README.html dans le même répertoire.
Le nom du fichier HTML généré est tiré de celui du fichier source, l'extension a été changée pour `.html`.
$ asciidoctor README.adoc
-Vous pouvez contrôler le processeur Asciidoctor en ajoutant plusieurs paramètres, vous pouvez en apprendre plus sur ces derniers en utilisant la commande :
+Vous pouvez contrôler le processeur Asciidoctor en ajoutant plusieurs paramètres, vous pouvez en apprendre plus sur ces derniers en utilisant la commande :
$ asciidoctor --help
-Par exemple, pour écrire le fichier dans un répertoire différent, utilisez :
+Par exemple, pour écrire le fichier dans un répertoire différent, utilisez :
$ asciidoctor -D output README.adoc
-Le {uri-manpage}[man page] `asciidoctor` fournit une référence complète sur l'interface de ligne de commande.
+La {uri-manpage}[page man] `asciidoctor` fournit une référence complète sur l'interface de ligne de commande.
Référez-vous aux ressources suivantes pour en apprendre davantage sur la façon d'utiliser la commande `asciidoctor`.
@@ -244,21 +295,21 @@ Référez-vous aux ressources suivantes pour en apprendre davantage sur la faço
=== API Ruby
-Pour utiliser Asciidoctor dans votre application, vous avez tout d'abord besoin de faire un require sur la gem :
+Pour utiliser Asciidoctor dans votre application, vous avez tout d'abord besoin de faire un « require » sur la gemme :
[source]
require 'asciidoctor'
-Vous pouvez ensuite convertir un fichier AsciiDoc en fichier HTML en utilisant :
+Vous pouvez ensuite convertir un fichier AsciiDoc en fichier HTML en utilisant :
[source]
Asciidoctor.convert_file 'README.adoc', to_file: true, safe: :safe
WARNING: Quand vous utilisez Asciidoctor via l'API, le mode de sûreté par défaut est `:secure`.
-Dans le mode secure, plusieurs fonctionnalités centrales sont désactivées, comme la directive `include`.
-Si vous souhaitez activer ces fonctionnalités, vous aurez besoin de définir explicitement le mode de sûreté avec une la valeur `:server` ou `:safe`.
+Dans le mode « secure », plusieurs fonctionnalités centrales sont désactivées, comme la directive `include`.
+Si vous souhaitez activer ces fonctionnalités, vous aurez besoin de définir explicitement le mode de sûreté avec une la valeur `:server` (recommandée) ou `:safe`.
-Vous pouvez aussi convertir une chaîne de texte en fragment HTML (pour une insertion dans une page HTML) en utilisant :
+Vous pouvez aussi convertir une chaîne de texte en fragment HTML (pour une insertion dans une page HTML) en utilisant :
[source]
----
@@ -266,7 +317,7 @@ content = '_Zen_ in the art of writing http://asciidoctor.org[AsciiDoc].'
Asciidoctor.convert content, safe: :safe
----
-Si vous voulez le document HTML complet, activez l'option `header_footer` comme ci-dessous :
+Si vous voulez le document HTML complet, activez l'option `header_footer` comme ci-dessous :
[source]
----
@@ -274,7 +325,7 @@ content = '_Zen_ in the art of writing http://asciidoctor.org[AsciiDoc].'
html = Asciidoctor.convert content, header_footer: true, safe: :safe
----
-Si vous avez besoin d'accèder au document analysé, vous pouvez séparer la conversion en deux étapes distinctes :
+Si vous avez besoin d'accéder au document analysé, vous pouvez séparer la conversion en deux étapes distinctes :
[source]
----
@@ -284,10 +335,10 @@ puts document.doctitle
html = document.convert
----
-Gardez en tête que si vous n'aimez pas le contenu généré par Asciidoctor, _vous pouvez le changer !_
-Asciidoctor supporte des convertisseurs personnalisés qui peuvent prendre en charge la conversion du document analysé vers un contenu généré.
+Gardez en tête que si vous n'aimez pas le contenu généré par Asciidoctor, _vous pouvez le changer !_
+Asciidoctor supporte des convertisseurs personnalisés qui peuvent prendre en charge la conversion depuis le document analysé jusqu'au contenu généré.
-Une façon simple de personnaliser les morceaux de contenu généré est d'utiliser le convertisseur de template.
+Une façon simple de personnaliser les morceaux de contenu générés est d'utiliser le convertisseur de template.
Le convertisseur de template vous permet, en utilisant un template supporté par {uri-tilt}[Tilt], de prendre en charge la conversion de n'importe quel élément dans le document.
Vous l'aurez compris, vous _pouvez_ complètement prendre le contrôle sur le contenu généré.
@@ -296,10 +347,10 @@ Pour plus d'informations sur comment utiliser l'API ou personnaliser le contenu
== Contributions
Dans l'esprit du {uri-freesoftware}[logiciel libre], _tout le monde_ est encouragé à aider en vue d'améliorer le projet.
-Si vous découvrez des erreurs ou des oublis dans le code source, la documentation, ou le contenu du site web, s'il vous plaît n'hésitez pas à ouvrir un ticket ou une pull request avec un correctif.
-Les contributeurs et contributrices sont toujours les bienvenus !
+Si vous découvrez des erreurs ou des oublis dans le code source, la documentation, ou le contenu du site web, s'il vous plaît n'hésitez pas à ouvrir un ticket ou une « pull request » avec un correctif.
+Les contributeurs et contributrices sont toujours les bienvenus !
-Voici quelques façons de contribuer :
+Voici quelques façons de contribuer :
* en utilisant les versions prerelease (alpha, beta ou preview),
* en rapportant des anomalies,
@@ -310,7 +361,7 @@ Voici quelques façons de contribuer :
** corriger une coquille,
** ajouter des commentaires,
** nettoyer des espaces inutiles,
-** écrire des tests !
+** écrire des tests !
* en refactorant le code,
* en corrigeant des {uri-issues}[anomalies],
* en effectuant des relectures des patches.
@@ -320,30 +371,32 @@ Le guide du {uri-contribute}[parfait Contributeur] fournit des informations sur
== Être aidé
Le projet Asciidoctor est développé pour vous aider à écrire et publier du contenu.
-Mais nous ne pouvons pas le faire sans avoir vos avis !
-Nous vous encourageons à poser vos questions et discuter de n'importe quels aspects du projet sur la liste de discussion, Twitter ou IRC.
+Mais nous ne pouvons pas le faire sans avoir vos avis !
+Nous vous encourageons à poser vos questions et discuter de n'importe quels aspects du projet sur la liste de discussion, Twitter ou dans le salon de discussion.
Mailing list:: {uri-discuss}
-Twitter (Chat):: hashtag #asciidoctor
+Twitter (Chat):: hashtag #asciidoctor ou la mention @asciidoctor
Gitter (Chat):: image:https://badges.gitter.im/Join%20In.svg[Gitter, link=https://gitter.im/asciidoctor/asciidoctor]
+////
IRC (Chat):: {uri-irc}[#asciidoctor] sur FreeNode IRC
+////
ifdef::env-github[]
-De plus amples informations et documentation sur Asciidoctor peuvent être trouvé sur le site web du projet.
+De plus amples informations et documentations sur Asciidoctor peuvent être trouvées sur le site web du projet.
{uri-project}/[Home] | {uri-news}[News] | {uri-docs}[Docs]
endif::[]
L'organisation Asciidoctor sur GitHub héberge le code source du projet, le gestionnaire de tickets ainsi que des sous-projets.
-Repository des sources (git):: {uri-repo}
+Dépôt des sources (git):: {uri-repo}
Gestionnaire de tickets:: {uri-issues}
L'organisation Asciidoctor sur GitHub:: {uri-org}
== Copyright et licence
Copyright (C) 2012-2016 Dan Allen, Ryan Waldron et le projet Asciidoctor.
-Une utilisation libre de ce logiciel est autorisé sous les termes de la licence MIT.
+Une utilisation libre de ce logiciel est autorisée sous les termes de la licence MIT.
Consultez le fichier {uri-license}[LICENSE] pour plus de détails.
diff --git a/README-jp.adoc b/README-jp.adoc
new file mode 100644
index 0000000..b698626
--- /dev/null
+++ b/README-jp.adoc
@@ -0,0 +1,395 @@
+= Asciidoctor
+Dan Allen <https://github.com/mojavelinux[@mojavelinux]>; Sarah White <https://github.com/graphitefriction[@graphitefriction]>; Ryan Waldron <https://github.com/erebor[@erebor]>
+// settings:
+:page-layout: base
+:idprefix:
+:idseparator: -
+:source-language: ruby
+:language: {source-language}
+ifdef::env-github[:status:]
+// URIs:
+:uri-org: https://github.com/asciidoctor
+:uri-repo: {uri-org}/asciidoctor
+:uri-asciidoctorj: {uri-org}/asciidoctorj
+:uri-asciidoctorjs: {uri-org}/asciidoctor.js
+:uri-project: http://asciidoctor.org
+ifdef::env-site[:uri-project: link:]
+:uri-docs: {uri-project}/docs
+:uri-news: {uri-project}/news
+:uri-manpage: {uri-project}/man/asciidoctor
+:uri-issues: {uri-repo}/issues
+:uri-contributors: {uri-repo}/graphs/contributors
+:uri-rel-file-base: link:
+:uri-rel-tree-base: link:
+ifdef::env-site[]
+:uri-rel-file-base: {uri-repo}/blob/master/
+:uri-rel-tree-base: {uri-repo}/tree/master/
+endif::[]
+:uri-changelog: {uri-rel-file-base}CHANGELOG.adoc
+:uri-contribute: {uri-rel-file-base}CONTRIBUTING.adoc
+:uri-license: {uri-rel-file-base}LICENSE.adoc
+:uri-tests: {uri-rel-tree-base}test
+:uri-discuss: http://discuss.asciidoctor.org
+:uri-irc: irc://irc.freenode.org/#asciidoctor
+:uri-rubygem: https://rubygems.org/gems/asciidoctor
+:uri-what-is-asciidoc: {uri-docs}/what-is-asciidoc
+:uri-user-manual: {uri-docs}/user-manual
+:uri-install-docker: https://github.com/asciidoctor/docker-asciidoctor
+//:uri-install-doc: {uri-docs}/install-toolchain
+:uri-install-osx-doc: {uri-docs}/install-asciidoctor-macosx
+:uri-render-doc: {uri-docs}/render-documents
+:uri-themes-doc: {uri-docs}/produce-custom-themes-using-asciidoctor-stylesheet-factory
+:uri-gitscm-repo: https://github.com/git/git-scm.com
+:uri-prototype: {uri-gitscm-repo}/commits/master/lib/asciidoc.rb
+:uri-freesoftware: https://www.gnu.org/philosophy/free-sw.html
+:uri-foundation: http://foundation.zurb.com
+:uri-tilt: https://github.com/rtomayko/tilt
+:uri-ruby: https://ruby-lang.org
+// images:
+:image-uri-screenshot: https://raw.githubusercontent.com/asciidoctor/asciidoctor/master/screenshot.png
+
+{uri-project}/[Asciidoctor]は _高速な_ テキストプロセッサで {uri-what-is-asciidoc}[Asciidoc] をHTML5, DocBook 5(4.5)や他のフォーマットに変換するツールチェインを配布しています.
+AsciidoctorはRubyで書かれており, RubyGemとしてパッケージされ, {uri-rubygem}[RubyGems.org] で配布されています.
+gemはいくつかのLinuxディストリビューション, Fedora, Debian, Ubuntuにも含まれています.
+Asciidoctorはオープンソース {uri-repo}[hosted on Github] で {uri-license}[the MIT licence]のもとに配布されます.
+
+ifndef::env-site[]
+.Translations of the document are available in the following languages:
+* {uri-rel-file-base}README-zh_CN.adoc[汉语]
+* {uri-rel-file-base}README.adoc[English]
+* {uri-rel-file-base}README-fr.adoc[Français]
+endif::[]
+
+.Key documentation
+[.compact]
+* {uri-docs}/what-is-asciidoc[What is Asciidoc?]
+* {uri-docs}/asciidoc-writers-guide[AsciiDoc Writer's Guide]
+* {uri-docs}/asciidoc-syntax-quick-reference[AsciiDoc Syntax Reference]
+* {uri-docs}/user-manual[Asciidoctor User Manual]
+
+.Rubyの行く先, Asciidoctorの追うところ
+****
+AsciidoctorはJRubyを用いてJVM上でも実行できます.
+Javaや他のJVM言語からAsciidoctor APIを直接呼び出すには, {uri-asciidoctorj}[AsciidoctorJ] を使ってください.
+AsciidoctorJに基づいた, AsciidoctorプロセッサをApache Maven, GradleやJavadocに統合するプラグインがあります.
+
+AsciidoctorはJavaScriptでも実行可能です.
+{uri-asciidoctorjs}[Asciidoctor.js], WebブラウザやNode.jsのようなJavaScript環境で動くAsciidoctorの完全機能版, を生成するために, RubyのソースをJavaScriptにトランスパイルするのに http://opalrb.org[Opal]を使います.
+Asciidoctor.jsはChrome, Atom, Brackets や他のウェブベースのツールの拡張機能としてAsciiDocのプレビューのために使われます.
+****
+
+ifdef::status[]
+.*Project health*
+image:https://img.shields.io/travis/asciidoctor/asciidoctor/master.svg[Build Status (Travis CI), link=https://travis-ci.org/asciidoctor/asciidoctor]
+image:https://ci.appveyor.com/api/projects/status/ifplu67oxvgn6ceq/branch/master?svg=true&passingText=green%20bar&failingText=%23fail&pendingText=building%2E%2E%2E[Build Status (AppVeyor), link=https://ci.appveyor.com/project/asciidoctor/asciidoctor]
+//image:https://img.shields.io/coveralls/asciidoctor/asciidoctor/master.svg[Coverage Status, link=https://coveralls.io/r/asciidoctor/asciidoctor]
+image:https://codeclimate.com/github/asciidoctor/asciidoctor/badges/gpa.svg[Code Climate, link="https://codeclimate.com/github/asciidoctor/asciidoctor"]
+image:https://inch-ci.org/github/asciidoctor/asciidoctor.svg?branch=master[Inline docs, link="https://inch-ci.org/github/asciidoctor/asciidoctor"]
+endif::[]
+
+== The Big Picture
+
+Asciidoctorは下図の左側のパネルに示されるように, 平文で書かれた内容を読み, 右のパネルに描かれるようにHTML5に変換します.
+Asciidoctorは枠にとらわれない快適なエクスペリエンスのためにデフォルトスタイルシートをHTML5時メントに適用します.
+
+image::{image-uri-screenshot}[Preview of AsciiDoc source and corresponding rendered HTML]
+
+== AsciiDoc Processing
+AsciidoctorはAsciiDoc文法で書かれたテキストを読み込み解釈し, それからHTML5, DocBook5(4.5)やman(ual)を出力するために内蔵コンバータセットにパースツリーを渡します.
+生成された出力をカスタマイズ, あるいは追加のフォーマットをつくるためにあなた自身のコンバータを使うことや {uri-tilt}[Tilt]-supported テンプレートを読み込むオプションがあります.
+
+NOTE: AsciidoctorはオリジナルのAsciiDoc Pythonプロセッサ(`asciidoc.py`)の完全互換です.
+Asciidoctorテストスイートは {uri-tests}[> 1,600 tests] をAsciiDoc文法との互換性を保証するために有しています.
+
+クラシックなAsciiDoc文法に加えて, Asciidoctorは追加のマークアップとフォントベースのicons(例えば, `+icon:fire[]+`)などのフォーマッティングオプションとUIエレメント(`+button:[Save]+`)を 受け付けます.
+AsciidoctorはHTML5出力をスタイルするため, モダンで, {uri-foundation}[Foundation] に基づいたレスポンシブテーマをも提供します.
+
+== Requirements
+
+AsciidoctorはLinux, OS X (Mac)とWindowsで動き, 下記の {uri-ruby}[Ruby]実装の一つを必要とします.
+
+* MRI (Ruby 1.8.7, 1.9.3, 2.0, 2.1, 2.2 & 2.3)
+* JRuby (1.7 in Ruby 1.8 and 1.9 modes, 9000)
+* Rubinius 2.2.x
+* Opal (JavaScript)
+
+[CAUTION]
+====
+もし非英語環境のWindowsを使っているなら, Asciidoctorを起動した時に`Encoding::UndefinedConversionError`に遭遇するでしょう.
+これを解決するには使っているコンソールの有効なコードページをUTF-8:
+
+ chcp 65001
+
+に変更することを推奨します.
+一度この変更をすると, Unicode関連の頭痛の種は消えるでしょう.
+もしEclipseのようなIDEを使っているなら, 同様にエンコーディングをUTF-8にするのを忘れないでください.
+AsciidoctorはUTF-8が使われているところで最高の働きを見せます.
+====
+
+== Installation
+
+Asciidoctorは (a) `gem install` コマンド, (b) Bundler あるいは (c) 有名Linuxディストリビューションのパッケージマネージャ を用いてインストールされます.
+
+TIP: Linuxパッケージマネージャを用いてインストールすることの利点は, もしRubyやRubyGemsライブラリがまだインストールされていなかったら, それらを処理してくれることです.
+欠点はgemのリリース直後にはすぐには有効にならないことです.
+もし最新バージョンを使いたければ, 必ず `gem` コマンドを使いましょう.
+
+=== (a) gem install
+
+ターミナルを開, 入力しましょう (先頭の`$`は除く):
+
+ $ gem install asciidoctor
+
+もし, 先行リリースバージョン(例えばリリース候補版)をインストールしたければ
+
+ $ gem install asciidoctor --pre
+
+.アップグレード
+[TIP]
+====
+もしAsciidoctorの以前のバージョンあインストール済みであれば, 以下によってアップデートできます:
+
+ $ gem update asciidoctor
+
+もし gem update の代わりに `gem install` を使ってgemを新バージョンにした場合, 複数バージョンばインストールされるでしょう.
+そのときは, 以下のgemコマンドで古いバージョンを削除しましょう:
+
+ $ gem cleanup asciidoctor
+====
+
+=== (b) Bundler
+
+. プロジェクトフォルダーのルート(かカレントディレクトリ)にGemfileを作成
+. `asciidoctor` gemをGemfileに以下のように追加:
++
+[source]
+----
+source 'https://rubygems.org'
+gem 'asciidoctor'
+# or specify the version explicitly
+# gem 'asciidoctor', '1.5.4'
+----
+
+. Gemfileを保存
+. ターミナルを開き, gemをインストール:
+
+ $ bundle
+
+gemをアップグレードするには, Gemfileで新バージョンを指定し, `bundle` を再び実行してください.
+`bundle update` は他のgemもアップデートするため推奨されて *いない* ので, 思わぬ結果になるかも知れません.
+
+=== (c) Linux package managers
+
+==== DNF (Fedora 21 or greater)
+
+dnfを使いFedora21かそれ以上にインストールするには, ターミナルを開き, 以下を入力してください:
+
+ $ sudo dnf install -y asciidoctor
+
+gemをアップグレードするには:
+
+ $ sudo dnf update -y asciidoctor
+
+TIP: お使いのシステムは自動的にrpmパッケージをアップデートするよう設定されているかも知れません.その場合, gemのアップデートのためにあなたがすべきことはありません.
+
+==== apt-get (Debian, Ubuntu, Mint)
+
+Debian, UbuntuまたはMintにインストールするには, ターミナルを開き, 以下を入力してください:
+
+ $ sudo apt-get install -y asciidoctor
+
+gemをアップグレードするには:
+
+ $ sudo apt-get upgrade -y asciidoctor
+
+TIP: お使いのシステムは自動的にdebパッケージをアップデートするよう設定されているかも知れません.その場合, gemのアップデートのためにあなたがすべきことはありません.
+
+パッケージマネージャ(apt-get)によってインストールされたバージョンのAsciidoctorは最新リリースのAsciidoctorではないかもしれません.
+ディストリビューションのリリース毎に, どのバージョンがパッケージされているかはパッケージリポジトリを調べてください.
+
+* https://packages.debian.org/search?keywords=asciidoctor&searchon=names&exact=1&suite=all§ion=all[asciidoctor package by Debian release]
+* http://packages.ubuntu.com/search?keywords=asciidoctor&searchon=names&exact=1&suite=all§ion=all[asciidoctor package by Ubuntu release]
+* https://community.linuxmint.com/software/view/asciidoctor[asciidoctor package by Mint release]
+
+[CAUTION]
+====
+パッケージマネージャによって管理されているgemをアップデートするのに `gem udpate` コマンドを使うなといわれるでしょう.
+そのようなことをするのは, パッケージマネージャがファイル(/usr/local下にインストールされた)を追跡できなくなるためにシステムが不安定な状態にするためです.
+単純に, システムgemはパッケージマネージャによってのみ管理されるべきです.
+
+もし, パッケージマネージャによってインストールされたのより新しいバージョンのAsciidoctorを使いたければ, http://rvm.io[RVM] や https://github.com/rbenv/rbenv[rbenv]を使ってRubyをホームディレクトリ(すなわち, ユーザースペース)にインストールするべきです.
+それから, 安心して `gem` コマンドをAsciidoctorのアップデート, インストールのために使うことができます.
+RVMやrbenvを使っているなら, gemはシステムからは孤立した場所にインストールされます.
+====
+
+==== apk (Alpine Linux)
+
+Alpine Linuxにgemをインストールするには, ターミナルを開き, 以下を入力してください:
+
+ $ sudo apk add asciidoctor
+
+gemをアップグレードするには:
+
+ $ sudo apk add -u asciidoctor
+
+TIP: お使いのシステムは自動的にapkパッケージをアップデートするよう設定されているかも知れません.その場合, gemのアップデートのためにあなたがすべきことはありません.
+
+=== Other installation options
+
+* {uri-install-docker}[Installing Asciidoctor using Docker]
+* {uri-install-osx-doc}[Installing Asciidoctor on Mac OS X]
+// at the moment, the following entry is just a reiteration of the information in this README
+//* {uri-install-doc}[Installing the Asciidoctor toolchain]
+
+== Usage
+
+Asciidoctorのインストールに成功すれば, `asciidoctor` コマンドラインインターフェース(CLI)がPATH中で有効になります.
+確認のために, 以下をターミナルで実行しましょう:
+
+ $ asciidoctor --version
+
+AsciidoctorのバージョンとRuby環境についての情報がターミナルに出力されたのを見ることができるはずです.
+
+[.output]
+....
+Asciidoctor 1.5.4 [http://asciidoctor.org]
+Runtime Environment (ruby 2.2.2p95 [x86_64-linux]) (lc:UTF-8 fs:UTF-8 in:- ex:UTF-8)
+....
+
+AsciidoctorはAPIを提供します.
+APIは他のRubyソフトウェア, Rails, SinatraとGitHub, そして他の言語, Java (via {uri-asciidoctorj}[AsciidoctorJ] )とJavaScript (via {uri-asciidoctorjs}[Asciidoctor.js])との統合を意図しています.
+
+=== Command line interface (CLI)
+
+`asciidoctorjs` コマンドはAsciidoctorをコマンドライン(つまりターミナル)から起動することを可能にします.
+
+次のコマンドはファイルREADME.adocをHTMLに変換し, 結果を同じディレクトリのREADME.htmlに保存します.
+生成されたHTMLファイルの名前はソースファイル依存し, その拡張子を `.html` に変えます.
+
+ $ asciidoctor README.adoc
+
+Asciidoctorプロセッサに様々なフラグやスイッチを与えることで制御できます.それは以下を用いて調べることができます:
+
+ $ asciidoctor --help
+
+例えば, ファイルを異なるディレクトリに書き出すには:
+
+ $ asciidoctor -D output README.adoc
+
+`asciidoctor` {uri-manpage}[man page] はコマンドライン・インタフェースの完全なリファレンスを提供します.
+
+`asciidoctor` コマンドの使い方についてもっと学ぶには以下を参照してください.
+
+* {uri-render-doc}[How do I convert a document?]
+* {uri-themes-doc}[How do I use the Asciidoctor stylesheet factory to produce custom themes?]
+
+=== Ruby API
+
+Asciidoctorをアプリケーションの中で使うには, まずgemをrequireする必要があります:
+
+[source]
+require 'asciidoctor'
+
+それから, AsciiDocソースファイルをHTMLファイルに変換できます:
+
+[source]
+Asciidoctor.convert_file 'README.adoc', to_file: true, safe: :safe
+
+WARNING: AsciidoctorをAPI経由で使っている時, デフォルトのセーフモードは `:secure` です.
+セキュアモードでは, `include` ディレクティブを含むいくつかのコア機能は無効化されています.
+もしこれらの機能を有効化したい場合, 明示的にセーフモードを `:server` (推奨)か `:safe` にする必要があります.
+
+AsciiDoc文字列を埋め込みHTML(HTMLページヘの挿入)へ変換することもできます:
+
+[source]
+----
+content = '_Zen_ in the art of writing http://asciidoctor.org[AsciiDoc].'
+Asciidoctor.convert content, safe: :safe
+----
+
+もし完全なHTMLドキュメントを求めるのであれば, `header_footer` オプションを以下の通り有効にしてください:
+
+[source]
+----
+content = '_Zen_ in the art of writing http://asciidoctor.org[AsciiDoc].'
+html = Asciidoctor.convert content, header_footer: true, safe: :safe
+----
+
+パースされたドキュメントにアクセスしたいのなら, 変換を個々のステップに分割することが出来ます:
+
+[source]
+----
+content = '_Zen_ in the art of writing http://asciidoctor.org[AsciiDoc].'
+document = Asciidoctor.load content, header_footer: true, safe: :safe
+puts document.doctitle
+html = document.convert
+----
+
+Asciidoctorの生成する出力が気に入らないのであれば, _あなたはそれを変更できる_ ことを忘れないでください!
+Asciidoctorはパースされたドキュメントを生成された出力に変換する処理を扱うカスタムコンバーターをサポートしています.
+
+断片的な出力をカスタマイズする簡単な方法の一つはテンプレートコンバーターを使うことです.
+テンプレートコンバーターによって, ドキュメント中のあらゆるノードの変換を扱うために {uri-tilt}[Tilt]-supportedテンプレートファイルを使うことができます.
+
+そのようにすれば, 出力を100%制御することが _できます_ .
+APIの使い方や出力のカスタマイズ方法についてのより詳しい情報は {uri-user-manual}[user manual] を参照してください.
+
+== Contributing
+
+{uri-freesoftware}[free software] の精神においては, _everyone_ がこのプロジェクトを改良するのをたすけることが勧められている.
+もしエラーや手抜かりをソースコード, ドキュメント, あるいはウェブサイトに見つけたのなら, 恥じることなく修正と共にpull requestの開設やissueの送信をしてください.
+New contributors are always welcome!
+
+*あなた* にもできることがあります:
+
+* 先行バージョン(alpha, beta or preview)の使用
+* バグレポート
+* 新機能提案
+* ドキュメントの執筆
+* 仕様の執筆
+* コーディング -- _パッチでも, 足りなすぎるなんてことはありません_
+** typoの修正
+** コメントの追加
+** 一貫性のないホワイトスペースの除去
+** テストの記述!
+* リファクタリング
+* {uri-issues}[issues] の修正
+* パッチの批評
+
+{uri-contribute}[Contributing] ガイドはどうやってスタイルをつくるか, issueを送るか, 機能リクエスト, コーディング, ドキュメンテーションをAsciidoctor Projectにするかの情報を提供しています.
+
+== Getting Help
+
+Asciidoctorプロジェクトはあなたが簡単に著作を書いて, 配布するのをたすけるため開発されています.
+しかしあなたのフィードバックなしにはできません!
+ディスカッションリストで, Twitterで, チャットルームで, 質問し, プロジェクトのあらゆる側面について話し合うようお勧めします.
+
+Discussion list (Nabble):: {uri-discuss}
+Twitter:: #asciidoctor hashtag or @asciidoctor mention
+Chat (Gitter):: image:https://badges.gitter.im/Join%20In.svg[Gitter, link=https://gitter.im/asciidoctor/asciidoctor]
+
+ifdef::env-github[]
+Further information and documentation about Asciidoctor can be found on the project's website.
+
+{uri-project}/[Home] | {uri-news}[News] | {uri-docs}[Docs]
+endif::[]
+
+GitHub上のAsciidoctorはプロジェクトのソースコード, イシュートラッカー, サブプロジェクトを管理しています.
+
+Source repository (git):: {uri-repo}
+Issue tracker:: {uri-issues}
+Asciidoctor organization on GitHub:: {uri-org}
+
+== Copyright and Licensing
+
+Copyright (C) 2012-2016 Dan Allen, Ryan Waldron and the Asciidoctor Project.
+Free use of this software is granted under the terms of the MIT License.
+
+See the {uri-license}[LICENSE] file for details.
+
+== Authors
+
+*Asciidoctor* is led by https://github.com/mojavelinux[Dan Allen] and https://github.com/graphitefriction[Sarah White] and has received contributions from {uri-contributors}[many other individuals] in Asciidoctor's awesome community.
+The project was initiated in 2012 by https://github.com/erebor[Ryan Waldron] and based on {uri-prototype}[a prototype] written by https://github.com/nickh[Nick Hengeveld].
+
+*AsciiDoc* was started by Stuart Rackham and has received contributions from many other individuals in the AsciiDoc community.
diff --git a/README-zh_CN.adoc b/README-zh_CN.adoc
new file mode 100644
index 0000000..75f287d
--- /dev/null
+++ b/README-zh_CN.adoc
@@ -0,0 +1,414 @@
+= Asciidoctor
+Dan Allen <https://github.com/mojavelinux[@mojavelinux]>; Sarah White <https://github.com/graphitefriction[@graphitefriction]>; Ryan Waldron <https://github.com/erebor[@erebor]>
+// settings:
+:page-layout: base
+:idprefix:
+:idseparator: -
+:source-language: ruby
+:language: {source-language}
+ifdef::env-github[:status:]
+// URIs:
+:uri-org: https://github.com/asciidoctor
+:uri-repo: {uri-org}/asciidoctor
+:uri-asciidoctorj: {uri-org}/asciidoctorj
+:uri-asciidoctorjs: {uri-org}/asciidoctor.js
+:uri-project: http://asciidoctor.org
+ifdef::env-site[:uri-project: link:]
+:uri-docs: {uri-project}/docs
+:uri-news: {uri-project}/news
+:uri-manpage: {uri-project}/man/asciidoctor
+:uri-issues: {uri-repo}/issues
+:uri-contributors: {uri-repo}/graphs/contributors
+:uri-rel-file-base: link:
+:uri-rel-tree-base: link:
+ifdef::env-site[]
+:uri-rel-file-base: {uri-repo}/blob/master/
+:uri-rel-tree-base: {uri-repo}/tree/master/
+endif::[]
+:uri-changelog: {uri-rel-file-base}CHANGELOG.adoc
+:uri-contribute: {uri-rel-file-base}CONTRIBUTING.adoc
+:uri-license: {uri-rel-file-base}LICENSE.adoc
+:uri-tests: {uri-rel-tree-base}test
+:uri-discuss: http://discuss.asciidoctor.org
+:uri-irc: irc://irc.freenode.org/#asciidoctor
+:uri-rubygem: https://rubygems.org/gems/asciidoctor
+:uri-what-is-asciidoc: {uri-docs}/what-is-asciidoc
+:uri-user-manual: {uri-docs}/user-manual
+:uri-install-docker: https://github.com/asciidoctor/docker-asciidoctor
+//:uri-install-doc: {uri-docs}/install-toolchain
+:uri-install-osx-doc: {uri-docs}/install-asciidoctor-macosx
+:uri-render-doc: {uri-docs}/render-documents
+:uri-themes-doc: {uri-docs}/produce-custom-themes-using-asciidoctor-stylesheet-factory
+:uri-gitscm-repo: https://github.com/git/git-scm.com
+:uri-prototype: {uri-gitscm-repo}/commits/master/lib/asciidoc.rb
+:uri-freesoftware: https://www.gnu.org/philosophy/free-sw.html
+:uri-foundation: http://foundation.zurb.com
+:uri-tilt: https://github.com/rtomayko/tilt
+:uri-ruby: https://ruby-lang.org
+// images:
+:image-uri-screenshot: https://raw.githubusercontent.com/asciidoctor/asciidoctor/master/screenshot.png
+
+{uri-project}/[Asciidoctor] 是一个 _快速_ 文本处理器和发布工具链,它可以将 {uri-what-is-asciidoc}[AsciiDoc] 文档转化成 HTML5、 DocBook 5 (或 4.5) 以及其他格式。
+Asciidoctor 由 Ruby 编写,打包成 RubyGem,然后发布到 {uri-rubygem}[RubyGems.org] 上。
+这个 gem 还被包含道几个 Linux 发行版中,其中包括 Fedora、Debian 和 Ubuntu。
+Asciidoctor 是开源的,{uri-repo}[代码托管在 GitHub],并且是以 {uri-license}[MIT 协议]授权。
+
+.该文档有如下语言的翻译版:
+* {uri-rel-file-base}README.adoc[English]
+* {uri-rel-file-base}README-fr.adoc[Français]
+
+.关键文档
+[.compact]
+* {uri-docs}/what-is-asciidoc[什么是 Asciidoctor?]
+* {uri-docs}/asciidoc-writers-guide[AsciiDoc 作家指南]
+* {uri-docs}/asciidoc-syntax-quick-reference[AsciiDoc 语法快速参考]
+* {uri-docs}/user-manual[Asciidoctor 用户手册]
+
+.Ruby 所至, Asciidoctor 相随
+****
+使用 JRuby 可以让 Asciidoctor 运行在 Java 虚拟机上。
+使用 {uri-asciidoctorj}[AsciidoctorJ] 就可以让 Java 或者其他 Java 虚拟机语言直接调用 Asciidoctor API。
+基于 AsciidoctorJ 有好多好多插件可用,这些插件可以将 Asciidoctor 整合到 Apache Maven,Gradle 或 Javadoc 构建中。
+
+Asciidoctor 也可以运行在 JavaScript 上。
+我们可以使用 http://opalrb.org[Opal] 将 Ruby 源码编译成 JavaScript 并生成 {uri-asciidoctorjs}[Asciidoctor.js],这是一个全功能版的 Asciidoctor,可以运行在任意的 JavaScript 环境中,比如 Web 浏览器 或 Node.js。
+Asciidoctor.js 被用于 AsciiDoc 预览,支持 Chrome 扩展,Atom,Brackets 或其他基于 Web 的工具。
+****
+
+ifdef::badges[]
+.*Project health*
+image:https://img.shields.io/travis/asciidoctor/asciidoctor/master.svg[Build Status (Travis CI), link=https://travis-ci.org/asciidoctor/asciidoctor]
+image:https://ci.appveyor.com/api/projects/status/ifplu67oxvgn6ceq/branch/master?svg=true&passingText=green%20bar&failingText=%23fail&pendingText=building%2E%2E%2E[Build Status (AppVeyor), link=https://ci.appveyor.com/project/asciidoctor/asciidoctor]
+//image:https://img.shields.io/coveralls/asciidoctor/asciidoctor/master.svg[Coverage Status, link=https://coveralls.io/r/asciidoctor/asciidoctor]
+image:https://codeclimate.com/github/asciidoctor/asciidoctor/badges/gpa.svg[Code Climate, link="https://codeclimate.com/github/asciidoctor/asciidoctor"]
+image:https://inch-ci.org/github/asciidoctor/asciidoctor.svg?branch=master[Inline docs, link="https://inch-ci.org/github/asciidoctor/asciidoctor"]
+endif::[]
+
+[#the-big-picture]
+== 全局概况
+
+Asciidoctor 以纯文本格式读取内容,见下图左边的面板,将它转换成 HTML5 呈现在右侧面板中。
+Asciidoctor 将默认的样式表应用到 HTML5 文档上,提供一个愉快的开箱即用的体验。
+
+image::{image-uri-screenshot}[AsciiDoc 源文预览和相应的 HTML 渲染]
+
+[#asciidoc-processing]
+== AsciiDoc Processing
+
+Asciidoctor 读取并处理以 AsciiDoc 语法写作的文件,然后然后将解析出来的解析树交给内置的转化器生成 HTML5,DocBook 5 (或 4.5) 或帮助手册页面输出。
+你可以选择使用你自己的转化器或者加载 {uri-tilt}[Tilt] - 支持通过模板来自定义输出或产生附加的格式。
+
+NOTE: Asciidoctor是为了直接替换原 AsciiDoc Python 处理器(`asciidoc.py`)。
+Asciidoctor 测试套件含有 {uri-tests}[> 1,600 测试用例] 来确保和 AsciiDoc 语法的兼容性。
+
+除了经典的 AsciiDoc 语法,Asciidoctor 还添加额外的标记和格式设置选项,例如 font-based 图标(例如: `+icon:fire[]+`)和 UI 元素(例如: `+button:[Save]+`)。
+Asciidoctor 还提供了一个基于 {uri-foundation}[Foundation] 的现代的、响应式主题来美化 HTML5 输出。
+
+[#requirements]
+== 要求
+
+Asciidoctor 可以在 Linux,OSX (Mac) 和 Windows,并且需要下面其中一个 {uri-ruby}[Ruby] 实现:
+
+* MRI (Ruby 1.8.7, 1.9.3, 2.0, 2.1, 2.2 & 2.3)
+* JRuby (1.7 in Ruby 1.8 and 1.9 modes, 9000)
+* Rubinius 2.2.x
+* Opal (JavaScript)
+
+我们欢迎你来帮助在这些以及其他平台测试 Asciidoctor。
+参考 <<{idprefix}contributing,Contributing>> 来学习如何参与进来。
+
+[CAUTION]
+====
+如果你使用一个非英语的 Windows 环境,当调用 Asciidoctor 时,可能会碰到 `Encoding::UndefinedConversionError` 错误。
+为了解决这个问题,我们建议将控制台的编码更改为 UTF-8:
+
+ chcp 65001
+
+一旦你做了这个改变,所有的编码问题,都将迎刃而解。
+只要你在任何地方都是 UTF-8,Asciidoctor 总会工作地很好。
+====
+
+[#installation]
+== 安装
+
+Asciidoctor 可以通过三种方式安装:(a) 使用 `gem install` 命令;(b) 使用 Bundler;(c) 流行的 Linux 发行版的包管理器
+
+TIP: 使用 Linux 包管理器安装的好处是如果 Ruby 和 RubyGems 库没有在你的机器上安装,它会一并安装上去。
+不利的是在 gem 发布之后,这类安装包并不是立即可用。
+如果你需要最新版,你应该总是优先使用 `gem` 命令安装。
+
+[#a-gem-install]
+=== (a) gem 安装
+
+打开一个终端输入如下命令(不含开头的 `$`):
+
+ $ gem install asciidoctor
+
+如果想安装一个预览版(比如:候选发布版),请使用:
+
+ $ gem install asciidoctor --pre
+
+.升级
+[TIP]
+====
+如果你安装有一个旧版本的 Asciidoctor,你可以使用下面的命令来升级:
+
+ $ gem update asciidoctor
+
+如果使用 `gem install` 命令来安装一个新版本的 gem 来代替升级,则会安装多个版本。
+如果是这种情况,使用下面的 gem 命令来移除旧版本:
+
+ $ gem cleanup asciidoctor
+====
+
+[#b-bundler]
+=== (b) Bundler
+
+. 在项目的根目录(或者当前路径),创建一个 `Gemfile` 文件;
+. 在这个文件中添加 `asciidoctor` gem 如下:
++
+[source]
+----
+source 'https://rubygems.org'
+gem 'asciidoctor'
+# 或者明确指明版本
+# gem 'asciidoctor', '1.5.4'
+----
+
+. 保存 `Gemfile` 文件
+. 打开终端,使用如下命令安装 gem:
+
+ $ bundle
+
+要升级 gem 的话,在 `Gemfile` 文件中,指明新版本,然后再次运行 `bundle` 即可。
+*不推荐* 直接使用 `bundle update` 命令,因为它还会升级其他 gem,也许会造成不可预料的结果。
+
+[#c-linux-package-managers]
+=== (c) Linux 包管理
+
+[#dnf-fedora-21-or-greater]
+==== DNF (Fedora 21 或更高版本)
+
+在 Fedora 21 或更高版本中安装这个 gem,可以使用 dnf。打开终端并输入如下命令:
+
+ $ sudo dnf install -y asciidoctor
+
+升级则使用:
+
+ $ sudo dnf update -y asciidoctor
+
+TIP: 如果你的 Fedora 系统配置的是自动升级包,在这种情况下,不需要你亲自动手升级。
+
+[#apt-get-debian-ubuntu-mint]
+==== apt-get (Debian, Ubuntu, Mint)
+
+在 Debian,Ubuntu 或 Mint 中安装这个 gem,请打开终端并输入如下命令:
+
+ $ sudo apt-get install -y asciidoctor
+
+升级则使用:
+
+ $ sudo apt-get upgrade -y asciidoctor
+
+TIP: 如果你的 Debian 或 Ubuntu 系统配置的是自动升级包,在这种情况下,不需要你亲自动手升级。
+
+使用包管理器( apt-get )安装的 Asciidoctor 的版本也许不是最新发布版。
+请查看发行版的包库,来确定每个发行版是打包的哪个版本。
+
+* https://packages.debian.org/search?keywords=asciidoctor&searchon=names&exact=1&suite=all§ion=all[Debian 发行版中的 asciidoctor]
+* http://packages.ubuntu.com/search?keywords=asciidoctor&searchon=names&exact=1&suite=all§ion=all[Ubuntu 发行版中的 asciidoctor]
+* https://community.linuxmint.com/software/view/asciidoctor[Mint 发行版中的 asciidoctor]
+
+[CAUTION]
+====
+我们建议不要使用 `gem update` 来升级包管理的 gem。
+这样做会使系统进入不一致的状态,包管理工具将不再跟踪相关文件(通常安装在 /usr/local 下。)
+简单地说,系统的 gem 只能由包管理器进行管理。
+
+如果你想使用一个比包管理器安装的更新版本的 Asciidoctor,你应该使用 http://rvm.io[RVM] 在你的用户家目录(比如:用户空间)下安装 Ruby。
+然后,你就可以放心地使用 `gem` 命令来安装或者更新 Asciidoctor gem。
+当使用 RVM 时,gem 将被安装到与系统隔离的位置。
+====
+
+[#apk-alpine-linux]
+==== apk (Alpine Linux)
+
+在 Alpine Linux 中安装这个 gem,请打开终端并输入如下命令:
+
+ $ sudo apk add asciidoctor
+
+升级则使用:
+
+ $ sudo apk add -u asciidoctor
+
+TIP: 如果你的 Alpine Linux 系统配置的是自动升级包,在这种情况下,不需要你亲自动手升级。
+
+[#other-installation-options]
+=== 其他安装选项
+
+* {uri-install-docker}[使用 Docker 安装 Asciidoctor ]
+* {uri-install-osx-doc}[在 Mac OS X 安装 Asciidoctor ]
+
+[#usage]
+== 使用
+
+如果成功安装 Asciidoctor,则在可执行程序路径中,`asciidoctor` 就可用了。
+为了验证它的可用性,你可以在终端中执行如下命令:
+
+ $ asciidoctor --version
+
+你应该看到关于 Asciidoctor 和 Ruby 环境信息将打印到你的终端上。
+
+[.output]
+....
+Asciidoctor 1.5.4 [http://asciidoctor.org]
+Runtime Environment (ruby 2.2.2p95 [x86_64-linux]) (lc:UTF-8 fs:UTF-8 in:- ex:UTF-8)
+....
+
+Asciidoctor 还提供了一套 API。
+这套 API 是为了整合其他的 Ruby 软件,例如 Rails、Sinatra、Github,甚至其他语言,比如 Java (通过 {uri-asciidoctorj}[AsciidoctorJ]) 和 JavaScript (通过 {uri-asciidoctorjs}[Asciidoctor.js])。
+
+[#command-line-interface-cli]
+=== 命令行(CLI)
+
+`asciidoctor` 命令可以让你通过命令行(比如:终端)来调用 Asciidoctor。
+
+下面的命令将 README.adoc 文件转化为 HTML,并且保存到同一目录下的 README.html 文件中。
+生成的 HTML 文件名源自源文件名,只是将其扩展名改为了 `.html`。
+
+ $ asciidoctor README.adoc
+
+您可以通过添加各种标志和开关控制 Asciidoctor 处理器,通过下面的命令你可以学习它的更多用法:
+
+ $ asciidoctor --help
+
+比如,将文件写入到不同路径里,使用如下命令:
+
+ $ asciidoctor -D output README.adoc
+
+`asciidoctor` {uri-manpage}[帮助页面] 提供了这个命令的完整参考。
+
+点击下面的资源,学习更多关于 `asciidoctor` 命令的用法。
+
+* {uri-render-doc}[如何转化文档?]
+* {uri-themes-doc}[如何使用 Asciidoctor 样式工厂来创建自定义主题?]
+
+[#ruby-api]
+=== Ruby API
+
+为了在你应用中使用 Asciidoctor,首先需要引入这个 gem:
+
+[source]
+require 'asciidoctor'
+
+然后,你可以通过下面的代码将 AsciiDoc 源文件转化成一个 HTML 文件:
+
+[source]
+Asciidoctor.convert_file 'README.adoc', to_file: true, safe: :safe
+
+WARNING: 当你通过 API 使用 Asciidoctor 时,默认的安全模式是 `:secure`。
+在 secure 模式下,很多核心特性将不可用,包括 `include` 特性。
+如果你想启用这些特性,你需要明确设置安全模式为 `:server` (推荐)或 `:safe`。
+
+你也可以将 AsciiDoc 字符串转化我内嵌的 HTML (为了插入到一个 HTML 页面),用法如下:
+
+[source]
+----
+content = '_Zen_ in the art of writing http://asciidoctor.org[AsciiDoc].'
+Asciidoctor.convert content, safe: :safe
+----
+
+如果你想得到完整的 HTML 文档,只需要启用 `header_footer` 选项即可。如下:
+
+[source]
+----
+content = '_Zen_ in the art of writing http://asciidoctor.org[AsciiDoc].'
+html = Asciidoctor.convert content, header_footer: true, safe: :safe
+----
+
+如果你想访问已经处理过的文档,可以将转化过程拆分成离散的几步:
+
+[source]
+----
+content = '_Zen_ in the art of writing http://asciidoctor.org[AsciiDoc].'
+document = Asciidoctor.load content, header_footer: true, safe: :safe
+puts document.doctitle
+html = document.convert
+----
+
+请注意:如果你不喜欢 Asciidoctor 输出结果,_你完全可以改变它。_
+Asciidoctor 支持自定义转化器,它可以操作从待处理文件到生成文档整个环节。
+
+一个简单的、细微地自定义输出的方式是使用模板转化器。
+模板转化器运行你提供一个 {uri-tilt}[Tilt] 模板,这样通过模板文件来操作转化出的文档的每个节点。
+
+这样,你就 _可以_ 百分之百地控制你的输出。
+关于更多关于 API 或自定义输出信息,请参考 {uri-user-manual}[用户帮助手册]。
+
+[#contributing]
+== 贡献
+
+自由软件的精神鼓励 _每个人_ 来帮助改善这个项目。
+如果你在源码、文档或网站内容中发现错误或漏洞,请不要犹豫,提交一个议题或者推送一个修复请求。
+随时欢迎新的贡献者!
+
+这里有几种 *你* 可以做出贡献的方式:
+
+* 使用预发布版本(alpha, beta 或 preview)
+* 报告 Bug
+* 提议新功能
+* 编写文档
+* 编写规范
+* 编写 -- _任何补丁都不小。_
+** 修正错别字
+** 添加评论
+** 清理多余空白
+** 编写测试!
+* 重构代码
+* 修复 {uri-issues}[议题]
+* 审查补丁
+
+{uri-contribute}[贡献] 指南提供了如何提供贡献,包括如何创建、修饰和提交问题、特性、需求、代码和文档给 Asciidoctor 项目。
+
+[#getting-help]
+== 获得帮助
+
+开发 Asciidoctor 项目是未来了帮助你更容易地书写和发布你的内容。
+但是,如果没有反馈,我们将寸步难行。
+我们鼓励你在讨论组、Twitter或聊天室里,提问为题,讨论项目的方方面面,
+
+讨论组 (Nabble):: {uri-discuss}
+Twitter:: #asciidoctor 井号或 @asciidoctor 提醒
+聊天 (Gitter):: image:https://badges.gitter.im/Join%20In.svg[Gitter, link=https://gitter.im/asciidoctor/asciidoctor]
+
+ifdef::env-github[]
+Further information and documentation about Asciidoctor can be found on the project's website.
+
+{uri-project}/[Home] | {uri-news}[News] | {uri-docs}[Docs]
+endif::[]
+
+Asciidoctor 组织在 Github 托管代码、议案跟踪和相关子项目。
+
+代码库 (git):: {uri-repo}
+议案跟踪:: {uri-issues}
+在 GitHub 的 Asciidoctor 组织:: {uri-org}
+
+[#copyright-and-licensing]
+== 版权和协议
+
+Copyright (C) 2012-2016 Dan Allen, Ryan Waldron and the Asciidoctor Project.
+这个软件的免费使用是在MIT许可条款授予的。
+
+请看 {uri-license}[版权声明] 文件来获取更多详细信息。
+
+[#authors]
+== 作者
+
+*Asciidoctor* 由 https://github.com/mojavelinux[Dan Allen] 和 https://github.com/graphitefriction[Sarah White] 领导,并从 Asciidoctor 社区的 {uri-contributors}[很多其他独立开发者] 上收到了很多贡献。
+项目最初由 https://github.com/erebor[Ryan Waldron] 于 2012年基于 https://github.com/nickh[Nick Hengeveld] 的 {uri-prototype}[原型] 创建。
+
+*AsciiDoc* 由 Stuart Rackham 启动,并从 AsciiDoc 社区的其他独立开发者上收到很多贡献。
+
+== Changelog
+
+请看 {uri-changelog}[CHANGELOG]。
diff --git a/README.adoc b/README.adoc
index d081400..e1d265d 100644
--- a/README.adoc
+++ b/README.adoc
@@ -1,20 +1,20 @@
= Asciidoctor
Dan Allen <https://github.com/mojavelinux[@mojavelinux]>; Sarah White <https://github.com/graphitefriction[@graphitefriction]>; Ryan Waldron <https://github.com/erebor[@erebor]>
-v1.5.4, 2016-01-05
+v1.5.5, 2016-10-05
// settings:
:page-layout: base
:idprefix:
:idseparator: -
:source-language: ruby
:language: {source-language}
-ifdef::env-github[:badges:]
+ifdef::env-github[:status:]
// URIs:
:uri-org: https://github.com/asciidoctor
:uri-repo: {uri-org}/asciidoctor
:uri-asciidoctorj: {uri-org}/asciidoctorj
:uri-asciidoctorjs: {uri-org}/asciidoctor.js
:uri-project: http://asciidoctor.org
-ifdef::awestruct-version[:uri-project: link:]
+ifdef::env-site[:uri-project: link:]
:uri-docs: {uri-project}/docs
:uri-news: {uri-project}/news
:uri-manpage: {uri-project}/man/asciidoctor
@@ -22,7 +22,7 @@ ifdef::awestruct-version[:uri-project: link:]
:uri-contributors: {uri-repo}/graphs/contributors
:uri-rel-file-base: link:
:uri-rel-tree-base: link:
-ifdef::awestruct-version[]
+ifdef::env-site[]
:uri-rel-file-base: {uri-repo}/blob/master/
:uri-rel-tree-base: {uri-repo}/tree/master/
endif::[]
@@ -54,6 +54,13 @@ Asciidoctor is written in Ruby, packaged as a RubyGem and published to {uri-ruby
The gem is also included in several Linux distributions, including Fedora, Debian and Ubuntu.
Asciidoctor is open source, {uri-repo}[hosted on GitHub] and released under {uri-license}[the MIT license].
+ifndef::env-site[]
+.Translations of this document are available in the following languages:
+* {uri-rel-file-base}README-zh_CN.adoc[汉语]
+* {uri-rel-file-base}README-fr.adoc[Français]
+* {uri-rel-file-base}README-jp.adoc[日本語]
+endif::[]
+
.Key documentation
[.compact]
* {uri-docs}/what-is-asciidoc[What is Asciidoc?]
@@ -72,10 +79,10 @@ We use http://opalrb.org[Opal] to transcompile the Ruby source to JavaScript to
Asciidoctor.js is used to power the AsciiDoc preview extensions for Chrome, Atom, Brackets and other web-based tooling.
****
-ifdef::badges[]
+ifdef::status[]
.*Project health*
-image:https://img.shields.io/travis/asciidoctor/asciidoctor/master.svg[Build Status (Travis CI), link=https://travis-ci.org/asciidoctor/asciidoctor]
-image:https://ci.appveyor.com/api/projects/status/ifplu67oxvgn6ceq/branch/master?svg=true&passingText=green%20bar&failingText=%23fail&pendingText=building%2E%2E%2E[Build Status (AppVeyor), link=https://ci.appveyor.com/project/asciidoctor/asciidoctor]
+image:https://img.shields.io/travis/asciidoctor/asciidoctor/master.svg[Build Status (Travis CI), link=https://travis-ci.org/asciidoctor/asciidoctor]
+image:https://ci.appveyor.com/api/projects/status/ifplu67oxvgn6ceq/branch/master?svg=true&passingText=green%20bar&failingText=%23fail&pendingText=building%2E%2E%2E[Build Status (AppVeyor), link=https://ci.appveyor.com/project/asciidoctor/asciidoctor]
//image:https://img.shields.io/coveralls/asciidoctor/asciidoctor/master.svg[Coverage Status, link=https://coveralls.io/r/asciidoctor/asciidoctor]
image:https://codeclimate.com/github/asciidoctor/asciidoctor/badges/gpa.svg[Code Climate, link="https://codeclimate.com/github/asciidoctor/asciidoctor"]
image:https://inch-ci.org/github/asciidoctor/asciidoctor.svg?branch=master[Inline docs, link="https://inch-ci.org/github/asciidoctor/asciidoctor"]
@@ -101,15 +108,27 @@ Asciidoctor also offers a modern, responsive theme based on {uri-foundation}[Fou
== Requirements
-Asciidoctor works on Linux, OSX (Mac) and Windows and requires one of the following implementations of {uri-ruby}[Ruby]:
+Asciidoctor works on Linux, OS X (Mac) and Windows and requires one of the following implementations of {uri-ruby}[Ruby]:
-* MRI (Ruby 1.8.7, 1.9.3, 2.0, 2.1 & 2.2)
-* JRuby 1.7 (Ruby 1.8 and 1.9 modes) & 9000
+* MRI (Ruby 1.8.7, 1.9.3, 2.0, 2.1, 2.2 & 2.3)
+* JRuby (1.7 in Ruby 1.8 and 1.9 modes, 9000)
* Rubinius 2.2.x
* Opal (JavaScript)
We welcome your help testing Asciidoctor on these and other platforms.
-Refer to <<{idprefix}contributing,Contributing>> to learn how to get involved.
+Refer to the <<Contributing>> section to learn how to get involved.
+
+[CAUTION]
+====
+If you're using a non-English Windows environment, you may bump into an `Encoding::UndefinedConversionError` when invoking Asciidoctor.
+To solve this issue, we recommend changing the active code page in your console to UTF-8:
+
+ chcp 65001
+
+Once you make this change, all your Unicode headaches will be behind you.
+If you're using an IDE like Eclipse, make sure you set the encoding to UTF-8 there as well.
+Asciidoctor works best when you use UTF-8 everywhere.
+====
== Installation
@@ -152,7 +171,7 @@ If that's the case, use the following gem command to remove the old versions:
source 'https://rubygems.org'
gem 'asciidoctor'
# or specify the version explicitly
-# gem 'asciidoctor', '1.5.3'
+# gem 'asciidoctor', '1.5.5'
----
. Save the Gemfile
@@ -165,21 +184,21 @@ Using `bundle update` is *not* recommended as it will also update other gems, wh
=== (c) Linux package managers
-==== Yum (Fedora 21 or greater)
+==== DNF (Fedora 21 or greater)
-To install the gem on Fedora 21 or greater using yum, open a terminal and type:
+To install the gem on Fedora 21 or greater using dnf, open a terminal and type:
- $ sudo yum install -y asciidoctor
+ $ sudo dnf install -y asciidoctor
To upgrade the gem, use:
- $ sudo yum update -y asciidoctor
+ $ sudo dnf update -y asciidoctor
-TIP: Your Fedora system may be configured to automatically update packages, in which case no action is required by you to update the gem.
+TIP: Your system may be configured to automatically update rpm packages, in which case no action is required by you to update the gem.
-==== apt-get (Debian Sid, Ubuntu Saucy or greater)
+==== apt-get (Debian, Ubuntu, Mint)
-To install the gem on Debian or Ubuntu, open a terminal and type:
+To install the gem on Debian, Ubuntu or Mint, open a terminal and type:
$ sudo apt-get install -y asciidoctor
@@ -187,7 +206,37 @@ To upgrade the gem, use:
$ sudo apt-get upgrade -y asciidoctor
-TIP: Your Debian or Ubuntu system may be configured to automatically update packages, in which case no action is required by you to update the gem.
+TIP: Your system may be configured to automatically update deb packages, in which case no action is required by you to update the gem.
+
+The version of Asciidoctor installed by the package manager (apt-get) may not match the latest release of Asciidoctor.
+Consult the package repository for your distribution to find out which version is packaged per distribution release.
+
+* https://packages.debian.org/search?keywords=asciidoctor&searchon=names&exact=1&suite=all§ion=all[asciidoctor package by Debian release]
+* http://packages.ubuntu.com/search?keywords=asciidoctor&searchon=names&exact=1&suite=all§ion=all[asciidoctor package by Ubuntu release]
+* https://community.linuxmint.com/software/view/asciidoctor[asciidoctor package by Mint release]
+
+[CAUTION]
+====
+You're advised against using the `gem update` command to update a gem managed by the package manager.
+Doing so puts the system into an inconsistent state as the package manager can no longer track the files (which get installed under /usr/local).
+Simply put, system gems should only be managed by the package manager.
+
+If you want to use a version of Asciidoctor that is newer than what is installed by the package manager, you should use http://rvm.io[RVM] to install Ruby in your home directory (i.e., user space).
+Then, you can safely use the `gem` command to install or update the Asciidoctor gem.
+When using RVM, gems are installed in a location isolated from the system.
+====
+
+==== apk (Alpine Linux)
+
+To install the gem on Alpine Linux, open a terminal and type:
+
+ $ sudo apk add asciidoctor
+
+To upgrade the gem, use:
+
+ $ sudo apk add -u asciidoctor
+
+TIP: Your system may be configured to automatically update apk packages, in which case no action is required by you to update the gem.
=== Other installation options
@@ -207,7 +256,7 @@ You should see information about the Asciidoctor version and your Ruby environme
[.output]
....
-Asciidoctor 1.5.3 [http://asciidoctor.org]
+Asciidoctor 1.5.5 [http://asciidoctor.org]
Runtime Environment (ruby 2.2.2p95 [x86_64-linux]) (lc:UTF-8 fs:UTF-8 in:- ex:UTF-8)
....
@@ -284,7 +333,7 @@ Keep in mind that if you don't like the output Asciidoctor produces, _you can ch
Asciidoctor supports custom converters that can handle converting from the parsed document to the generated output.
One easy way to customize the output piecemeal is by using the template converter.
-The template converter allows you uses supply a {uri-tilt}[Tilt]-supported template file to handle converting any node in the document.
+The template converter allows you to supply a {uri-tilt}[Tilt]-supported template file to handle converting any node in the document.
However you go about it, you _can_ have 100% control over the output.
For more information about how to use the API or to customize the output, refer to the {uri-user-manual}[user manual].
@@ -316,13 +365,15 @@ The {uri-contribute}[Contributing] guide provides information on how to create,
== Getting Help
The Asciidoctor project is developed to help you easily write and publish your content.
-But we can't do that without your feedback!
-We encourage you to ask questions and discuss any aspects of the project on the discussion list, Twitter or IRC.
+But we can't do it without your feedback!
+We encourage you to ask questions and discuss any aspects of the project on the discussion list, on Twitter or in the chat room.
-Mailing list:: {uri-discuss}
-Twitter (Chat):: #asciidoctor hashtag
-Gitter (Chat):: image:https://badges.gitter.im/Join%20In.svg[Gitter, link=https://gitter.im/asciidoctor/asciidoctor]
-IRC (Chat):: {uri-irc}[#asciidoctor] on FreeNode IRC
+Discussion list (Nabble):: {uri-discuss}
+Twitter:: #asciidoctor hashtag or @asciidoctor mention
+Chat (Gitter):: image:https://badges.gitter.im/Join%20In.svg[Gitter, link=https://gitter.im/asciidoctor/asciidoctor]
+////
+Chat (IRC):: {uri-irc}[#asciidoctor] on FreeNode IRC
+////
ifdef::env-github[]
Further information and documentation about Asciidoctor can be found on the project's website.
@@ -352,6 +403,59 @@ The project was initiated in 2012 by https://github.com/erebor[Ryan Waldron] and
== Changelog
+== 1.5.5 (2016-10-05) - @mojavelinux
+
+Enhancements::
+ * Add preference to limit the maximum size of an attribute value (#1861)
+ * Honor SOURCE_DATE_EPOCH environment variable to accomodate reproducible builds (@JojoBoulix) (#1721)
+ * Add reversed attribute to ordered list if reversed option is enabled (#1830)
+ * Add support for additional docinfo locations (e.g., :header)
+ * Configure default stylesheet to break monospace word if exceeds length of line; add roles to prevent breaks (#1814)
+ * Introduce translation file for built-in labels (@ciampix)
+ * Provide translations for built-in labels (@JmyL - kr, @ciampix - it, @ivannov - bg, @maxandersen - da, @radcortez - pt, @eddumelendez - es, @leathersole - jp, @aslakknutsen - no, @shahryareiv - fa, @AlexanderZobkov - ru, @dongwq - zh, @rmpestano - pt_BR, @ncomet - fr, @lgvz - fi, @patoi - hu, @BojanStipic - sr, @fwilhe - de, @rahmanusta - tr, @abelsromero - ca, @aboullaite - ar, @roelvs - nl)
+ * Translate README to Chinese (@diguage)
+ * Translate README to Japanese (@Mizuho32)
+
+Improvements::
+ * Style nested emphasized phrases properly when using default stylesheet (#1691)
+ * Honor explicit table width even when autowidth option is set (#1843)
+ * Only explicit noheader option on table should disable implicit table header (#1849)
+ * Support docbook orient="land" attribute on tables (#1815)
+ * Add alias named list to retrieve parent List of ListItem
+ * Update push_include method to support chaining (#1836)
+ * Enable font smoothing on Firefox on OSX (#1837)
+ * Support combined use of sectanchors and sectlinks in HTML5 output (#1806)
+ * fix API docs for find_by
+ * Upgrade to Font Awesome 4.6.3 (@allenan, @mogztter) (#1723)
+ * README: add install instructions for Alpine Linux
+ * README: Switch yum commands to dnf in README
+ * README: Mention Mint as a Debian distro that packages Asciidoctor
+ * README: Add caution advising against using gem update to update a system-managed gem (@oddhack)
+ * README: sync French version with English version (@flashcode)
+ * Add missing endline after title element when converting open block to HTML
+ * Move list_marker_keyword method from AbstractNode to AbstractBlock
+ * Rename definition list to description list internally
+
+Compliance::
+ * Support 6-digit decimal char refs, 5-digit hexidecimal char refs (#1824)
+ * Compatibility fixes for Opal
+ * Check for number using Integer instead of Fixnum class for compatibility with Ruby 2.4
+
+Bug fixes::
+ * Use method_defined? instead of respond_to? to check if method is already defined when patching (#1838)
+ * Fix invalid conditional in HTML5 converter when handling of SVG
+ * Processor#parse_content helper no longer shares attribute list between blocks (#1651)
+ * Fix infinite loop if unordered list marker is immediately followed by a dot (#1679)
+ * Don't break SVG source when cleaning if svg start tag name is immediately followed by endline (#1676)
+ * Prevent template converter from crashing if .rb file found in template directory (#1827)
+ * Fix crash when generating section ID when both idprefix & idseparator are blank (#1821)
+ * Use stronger CSS rule for general text color in Pygments stylesheet (#1802)
+ * Don't duplicate forward slash for path relative to root (#1822)
+
+Infrastructure::
+ * Build gem properly in the absense of a git workspace, make compatible with JRuby (#1779)
+ * Run tests in CI using latest versions of Ruby, including Ruby 2.3 (@ferdinandrosario)
+
== 1.5.4 (2016-01-03) - @mojavelinux
Enhancements::
@@ -429,7 +533,7 @@ Improvements::
* restore attributes to header attributes after parse (#1255)
* allow docdate and doctime to be overridden (#1495)
* add CSS class `.center` for center block alignment (#1456)
- * recognize U+2022 as alternative marker for unordered lists (@mogztter) (#1177)
+ * recognize U+2022 (bullet) as alternative marker for unordered lists (@mogztter) (#1177)
* allow videos to work for local files by prepending asset-uri-scheme (Chris) (#1320)
* always assign playlist param when loop option is enabled for YouTube video
* parse isolated version in revision line (@bk2204) (#790)
@@ -454,6 +558,7 @@ Improvements::
* fix `+--help+` output text for `-I` (@bk2204)
* don't require open-uri-cached if already loaded
* do not attempt to scan pattern of non-existent directory in template converter
+ * prevent CodeRay from bolding every 10th line number
Compliance::
* use `<sup>` for footnote reference in text instead of `<span>` (#1523)
@@ -496,47 +601,4 @@ Infrastructure::
* add config to run CI build on AppVeyor
* exclude benchmark folder from gem (#1522)
-== 1.5.2 (2014-11-27) - @mojavelinux
-
-Enhancements::
-
- * add docinfo extension (@mogztter) (#1162)
- * allow docinfo to be in separate directory from content, specified by `docinfodir` attribute (@mogztter) (#511)
- * enable TeX equation auto-numbering if `eqnums` attribute is set (@jxxcarlson) (#1110)
-
-Improvements::
-
- * recognize `+--+` as valid line comment for callout numbers; make line comment configurable (#1068)
- * upgrade highlight.js to version 8.4 (#1216)
- * upgrade Font Awesome to version 4.2.0 (@clojens) (#1201)
- * define JAVASCRIPT_PLATFORM constant to simplify conditional logic in the JavaScript environment (#897)
- * provide access to destination directory, outfile and outdir via Document object (#1203)
- * print encoding information in version report produced by `asciidoctor -v` (#1210)
- * add intrinsic attribute named `cpp` with value `pass:[C++]` (#1208)
- * preserve URI targets passed to `stylesheet` and related attributes (#1192)
- * allow numeric characters in block attribute name (#1103)
- * support custom YouTube playlists (#1105)
- * make start number for unique id generation configurable (#1148)
- * normalize and force UTF-8 encoding of docinfo content (#831)
- * allow subs and default_subs to be specified in Block constructor (#749)
- * enhance error message when reading binary input files (@mogztter) (#1158)
- * add `append` method as alias to `<<` method on AbstractBlock (#1085)
- * assign value of `preface-title` as title of preface node (#1090)
- * fix spacing around checkbox in checklist (#1138)
- * automatically load Slim's include plugin when using slim templates (@jirutka) (#1151)
- * mixin Slim helpers into execution scope of slim templates (@jirutka) (#1143)
- * improve DocBook output for manpage doctype (@bk2204) (#1134, #1142)
-
-Compliance::
-
- * substitute attribute entry value in attributes defined outside of header (#1130)
- * allow empty cell to appear at end of table row (#1106)
- * only produce one row for table in CSV or DSV format with a single cell (#1180)
-
-Bug fixes::
-
- * add explicit to_s call to generate delimiter settings for MathJax config (#1198)
- * fix includes that reference absolute Windows paths (#1144)
- * apply DSL to extension block in a way compatible with Opal
-
Refer to the {uri-changelog}[CHANGELOG] for a complete list of changes in older releases.
diff --git a/_settings-README.adoc b/_settings-README.adoc
index c8b2928..8e88bdf 100644
--- a/_settings-README.adoc
+++ b/_settings-README.adoc
@@ -11,7 +11,7 @@ ifdef::env-github[:badges:]
:uri-asciidoctorj: {uri-org}/asciidoctorj
:uri-asciidoctorjs: {uri-org}/asciidoctor.js
:uri-project: http://asciidoctor.org
-ifdef::awestruct-version[:uri-project: link:]
+ifdef::env-site[:uri-project: link:]
:uri-docs: {uri-project}/docs
:uri-news: {uri-project}/news
:uri-manpage: {uri-project}/man/asciidoctor
@@ -19,7 +19,7 @@ ifdef::awestruct-version[:uri-project: link:]
:uri-contributors: {uri-repo}/graphs/contributors
:uri-rel-file-base: link:
:uri-rel-tree-base: link:
-ifdef::awestruct-version[]
+ifdef::env-site[]
:uri-rel-file-base: {uri-repo}/blob/master/
:uri-rel-tree-base: {uri-repo}/tree/master/
endif::[]
@@ -32,7 +32,8 @@ endif::[]
:uri-rubygem: https://rubygems.org/gems/asciidoctor
:uri-what-is-asciidoc: {uri-docs}/what-is-asciidoc
:uri-user-manual: {uri-docs}/user-manual
-:uri-install-doc: {uri-docs}/install-toolchain
+:uri-install-docker: https://github.com/asciidoctor/docker-asciidoctor
+//:uri-install-doc: {uri-docs}/install-toolchain
:uri-install-osx-doc: {uri-docs}/install-asciidoctor-macosx
:uri-render-doc: {uri-docs}/render-documents
:uri-themes-doc: {uri-docs}/produce-custom-themes-using-asciidoctor-stylesheet-factory
diff --git a/asciidoctor.gemspec b/asciidoctor.gemspec
index d9e79b2..942d392 100644
--- a/asciidoctor.gemspec
+++ b/asciidoctor.gemspec
@@ -1,29 +1,29 @@
# -*- encoding: utf-8 -*-
require File.expand_path '../lib/asciidoctor/version', __FILE__
+require 'open3' unless defined? Open3
Gem::Specification.new do |s|
- s.name = 'asciidoctor'
- s.version = Asciidoctor::VERSION
- s.summary = 'An implementation of the AsciiDoc text processor and publishing toolchain in Ruby'
- s.description = <<-EOS
-A fast, open source text processor and publishing toolchain, written in Ruby, for converting AsciiDoc content to HTML5, DocBook 5 (or 4.5) and other formats.
- EOS
- s.authors = ['Dan Allen', 'Sarah White', 'Ryan Waldron', 'Jason Porter', 'Nick Hengeveld', 'Jeremy McAnally']
- s.email = ['dan.j.allen at gmail.com']
- s.homepage = 'http://asciidoctor.org'
- s.license = 'MIT'
+ s.name = 'asciidoctor'
+ s.version = Asciidoctor::VERSION
+ s.summary = 'An implementation of the AsciiDoc text processor and publishing toolchain in Ruby'
+ s.description = 'A fast, open source text processor and publishing toolchain, written in Ruby, for converting AsciiDoc content to HTML5, DocBook 5 (or 4.5) and other formats.'
+ s.authors = ['Dan Allen', 'Sarah White', 'Ryan Waldron', 'Jason Porter', 'Nick Hengeveld', 'Jeremy McAnally']
+ s.email = ['dan.j.allen at gmail.com']
+ s.homepage = 'http://asciidoctor.org'
+ s.license = 'MIT'
- begin
- s.files = `git ls-files -z -- {bin,data,features,lib,man,test}/* {CHANGELOG,CONTRIBUTING,LICENSE,README}.adoc Rakefile`.split "\0"
+ files = begin
+ (result = Open3.popen3('git ls-files -z') {|_, out| out.read }.split %(\0)).empty? ? Dir['**/*'] : result
rescue
- s.files = Dir['**/*']
+ Dir['**/*']
end
- s.executables = ['asciidoctor', 'asciidoctor-safe']
- s.test_files = s.files.grep(/^(?:test\/.*_test\.rb|features\/.*\.(?:feature|rb))$/)
- s.require_paths = ['lib']
- s.has_rdoc = true
- s.rdoc_options = ['--charset=UTF-8']
- s.extra_rdoc_files = ['CHANGELOG.adoc', 'CONTRIBUTING.adoc', 'LICENSE.adoc']
+ s.files = files.grep(/^(?:(?:data|lib|man)\/.+|Gemfile|Rakefile|(?:CHANGELOG|CONTRIBUTING|LICENSE|README(?:-\w+)?)\.adoc|#{s.name}\.gemspec)$/)
+ s.executables = files.grep(/^bin\//).map {|f| File.basename f }
+ s.test_files = files.grep(/^(?:test\/.*_test\.rb|features\/.*\.(?:feature|rb))$/)
+ s.require_paths = ['lib']
+ s.has_rdoc = true
+ s.rdoc_options = ['--charset=UTF-8']
+ s.extra_rdoc_files = ['CHANGELOG.adoc', 'CONTRIBUTING.adoc', 'LICENSE.adoc']
# asciimath is needed for testing AsciiMath in DocBook backend
s.add_development_dependency 'asciimath', '~> 1.0.2'
diff --git a/benchmark/benchmark.rb b/benchmark/benchmark.rb
index 9acb3ac..c65d80d 100755
--- a/benchmark/benchmark.rb
+++ b/benchmark/benchmark.rb
@@ -110,7 +110,7 @@ when 'userguide-loop'
when 'mdbasics-loop'
require '../lib/asciidoctor.rb'
GC.start
- sample_file = ENV['BENCH_TEST_FILE'] || 'sample-data/userguide.adoc'
+ sample_file = ENV['BENCH_TEST_FILE'] || 'sample-data/mdbasics.adoc'
backend = ENV['BENCH_BACKEND'] || 'html5'
best = nil
diff --git a/data/locale/attributes.adoc b/data/locale/attributes.adoc
new file mode 100644
index 0000000..2a7e50c
--- /dev/null
+++ b/data/locale/attributes.adoc
@@ -0,0 +1,470 @@
+// This file provides translations for all built-in attributes in Asciidoctor that output localized content.
+// See http://asciidoctor.org/docs/user-manual/#customizing-built-in-labels to learn how to use it.
+//
+// NOTE: Please use a line comment in front of the listing-caption and preface-title entries.
+// These attributes are optional and not set by default.
+//
+// IMPORTANT: Do not add any blank lines.
+//
+// Arabic translation, courtesy of Aboullaite Mohammed <aboullaite.mohammed at gmail.com>
+ifeval::["{lang}" == "ar"]
+:appendix-caption: ملحق
+:caution-caption: تنبيه
+:example-caption: مثال
+:figure-caption: الشكل
+:important-caption: مهم
+:last-update-label: اخر تحديث
+//:listing-caption: قائمة
+:manname-title: اسم
+:note-caption: ملاحظة
+//:preface-title: تمهيد
+:table-caption: جدول
+:tip-caption: تلميح
+:toc-title: فهرس
+:untitled-label: بدون عنوان
+:version-label: نسخة
+:warning-caption: تحذير
+endif::[]
+//
+// Bulgarian translation, courtesy of Ivan St. Ivanov <ivan.st.ivanov at gmail.com>
+ifeval::["{lang}" == "bg"]
+:appendix-caption: Приложение
+:caution-caption: Внимание
+:example-caption: Пример
+:figure-caption: Фигура
+:important-caption: Важно
+:last-update-label: Последно обновен
+//:listing-caption: Листинг
+:manname-title: ИМЕ
+:note-caption: Забележка
+//:preface-title: Предговор
+:table-caption: Таблица
+:tip-caption: Подсказка
+:toc-title: Съдържание
+:untitled-label: Без заглавие
+:version-label: Версия
+:warning-caption: Внимание
+endif::[]
+//
+// Catalan translation, courtesy of Abel Salgado Romero <abelromero at gmail.com> and Alex Soto
+ifeval::["{lang}" == "ca"]
+:appendix-caption: Apendix
+:caution-caption: Atenció
+:example-caption: Exemple
+:figure-caption: Figura
+:important-caption: Important
+:last-update-label: Última actualització
+//:listing-caption: Llista
+:manname-title: NOM
+:note-caption: Nota
+//:preface-title: Prefaci
+:table-caption: Taula
+:tip-caption: Suggeriment
+:toc-title: Índex
+:untitled-label: Sense títol
+:version-label: Versió
+:warning-caption: Advertència
+endif::[]
+//
+// Danish translation, courtesy of Max Rydahl Andersen <manderse at redhat.com>
+ifeval::["{lang}" == "da"]
+:appendix-caption: Appendix
+:caution-caption: Forsigtig
+:example-caption: Eksempel
+:figure-caption: Figur
+:important-caption: Vigtig
+:last-update-label: Sidst opdateret
+:listing-caption: List
+:manname-title: NAVN
+:note-caption: Notat
+//:preface-title:
+:table-caption: Tabel
+:tip-caption: Tips
+:toc-title: Indholdsfortegnelse
+:untitled-label: Unavngivet
+:version-label: Version
+:warning-caption: Advarsel
+endif::[]
+//
+// German translation, courtesy of Florian Wilhelm
+ifeval::["{lang}" == "de"]
+:appendix-caption: Anhang
+:caution-caption: Achtung
+:example-caption: Beispiel
+:figure-caption: Abbildung
+:important-caption: Wichtig
+:last-update-label: Zuletzt aktualisiert
+//:listing-caption: Listing
+:manname-title: BEZEICHNUNG
+:note-caption: Anmerkung
+//:preface-title: Vorwort
+:table-caption: Tabelle
+:tip-caption: Hinweis
+:toc-title: Inhalt
+:untitled-label: Ohne Titel
+:version-label: Version
+:warning-caption: Warnung
+endif::[]
+//
+// Spanish translation, courtesy of Eddú Meléndez <eddu.melendez at gmail.com>
+ifeval::["{lang}" == "es"]
+:appendix-caption: Apéndice
+:caution-caption: Precaución
+:example-caption: Ejemplo
+:figure-caption: Figura
+:important-caption: Importante
+:last-update-label: Ultima actualización
+//:listing-caption: Lista
+:manname-title: NOMBRE
+:note-caption: Nota
+//:preface-title: Prefacio
+:table-caption: Tabla
+:tip-caption: Sugerencia
+:toc-title: Tabla de Contenido
+:untitled-label: Sin título
+:version-label: Versión
+:warning-caption: Aviso
+endif::[]
+//
+// Persian (Farsi) translation, courtesy of Shahryar Eivazzadeh <shahryareiv at gmail.com>
+ifeval::["{lang}" == "fa"]
+:appendix-caption: پیوست
+:caution-caption: گوشزد
+:example-caption: نمونه
+:figure-caption: نمودار
+:important-caption: مهم
+:last-update-label: آخرین به روز رسانی
+//:listing-caption: فهرست
+:manname-title: نام
+:note-caption: یادداشت
+//:preface-title: پیشگفتار
+:table-caption: جدول
+:tip-caption: نکته
+:toc-title: فهرست مطالب
+:untitled-label: بینام
+:version-label: نگارش
+:warning-caption: هشدار
+endif::[]
+//
+// Finnish translation by Tero Hänninen
+ifeval::["{lang}" == "fi"]
+:appendix-caption: Liitteet
+:caution-caption: Huom
+:example-caption: Esimerkki
+:figure-caption: Kuvio
+:important-caption: Tärkeää
+:last-update-label: Viimeksi päivitetty
+//:listing-caption: Listaus
+:manname-title: NIMI
+:note-caption: Huomio
+//:preface-title: Esipuhe
+:table-caption: Taulukko
+:tip-caption: Vinkki
+:toc-title: Sisällysluettelo
+:untitled-label: Nimetön
+:version-label: Versio
+:warning-caption: Varoitus
+endif::[]
+//
+// French translation, courtesy of Nicolas Comet <nicolas.comet at gmail.com>
+ifeval::["{lang}" == "fr"]
+:appendix-caption: Appendice
+:caution-caption: Avertissement
+:example-caption: Exemple
+:figure-caption: Figure
+:important-caption: Important
+:last-update-label: Dernière mise à jour
+//:listing-caption: Liste
+:manname-title: NOM
+:note-caption: Note
+//:preface-title: Préface
+:table-caption: Tableau
+:tip-caption: Astuce
+:toc-title: Table des matières
+:untitled-label: Sans titre
+:version-label: Version
+:warning-caption: Attention
+endif::[]
+//
+// Hungarian translation, courtesy of István Pató <istvan.pato at gmail.com>
+ifeval::["{lang}" == "hu"]
+:appendix-caption: függelék
+:caution-caption: Figyelmeztetés
+:example-caption: Példa
+:figure-caption: Ábra
+:important-caption: Fontos
+:last-update-label: Utolsó frissítés
+//:listing-caption: Lista
+:manname-title: NÉV
+:note-caption: Megjegyzés
+//:preface-title: Előszó
+:table-caption: Táblázat
+:tip-caption: Tipp
+:toc-title: Tartalomjegyzék
+:untitled-label: Névtelen
+:version-label: Verzió
+:warning-caption: Figyelem
+endif::[]
+//
+// Italian translation, courtesy of Marco Ciampa <ciampix at libero.it>
+ifeval::["{lang}" == "it"]
+:appendix-caption: Appendice
+:caution-caption: Attenzione
+:chapter-label: Capitolo
+:example-caption: Esempio
+:figure-caption: Figura
+:important-caption: Importante
+:last-update-label: Ultimo aggiornamento
+//:listing-caption: Elenco
+:manname-title: NOME
+:note-caption: Nota
+//:preface-title: Prefazione
+:table-caption: Tabella
+:tip-caption: Suggerimento
+:toc-title: Indice
+:untitled-label: Senza titolo
+:version-label: Versione
+:warning-caption: Attenzione
+endif::[]
+//
+// Japanese translation, courtesy of Takayuki Konishi <seannos.takayuki at gmail.com>
+ifeval::["{lang}" == "ja"]
+:appendix-caption: 付録
+:caution-caption: 注意
+:example-caption: 例
+:figure-caption: 図
+:important-caption: 重要
+:last-update-label: 最終更新
+//:listing-caption: リスト
+:manname-title: 名前
+:note-caption: 注記
+//:preface-title: まえがき
+:table-caption: 表
+:tip-caption: ヒント
+:toc-title: 目次
+:untitled-label: 無題
+:version-label: バージョン
+:warning-caption: 警告
+endif::[]
+//
+// Korean translation, courtesy of Sungsik Nam <jmyl at me.com>
+ifeval::["{lang}" == "kr"]
+:appendix-caption: 부록
+:caution-caption: 주의
+:example-caption: 예시
+:figure-caption: 그림
+:important-caption: 중요
+:last-update-label: 마지막 업데이트
+//:listing-caption: 목록
+:manname-title: 이름
+:note-caption: 노트
+//:preface-title: 머리말
+:table-caption: 표
+:tip-caption: 힌트
+:toc-title: 차례
+:untitled-label: 익명
+:version-label: 버전
+:warning-caption: 경고
+endif::[]
+//
+// Dutch translation, courtesy of Roel Van Steenberghe <roel.vansteenberghe at gmail.com>
+ifeval::["{lang}" == "nl"]
+:appendix-caption: Bijlage
+:caution-caption: Opgelet
+:example-caption: Voorbeeld
+:figure-caption: Figuur
+:important-caption: Belangrijk
+:last-update-label: Laatste aanpassing
+//:listing-caption: Lijst
+:manname-title: NAAM
+:note-caption: Noot
+//:preface-title: Inleiding
+:table-caption: Tabel
+:tip-caption: Tip
+:toc-title: Ínhoudsopgave
+:untitled-label: Naamloos
+:version-label: Versie
+:warning-caption: Waarschuwing
+endif::[]
+//
+// Norwegian, courtesy of Aslak Knutsen <aslak at 4fs.no>
+ifeval::["{lang}" == "no"]
+:appendix-caption: Vedlegg
+:caution-caption: Forsiktig
+:example-caption: Eksempel
+:figure-caption: Figur
+:important-caption: Viktig
+:last-update-label: Sist oppdatert
+//:listing-caption:
+:manname-title: NAVN
+:note-caption: Notat
+//:preface-title:
+:table-caption: Tabell
+:tip-caption: Tips
+:toc-title: Innholdsfortegnelse
+:untitled-label: Navnløs
+:version-label: Versjon
+:warning-caption: Advarsel
+endif::[]
+//
+// Portuguese translation, courtesy of Roberto Cortez <radcortez at yahoo.com>
+ifeval::["{lang}" == "pt"]
+:appendix-caption: Apêndice
+:caution-caption: Atenção
+:example-caption: Exemplo
+:figure-caption: Figura
+:important-caption: Importante
+:last-update-label: Última actualização
+//:listing-caption: Listagem
+:manname-title: NOME
+:note-caption: Nota
+//:preface-title: Prefácio
+:table-caption: Tabela
+:tip-caption: Sugestão
+:toc-title: Índice
+:untitled-label: Sem título
+:version-label: Versão
+:warning-caption: Aviso
+endif::[]
+//
+// Brazilian Portuguese translation, courtesy of Rafael Pestano <rmpestano at gmail.com>
+ifeval::["{lang}" == "pt_BR"]
+:appendix-caption: Apêndice
+:caution-caption: Cuidado
+:example-caption: Exemplo
+:figure-caption: Figura
+:important-caption: Importante
+:last-update-label: Última atualização
+//:listing-caption: Listagem
+:manname-title: NOME
+:note-caption: Nota
+//:preface-title: Prefácio
+:table-caption: Tabela
+:tip-caption: Dica
+:toc-title: Índice
+:untitled-label: Sem título
+:version-label: Versão
+:warning-caption: Aviso
+endif::[]
+//
+// Russian translation, courtesy of Alexander Zobkov <alexander.zobkov at gmail.com>
+ifeval::["{lang}" == "ru"]
+:appendix-caption: Приложение
+:caution-caption: Внимание
+:example-caption: Пример
+:figure-caption: Рисунок
+:important-caption: Важно
+:last-update-label: Последний раз обновлено
+//:listing-caption: Листинг
+:manname-title: НАЗВАНИЕ
+:note-caption: Примечание
+//:preface-title: Предисловие
+:table-caption: Таблица
+:tip-caption: Подсказка
+:toc-title: Содержание
+:untitled-label: Без названия
+:version-label: Версия
+:warning-caption: Предупреждение
+endif::[]
+//
+// Serbian Cyrillic translation, courtesy of Bojan Stipic <bojan-7 at live.com>
+ifeval::["{lang}" == "sr"]
+:appendix-caption: Додатак
+:caution-caption: Опрез
+//:chapter-label: Поглавље
+:example-caption: Пример
+:figure-caption: Слика
+:important-caption: Важно
+:last-update-label: Последње ажурирано
+//:listing-caption: Списак
+:manname-title: НАЗИВ
+:note-caption: Белешка
+//:preface-title: Предговор
+:table-caption: Табела
+:tip-caption: Савет
+:toc-title: Садржај
+:untitled-label: Без назива
+:version-label: Верзија
+:warning-caption: Упозорење
+endif::[]
+//
+// Serbian Latin translation, courtesy of Bojan Stipic <bojan-7 at live.com>
+ifeval::["{lang}" == "sr_Latn"]
+:appendix-caption: Dodatak
+:caution-caption: Oprez
+//:chapter-label: Poglavlje
+:example-caption: Primer
+:figure-caption: Slika
+:important-caption: Važno
+:last-update-label: Poslednje ažurirano
+//:listing-caption: Spisak
+:manname-title: NAZIV
+:note-caption: Beleška
+//:preface-title: Predgovor
+:table-caption: Tabela
+:tip-caption: Savet
+:toc-title: Sadržaj
+:untitled-label: Bez naziva
+:version-label: Verzija
+:warning-caption: Upozorenje
+endif::[]
+//
+// Turkish translation, courtesy of Rahman Usta <rahman.usta.88 at gmail.com>
+ifeval::["{lang}" == "tr"]
+:appendix-caption: Ek bölüm
+:caution-caption: Dikkat
+:example-caption: Örnek
+:figure-caption: Görsel
+:important-caption: Önemli
+:last-update-label: Son güncelleme
+//:listing-caption: Listeleme
+:manname-title: İSİM
+:note-caption: Not
+//:preface-title: Ön söz
+:table-caption: Tablo
+:tip-caption: İpucu
+:toc-title: İçindekiler
+:untitled-label: İsimsiz
+:version-label: Versiyon
+:warning-caption: Uyarı
+endif::[]
+//
+// Simplified Chinese translation, courtesy of John Dong <dongwqs at gmail.com>
+ifeval::["{lang}" == "zh_CN"]
+:appendix-caption: 附录
+:caution-caption: 注意
+:example-caption: 示例
+:figure-caption: 图表
+:important-caption: 重要
+:last-update-label: 最后更新
+//:listing-caption: 列表
+:manname-title: 名称
+:note-caption: 笔记
+//:preface-title: 序言
+:table-caption: 表格
+:tip-caption: 提示
+:toc-title: 目录
+:untitled-label: 暂无标题
+:version-label: 版本
+:warning-caption: 警告
+endif::[]
+//
+// Traditional Chinese translation, courtesy of John Dong <dongwqs at gmail.com>
+ifeval::["{lang}" == "zh_TW"]
+:appendix-caption: 附錄
+:caution-caption: 注意
+:example-caption: 示例
+:figure-caption: 圖表
+:important-caption: 重要
+:last-update-label: 最後更新
+//:listing-caption: 列表
+:manname-title: 名稱
+:note-caption: 筆記
+//:preface-title: 序言
+:table-caption: 表格
+:tip-caption: 提示
+:toc-title: 目錄
+:untitled-label: 暫無標題
+:version-label: 版本
+:warning-caption: 警告
+endif::[]
diff --git a/data/stylesheets/asciidoctor-default.css b/data/stylesheets/asciidoctor-default.css
index 36590bf..27ac53b 100644
--- a/data/stylesheets/asciidoctor-default.css
+++ b/data/stylesheets/asciidoctor-default.css
@@ -7,7 +7,6 @@ audio:not([controls]){display:none;height:0}
[hidden],template{display:none}
script{display:none!important}
html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}
-body{margin:0}
a{background:transparent}
a:focus{outline:thin dotted}
a:active,a:hover{outline:0}
@@ -42,7 +41,7 @@ textarea{overflow:auto;vertical-align:top}
table{border-collapse:collapse;border-spacing:0}
*,*:before,*:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
html,body{font-size:100%}
-body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto}
+body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto;tab-size:4;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
a:hover{cursor:pointer}
img,object,embed{max-width:100%;height:auto}
object,embed{height:100%}
@@ -54,7 +53,6 @@ img{-ms-interpolation-mode:bicubic}
.text-center{text-align:center!important}
.text-justify{text-align:justify!important}
.hide{display:none}
-body{-webkit-font-smoothing:antialiased}
img,object,svg{display:inline-block;vertical-align:middle}
textarea{height:auto;min-height:50px}
select{width:100%}
@@ -109,13 +107,16 @@ table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:
table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f8f8f7}
table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6}
-body{tab-size:4}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
.clearfix:before,.clearfix:after,.float-group:before,.float-group:after{content:" ";display:table}
.clearfix:after,.float-group:after{clear:both}
-*:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed}
+*:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed;word-wrap:break-word}
+*:not(pre)>code.nobreak{word-wrap:normal}
+*:not(pre)>code.nowrap{white-space:nowrap}
pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed}
+em em{font-style:normal}
+strong strong{font-weight:400}
.keyseq{color:rgba(51,51,51,.8)}
kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
.keyseq kbd:first-child{margin-left:0}
diff --git a/lib/asciidoctor.rb b/lib/asciidoctor.rb
index 1a6398d..a34192a 100644
--- a/lib/asciidoctor.rb
+++ b/lib/asciidoctor.rb
@@ -13,7 +13,6 @@ if RUBY_ENGINE == 'opal'
require 'asciidoctor/opal_ext'
else
autoload :Base64, 'base64'
- autoload :FileUtils, 'fileutils'
autoload :OpenURI, 'open-uri'
autoload :StringScanner, 'strscan'
end
@@ -632,7 +631,7 @@ module Asciidoctor
InlineSectionAnchorRx = /^(.*?)#{CG_BLANK}+(\\)?\[\[([#{CC_ALPHA}:_][#{CC_WORD}:.-]*)(?:,#{CG_BLANK}*(\S.*?))?\]\]$/
# Matches invalid characters in a section id.
- InvalidSectionIdCharsRx = /&(?:[a-zA-Z]{2,}|#\d{2,5}|#x[a-fA-F0-9]{2,4});|[^#{CC_WORD}]+?/
+ InvalidSectionIdCharsRx = /&(?:[a-zA-Z]{2,}|#\d{2,6}|#x[a-fA-F0-9]{2,5});|[^#{CC_WORD}]+?/
# Matches the block style used to designate a section title as a floating title.
#
@@ -646,7 +645,9 @@ module Asciidoctor
## Lists
# Detects the start of any list item.
- AnyListRx = /^(?:<?\d+>#{CG_BLANK}+#{CG_GRAPH}|#{CG_BLANK}*(?:-|(?:\*|\.|\u2022){1,5}|\d+\.|[a-zA-Z]\.|[IVXivx]+\))#{CG_BLANK}+#{CG_GRAPH}|#{CG_BLANK}*.*?(?::{2,4}|;;)(?:#{CG_BLANK}+#{CG_GRAPH}|$))/
+ #
+ # NOTE we only have to check as far as the blank character because we know it means non-whitespace follows.
+ AnyListRx = /^(?:#{CG_BLANK}*(?:-|([*.\u2022])\1{0,4}|\d+\.|[a-zA-Z]\.|[IVXivx]+\))#{CG_BLANK}|#{CG_BLANK}*.*?(?::{2,4}|;;)(?:$|#{CG_BLANK})|<?\d+>#{CG_BLANK})/
# Matches an unordered list item (one level for hyphens, up to 5 levels for asterisks).
#
@@ -656,6 +657,7 @@ module Asciidoctor
# - Foo
#
# NOTE we know trailing (.*) will match at least one character because we strip trailing spaces
+ # NOTE I want to use (-|([*\u2022])\2{0,4}) but breaks the parser since it relies on fixed match positions
UnorderedListRx = /^#{CG_BLANK}*(-|\*{1,5}|\u2022{1,5})#{CG_BLANK}+(.*)$/
# Matches an ordered list item (explicit numbering or up to 5 consecutive dots).
@@ -684,7 +686,7 @@ module Asciidoctor
#:lowergreek => /[a-z]\]/
}
- # Matches a definition list item.
+ # Matches a description list entry.
#
# Examples
#
@@ -693,26 +695,26 @@ module Asciidoctor
# foo::::
# foo;;
#
- # # should be followed by a definition, on the same line...
+ # # the term can be followed by a description on the same line...
#
# foo:: That which precedes 'bar' (see also, <<bar>>)
#
- # # ...or on a separate line
+ # # ...or on a separate line (optionally indented)
#
# foo::
# That which precedes 'bar' (see also, <<bar>>)
#
- # # the term may be an attribute reference
+ # # the term or description may be an attribute reference
#
# {foo_term}:: {foo_def}
#
# NOTE negative match for comment line is intentional since that isn't handled when looking for next list item
- # QUESTION should we check for line comment in regex or when scanning the lines?
+ # TODO check for line comment when scanning lines instead of in regex
#
- DefinitionListRx = /^(?!\/\/)#{CG_BLANK}*(.*?)(:{2,4}|;;)(?:#{CG_BLANK}+(.*))?$/
+ DescriptionListRx = /^(?!\/\/)#{CG_BLANK}*(.*?)(:{2,4}|;;)(?:#{CG_BLANK}+(.*))?$/
- # Matches a sibling definition list item (which does not include the keyed type).
- DefinitionListSiblingRx = {
+ # Matches a sibling description list item (which does not include the type in the key).
+ DescriptionListSiblingRx = {
# (?:.*?[^:])? - a non-capturing group which grabs longest sequence of characters that doesn't end w/ colon
'::' => /^(?!\/\/)#{CG_BLANK}*((?:.*[^:])?)(::)(?:#{CG_BLANK}+(.*))?$/,
':::' => /^(?!\/\/)#{CG_BLANK}*((?:.*[^:])?)(:::)(?:#{CG_BLANK}+(.*))?$/,
@@ -727,7 +729,7 @@ module Asciidoctor
# <1> Foo
#
# NOTE we know trailing (.*) will match at least one character because we strip trailing spaces
- CalloutListRx = /^<?(\d+)>#{CG_BLANK}+(.*)/
+ CalloutListRx = /^<?(\d+)>#{CG_BLANK}+(.*)$/
# Matches a callout reference inside literal text.
#
@@ -749,7 +751,7 @@ module Asciidoctor
ListRxMap = {
:ulist => UnorderedListRx,
:olist => OrderedListRx,
- :dlist => DefinitionListRx,
+ :dlist => DescriptionListRx,
:colist => CalloutListRx
}
@@ -965,12 +967,12 @@ module Asciidoctor
## Layout
# Matches a trailing + preceded by at least one space character,
- # which forces a hard line break (<br> tag in HTML outputs).
+ # which forces a hard line break (<br> tag in HTML output).
#
# Examples
#
- # +
- # Foo +
+ # Humpty Dumpty sat on a wall, +
+ # Humpty Dumpty had a great fall.
#
if RUBY_ENGINE == 'opal'
# NOTE JavaScript only treats ^ and $ as line boundaries in multiline regexp; . won't match newlines
@@ -1249,7 +1251,7 @@ module Asciidoctor
# left double arrow <=
[/\\?<=/, '⇐', :none],
# restore entities
- [/\\?(&)amp;((?:[a-zA-Z]+|#\d{2,5}|#x[a-fA-F0-9]{2,4});)/, '', :bounding]
+ [/\\?(&)amp;((?:[a-zA-Z]{2,}|#\d{2,6}|#x[a-fA-F0-9]{2,5});)/, '', :bounding]
]
class << self
@@ -1308,7 +1310,8 @@ module Asciidoctor
if ::File === input
# TODO cli checks if input path can be read and is file, but might want to add check to API
input_path = ::File.expand_path input.path
- input_mtime = input.mtime
+ # See https://reproducible-builds.org/specs/source-date-epoch/
+ input_mtime = ::ENV['SOURCE_DATE_EPOCH'] ? (::Time.at ::ENV['SOURCE_DATE_EPOCH'].to_i).utc : input.mtime
lines = input.readlines
# hold off on setting infile and indir until we get a better sense of their purpose
attributes['docfile'] = input_path
@@ -1487,7 +1490,7 @@ module Asciidoctor
unless ::File.directory? outdir
if mkdirs
- ::FileUtils.mkdir_p outdir
+ Helpers.mkdir_p outdir
else
# NOTE we intentionally refer to the directory as it was passed to the API
raise ::IOError, %(target directory does not exist: #{to_dir})
diff --git a/lib/asciidoctor/abstract_block.rb b/lib/asciidoctor/abstract_block.rb
index 5e8259b..4f44d8a 100644
--- a/lib/asciidoctor/abstract_block.rb
+++ b/lib/asciidoctor/abstract_block.rb
@@ -244,11 +244,10 @@ class AbstractBlock < AbstractNode
end
=end
- # Public: Query for all descendant block nodes in the document tree that
- # match the specified Symbol filter_context and, optionally, the style and/or
- # role specified in the options Hash. If a block is provided, it's used as an
- # additional filter. If no filters are specified, all block nodes in the tree
- # are returned.
+ # Public: Query for all descendant block-level nodes in the document tree
+ # that match the specified selector (context, style, id, and/or role). If a
+ # Ruby block is given, it's used as an additional filter. If no selector or
+ # Ruby block is supplied, all block-level nodes in the tree are returned.
#
# Examples
#
@@ -262,7 +261,7 @@ class AbstractBlock < AbstractNode
# doc.find_by context: :listing, style: 'source'
# #=> Asciidoctor::Block at 13136720 { context: :listing, content_model: :verbatim, style: "source", lines: 1 }
#
- # Returns An Array of block nodes that match the given selector or an empty Array if no matches are found
+ # Returns An Array of block-level nodes that match the filter or an empty Array if no matches are found
#--
# TODO support jQuery-style selector (e.g., image.thumb)
def find_by selector = {}, &block
@@ -290,8 +289,8 @@ class AbstractBlock < AbstractNode
result.concat(@header.find_by selector, &block)
end
- # yuck, dlist is a special case
unless context_selector == :document # optimization
+ # yuck, dlist is a special case
if @context == :dlist
if any_context || context_selector != :section # optimization
@blocks.flatten.each do |li|
@@ -356,6 +355,17 @@ class AbstractBlock < AbstractNode
nil
end
+ # Public: Retrieve the list marker keyword for the specified list type.
+ #
+ # For use in the HTML type attribute.
+ #
+ # list_type - the type of list; default to the @style if not specified
+ #
+ # Returns the single-character [String] keyword that represents the marker for the specified list type
+ def list_marker_keyword list_type = nil
+ ORDERED_LIST_KEYWORDS[list_type || @style]
+ end
+
# Internal: Assign the next index (0-based) to this section
#
# Assign the next index of this section within the parent
@@ -369,10 +379,10 @@ class AbstractBlock < AbstractNode
if section.sectname == 'appendix'
appendix_number = @document.counter 'appendix-number', 'A'
section.number = appendix_number if section.numbered
- if (caption = @document.attr 'appendix-caption', '') != ''
- section.caption = %(#{caption} #{appendix_number}: )
- else
+ if (caption = @document.attr 'appendix-caption', '').empty?
section.caption = %(#{appendix_number}. )
+ else
+ section.caption = %(#{caption} #{appendix_number}: )
end
elsif section.numbered
# chapters in a book doctype should be sequential even when divided into parts
diff --git a/lib/asciidoctor/abstract_node.rb b/lib/asciidoctor/abstract_node.rb
index 2b97871..b336a39 100644
--- a/lib/asciidoctor/abstract_node.rb
+++ b/lib/asciidoctor/abstract_node.rb
@@ -548,9 +548,9 @@ class AbstractNode
end
# Public: Calculate the relative path to this absolute filename from the Document#base_dir
- def relative_path(filename)
- (@path_resolver ||= PathResolver.new).relative_path filename, @document.base_dir
- end
+ #def relative_path(filename)
+ # (@path_resolver ||= PathResolver.new).relative_path filename, @document.base_dir
+ #end
# Public: Check whether the specified String is a URI by
# matching it against the Asciidoctor::UriSniffRx regex.
@@ -559,16 +559,5 @@ class AbstractNode
def is_uri? str
Helpers.uriish? str
end
-
- # Public: Retrieve the list marker keyword for the specified list type.
- #
- # For use in the HTML type attribute.
- #
- # list_type - the type of list; default to the @style if not specified
- #
- # Returns the single-character [String] keyword that represents the marker for the specified list type
- def list_marker_keyword(list_type = nil)
- ORDERED_LIST_KEYWORDS[list_type || @style]
- end
end
end
diff --git a/lib/asciidoctor/cli/invoker.rb b/lib/asciidoctor/cli/invoker.rb
index 08a687d..5055e24 100644
--- a/lib/asciidoctor/cli/invoker.rb
+++ b/lib/asciidoctor/cli/invoker.rb
@@ -13,12 +13,13 @@ module Asciidoctor
@err = nil
@code = 0
options = options.flatten
- if (first_option = options[0]).is_a?(Cli::Options)
+ case (first_option = options[0])
+ when Options
@options = first_option
- elsif first_option.is_a?(::Hash)
- @options = Cli::Options.new(options)
+ when ::Hash
+ @options = Options.new options
else
- if (result = Cli::Options.parse! options).is_a? ::Integer
+ if ::Integer === (result = Options.parse! options)
@code = result
@options = nil
else
diff --git a/lib/asciidoctor/cli/options.rb b/lib/asciidoctor/cli/options.rb
index 82db4e5..2932158 100644
--- a/lib/asciidoctor/cli/options.rb
+++ b/lib/asciidoctor/cli/options.rb
@@ -243,7 +243,7 @@ Example: asciidoctor -b html5 source.asciidoc
os.puts %(Asciidoctor #{::Asciidoctor::VERSION} [http://asciidoctor.org])
if RUBY_VERSION >= '1.9.3'
encoding_info = {'lc' => 'locale', 'fs' => 'filesystem', 'in' => 'internal', 'ex' => 'external'}.map do |k,v|
- %(#{k}:#{Encoding.find(v) || '-'})
+ %(#{k}:#{::Encoding.find(v) || '-'})
end
os.puts %(Runtime Environment (#{RUBY_DESCRIPTION}) (#{encoding_info * ' '}))
else
diff --git a/lib/asciidoctor/converter/docbook5.rb b/lib/asciidoctor/converter/docbook5.rb
index b176a06..060c429 100644
--- a/lib/asciidoctor/converter/docbook5.rb
+++ b/lib/asciidoctor/converter/docbook5.rb
@@ -388,7 +388,7 @@ module Asciidoctor
has_body = false
result = []
pgwide_attribute = (node.option? 'pgwide') ? ' pgwide="1"' : nil
- result << %(<#{tag_name = node.title? ? 'table' : 'informaltable'}#{common_attributes node.id, node.role, node.reftext}#{pgwide_attribute} frame="#{node.attr 'frame', 'all'}" rowsep="#{['none', 'cols'].include?(node.attr 'grid') ? 0 : 1}" colsep="#{['none', 'rows'].include?(node.attr 'grid') ? 0 : 1}">)
+ result << %(<#{tag_name = node.title? ? 'table' : 'informaltable'}#{common_attributes node.id, node.role, node.reftext}#{pgwide_attribute} frame="#{node.attr 'frame', 'all'}" rowsep="#{['none', 'cols'].include?(node.attr 'grid') ? 0 : 1}" colsep="#{['none', 'rows'].include?(node.attr 'grid') ? 0 : 1}"#{(node.attr? 'orientation', 'landscape', nil) ? ' orient="land"' : nil}>)
if (node.option? 'unbreakable')
result << '<?dbfo keep-together="always"?>'
elsif (node.option? 'breakable')
diff --git a/lib/asciidoctor/converter/factory.rb b/lib/asciidoctor/converter/factory.rb
index c6d84d1..c74616f 100644
--- a/lib/asciidoctor/converter/factory.rb
+++ b/lib/asciidoctor/converter/factory.rb
@@ -184,11 +184,7 @@ module Asciidoctor
# Returns the [Converter] object
def create backend, opts = {}
if (converter = resolve backend)
- if converter.is_a? ::Class
- return converter.new backend, opts
- else
- return converter
- end
+ return ::Class === converter ? (converter.new backend, opts) : converter
end
base_converter = case backend
diff --git a/lib/asciidoctor/converter/html5.rb b/lib/asciidoctor/converter/html5.rb
index 2aeebcc..42116b9 100644
--- a/lib/asciidoctor/converter/html5.rb
+++ b/lib/asciidoctor/converter/html5.rb
@@ -19,7 +19,7 @@ module Asciidoctor
#:latexmath => INLINE_MATH_DELIMITERS[:latexmath] + [false]
}).default = [nil, nil, nil]
- SvgPreambleRx = /\A.*?(?=<svg[ >])/m
+ SvgPreambleRx = /\A.*?(?=<svg\b)/m
SvgStartTagRx = /\A<svg[^>]*>/
DimensionAttributeRx = /\s(?:width|height|style)=(["']).*?\1/
@@ -74,7 +74,7 @@ module Asciidoctor
if node.attr? 'icons', 'font'
if node.attr? 'iconfont-remote'
- result << %(<link rel="stylesheet" href="#{node.attr 'iconfont-cdn', %[#{cdn_base}/font-awesome/4.5.0/css/font-awesome.min.css]}"#{slash}>)
+ result << %(<link rel="stylesheet" href="#{node.attr 'iconfont-cdn', %[#{cdn_base}/font-awesome/4.6.3/css/font-awesome.min.css]}"#{slash}>)
else
iconfont_stylesheet = %(#{node.attr 'iconfont-name', 'font-awesome'}.css)
result << %(<link rel="stylesheet" href="#{node.normalize_web_path iconfont_stylesheet, (node.attr 'stylesdir', ''), false}"#{slash}>)
@@ -220,7 +220,7 @@ module Asciidoctor
if node.attr? 'stem'
eqnums_val = node.attr 'eqnums', 'none'
- eqnums_val = 'AMS' if eqnums_val == ''
+ eqnums_val = 'AMS' if eqnums_val.empty?
eqnums_opt = %( equationNumbers: { autoNumber: "#{eqnums_val}" } )
# IMPORTANT inspect calls on delimiter arrays are intentional for JavaScript compat (emulates JSON.stringify)
result << %(<script type="text/x-mathjax-config">
@@ -321,15 +321,18 @@ MathJax.Hub.Config({
htag = %(h#{slevel + 1})
id_attr = anchor = link_start = link_end = nil
if node.id
- id_attr = %( id="#{node.id}")
- if node.document.attr? 'sectanchors'
- anchor = %(<a class="anchor" href="##{node.id}"></a>)
+ id_attr = %( id="#{id = node.id}")
+ if (doc = node.document).attr? 'sectanchors'
+ anchor = %(<a class="anchor" href="##{id}"></a>)
# possible idea - anchor icons GitHub-style
- #if node.document.attr? 'icons', 'font'
- # anchor = %(<a class="anchor" href="##{node.id}"><i class="fa fa-anchor"></i></a>)
+ #if doc.attr? 'icons', 'font'
+ # anchor = %(<a class="anchor" href="##{id}"><i class="fa fa-anchor"></i></a>)
#else
- elsif node.document.attr? 'sectlinks'
- link_start = %(<a class="link" href="##{node.id}">)
+ # anchor = %(<a class="anchor" href="##{id}"></a>)
+ #end
+ end
+ if doc.attr? 'sectlinks'
+ link_start = %(<a class="link" href="##{id}">)
link_end = '</a>'
end
end
@@ -377,9 +380,9 @@ MathJax.Hub.Config({
end
def audio node
- xml = node.document.attr? 'htmlsyntax', 'xml'
+ xml = @xml_mode
id_attribute = node.id ? %( id="#{node.id}") : nil
- classes = ['audioblock', node.style, node.role].compact
+ classes = ['audioblock', node.role].compact
class_attribute = %( class="#{classes * ' '}")
title_element = node.title? ? %(<div class="title">#{node.captioned_title}</div>\n) : nil
%(<div#{id_attribute}#{class_attribute}>
@@ -537,7 +540,7 @@ Your browser does not support the audio tag.
target = node.attr 'target'
width_attr = (node.attr? 'width') ? %( width="#{node.attr 'width'}") : nil
height_attr = (node.attr? 'height') ? %( height="#{node.attr 'height'}") : nil
- if ((node.attr? 'format', 'svg', false) || (target.include? '.svg')) && node.document.safe < SafeMode::SECURE
+ if ((node.attr? 'format', 'svg', false) || (target.include? '.svg')) && node.document.safe < SafeMode::SECURE &&
((svg = (node.option? 'inline')) || (obj = (node.option? 'interactive')))
if svg
img = (read_svg_contents node, target) || %(<span class="alt">#{node.attr 'alt'}</span>)
@@ -551,7 +554,7 @@ Your browser does not support the audio tag.
img = %(<a class="image" href="#{link}">#{img}</a>)
end
id_attr = node.id ? %( id="#{node.id}") : nil
- classes = ['imageblock', node.style, node.role].compact
+ classes = ['imageblock', node.role].compact
class_attr = %( class="#{classes * ' '}")
styles = []
styles << %(text-align: #{node.attr 'align'}) if node.attr? 'align'
@@ -645,7 +648,8 @@ Your browser does not support the audio tag.
type_attribute = (keyword = node.list_marker_keyword) ? %( type="#{keyword}") : nil
start_attribute = (node.attr? 'start') ? %( start="#{node.attr 'start'}") : nil
- result << %(<ol class="#{node.style}"#{type_attribute}#{start_attribute}>)
+ reversed_attribute = (node.option? 'reversed') ? (append_boolean_attribute 'reversed', @xml_mode) : nil
+ result << %(<ol class="#{node.style}"#{type_attribute}#{start_attribute}#{reversed_attribute}>)
node.items.each do |item|
result << '<li>'
@@ -666,19 +670,19 @@ Your browser does not support the audio tag.
''
else
id_attr = node.id ? %( id="#{node.id}") : nil
- title_el = node.title? ? %(<div class="title">#{node.title}</div>) : nil
+ title_el = node.title? ? %(<div class="title">#{node.title}</div>\n) : nil
%(<div#{id_attr} class="quoteblock abstract#{(role = node.role) && " #{role}"}">
#{title_el}<blockquote>
#{node.content}
</blockquote>
</div>)
end
- elsif style == 'partintro' && (node.level != 0 || node.parent.context != :section || node.document.doctype != 'book')
+ elsif style == 'partintro' && (node.level > 0 || node.parent.context != :section || node.document.doctype != 'book')
warn 'asciidoctor: ERROR: partintro block can only be used when doctype is book and it\'s a child of a book part. Excluding block content.'
''
else
id_attr = node.id ? %( id="#{node.id}") : nil
- title_el = node.title? ? %(<div class="title">#{node.title}</div>) : nil
+ title_el = node.title? ? %(<div class="title">#{node.title}</div>\n) : nil
%(<div#{id_attr} class="openblock#{style && style != 'open' ? " #{style}" : ''}#{(role = node.role) && " #{role}"}">
#{title_el}<div class="content">
#{node.content}
@@ -766,11 +770,11 @@ Your browser does not support the audio tag.
id_attribute = node.id ? %( id="#{node.id}") : nil
classes = ['tableblock', %(frame-#{node.attr 'frame', 'all'}), %(grid-#{node.attr 'grid', 'all'})]
styles = []
- unless node.option? 'autowidth'
- if (tablepcwidth = node.attr 'tablepcwidth') == 100
+ unless (node.option? 'autowidth') && !(node.attr? 'width', nil, false)
+ if node.attr? 'tablepcwidth', 100
classes << 'spread'
else
- styles << %(width: #{tablepcwidth}%;)
+ styles << %(width: #{node.attr 'tablepcwidth'}%;)
end
end
if (role = node.role)
@@ -867,7 +871,7 @@ Your browser does not support the audio tag.
div_classes.insert 1, 'checklist'
ul_class_attribute = ' class="checklist"'
if node.option? 'interactive'
- if node.document.attr? 'htmlsyntax', 'xml'
+ if @xml_mode
marker_checked = '<input type="checkbox" data-item-complete="1" checked="checked"/> '
marker_unchecked = '<input type="checkbox" data-item-complete="0"/> '
else
@@ -927,9 +931,9 @@ Your browser does not support the audio tag.
end
def video node
- xml = node.document.attr? 'htmlsyntax', 'xml'
+ xml = @xml_mode
id_attribute = node.id ? %( id="#{node.id}") : nil
- classes = ['videoblock', node.style, node.role].compact
+ classes = ['videoblock', node.role].compact
class_attribute = %( class="#{classes * ' '}")
title_element = node.title? ? %(\n<div class="title">#{node.captioned_title}</div>) : nil
width_attribute = (node.attr? 'width') ? %( width="#{node.attr 'width'}") : nil
@@ -1070,7 +1074,7 @@ Your browser does not support the video tag.
def inline_image node
if (type = node.type) == 'icon' && (node.document.attr? 'icons', 'font')
class_attr_val = %(fa fa-#{node.target})
- {'size' => 'fa-', 'rotate' => 'fa-rotate-', 'flip' => 'fa-flip-'}.each do |(key, prefix)|
+ {'size' => 'fa-', 'rotate' => 'fa-rotate-', 'flip' => 'fa-flip-'}.each do |key, prefix|
class_attr_val = %(#{class_attr_val} #{prefix}#{node.attr key}) if node.attr? key
end
title_attr = (node.attr? 'title') ? %( title="#{node.attr 'title'}") : nil
@@ -1146,16 +1150,17 @@ Your browser does not support the video tag.
def read_svg_contents node, target
if (svg = node.read_contents target, :start => (node.document.attr 'imagesdir'), :normalize => true, :label => 'SVG')
- svg = svg.sub SvgPreambleRx, ''
- start_tag = nil
+ svg = svg.sub SvgPreambleRx, '' unless svg.start_with? '<svg'
+ old_start_tag = new_start_tag = nil
+ # NOTE width, height and style attributes are removed if either width or height is specified
['width', 'height'].each do |dim|
if node.attr? dim
- # NOTE width, height and style attributes are removed if either width or height is specified
- start_tag ||= (svg.match SvgStartTagRx)[0].gsub DimensionAttributeRx, ''
- start_tag = %(#{start_tag.chop} #{dim}="#{node.attr dim}px">)
+ new_start_tag = (old_start_tag = (svg.match SvgStartTagRx)[0]).gsub DimensionAttributeRx, '' unless new_start_tag
+ # QUESTION should we add px since it's already the default?
+ new_start_tag = %(#{new_start_tag.chop} #{dim}="#{node.attr dim}px">)
end
end
- svg = svg.sub SvgStartTagRx, start_tag if start_tag
+ svg = %(#{new_start_tag}#{svg[old_start_tag.length..-1]}) if new_start_tag
end
svg
end
diff --git a/lib/asciidoctor/converter/manpage.rb b/lib/asciidoctor/converter/manpage.rb
index d745f8b..238f7d9 100644
--- a/lib/asciidoctor/converter/manpage.rb
+++ b/lib/asciidoctor/converter/manpage.rb
@@ -14,6 +14,13 @@ module Asciidoctor
ESC_BS = %(#{ESC}\\) # escaped backslash (indicates troff formatting sequence)
ESC_FS = %(#{ESC}.) # escaped full stop (indicates troff macro)
+ LiteralBackslashRx = /(?:\A|[^#{ESC}])\\/
+ LeadingPeriodRx = /^\./
+ EscapedMacroRx = /^(?:#{ESC}\\c\n)?#{ESC}\.((?:URL|MTO) ".*?" ".*?" )( |[^\s]*)(.*?)(?: *#{ESC}\\c)?$/
+ MockBoundaryRx = /<\/?BOUNDARY>/
+ EmDashCharRefRx = /—(?:;)?/
+ EllipsisCharRefRx = /…(?:)?/
+
# Converts HTML entity references back to their original form, escapes
# special man characters and strips trailing whitespace.
#
@@ -26,12 +33,10 @@ module Asciidoctor
# * :append_newline a Boolean that indicates whether to append an endline to the result (default: false)
def manify str, opts = {}
str = ((opts.fetch :preserve_space, true) ? (str.gsub TAB, ET) : (str.tr_s WHITESPACE, ' ')).
- gsub(/(?:\A|[^#{ESC}])\\/, '\&(rs'). # literal backslash (not a troff escape sequence)
- gsub(/^\./, '\\\&.'). # leading . is used in troff for macro call or other formatting; replace with \&.
+ gsub(LiteralBackslashRx, '\&(rs'). # literal backslash (not a troff escape sequence)
+ gsub(LeadingPeriodRx, '\\\&.'). # leading . is used in troff for macro call or other formatting; replace with \&.
# drop orphaned \c escape lines, unescape troff macro, quote adjacent character, isolate macro line
- gsub(/^(?:#{ESC}\\c\n)?#{ESC}\.((?:URL|MTO) ".*?" ".*?" )( |[^\s]*)(.*?)(?: *#{ESC}\\c)?$/) {
- (rest = $3.lstrip).empty? ? %(.#$1"#$2") : %(.#$1"#$2"#{LF}#{rest})
- }.
+ gsub(EscapedMacroRx) { (rest = $3.lstrip).empty? ? %(.#$1"#$2") : %(.#$1"#$2"#{LF}#{rest}) }.
gsub('-', '\-').
gsub('<', '<').
gsub('>', '>').
@@ -41,20 +46,20 @@ module Asciidoctor
gsub('™', '\(tm'). # trademark sign
gsub(' ', ' '). # thin space
gsub('–', '\(en'). # en dash
- gsub(/—(?:;)?/, '\(em'). # em dash
+ gsub(EmDashCharRefRx, '\(em'). # em dash
gsub('‘', '\(oq'). # left single quotation mark
gsub('’', '\(cq'). # right single quotation mark
gsub('“', '\(lq'). # left double quotation mark
gsub('”', '\(rq'). # right double quotation mark
- gsub(/…(?:)?/, '...'). # horizontal ellipsis
+ gsub(EllipsisCharRefRx, '...'). # horizontal ellipsis
gsub('←', '\(<-'). # leftwards arrow
gsub('→', '\(->'). # rightwards arrow
gsub('⇐', '\(lA'). # leftwards double arrow
gsub('⇒', '\(rA'). # rightwards double arrow
gsub('', '\:'). # zero width space
gsub('\'', '\(aq'). # apostrophe-quote
- gsub(/<\/?BOUNDARY>/, '').# artificial boundary
- gsub(ESC_BS, '\\'). # unescape troff backslash (NOTE update if more escaped are added)
+ gsub(MockBoundaryRx, ''). # mock boundary
+ gsub(ESC_BS, '\\'). # unescape troff backslash (NOTE update if more escapes are added)
rstrip # strip trailing space
opts[:append_newline] ? %(#{str}#{LF}) : str
end
diff --git a/lib/asciidoctor/converter/template.rb b/lib/asciidoctor/converter/template.rb
index b9e108a..4308dfd 100644
--- a/lib/asciidoctor/converter/template.rb
+++ b/lib/asciidoctor/converter/template.rb
@@ -246,20 +246,24 @@ module Asciidoctor
elsif name.start_with? 'block_'
name = name[6..-1]
end
- ext_name = path_segments[-1]
+
template_class = ::Tilt
extra_engine_options = {}
- if ext_name == 'slim'
+ case (ext_name = path_segments[-1])
+ when 'slim'
# slim doesn't get loaded by Tilt, so we have to load it explicitly
Helpers.require_library 'slim' unless defined? ::Slim
# align safe mode of AsciiDoc embedded in Slim template with safe mode of current document
(@engine_options[:slim][:asciidoc] ||= {})[:safe] ||= @safe if @safe && ::Slim::VERSION >= '3.0'
# load include plugin when using Slim >= 2.1
require 'slim/include' unless (defined? ::Slim::Include) || ::Slim::VERSION < '2.1'
- elsif ext_name == 'erb'
+ when 'erb'
template_class, extra_engine_options = (eruby_loaded ||= load_eruby(@eruby))
+ when 'rb'
+ next
+ else
+ next unless ::Tilt.registered? ext_name
end
- next unless ::Tilt.registered? ext_name
unless template_cache && (template = template_cache[file])
template = template_class.new file, 1, (@engine_options[ext_name.to_sym] || {}).merge(extra_engine_options)
end
diff --git a/lib/asciidoctor/core_ext.rb b/lib/asciidoctor/core_ext.rb
index 5f2fdbc..a3e2b73 100644
--- a/lib/asciidoctor/core_ext.rb
+++ b/lib/asciidoctor/core_ext.rb
@@ -1,7 +1,8 @@
-require 'asciidoctor/core_ext/object/nil_or_empty'
-unless RUBY_ENGINE == 'opal'
- unless RUBY_MIN_VERSION_1_9
- require 'asciidoctor/core_ext/string/chr'
- require 'asciidoctor/core_ext/symbol/length'
- end
+require 'asciidoctor/core_ext/nil_or_empty'
+if RUBY_MIN_VERSION_1_9
+ require 'asciidoctor/core_ext/string/limit'
+elsif RUBY_ENGINE != 'opal'
+ require 'asciidoctor/core_ext/1.8.7/string/chr'
+ require 'asciidoctor/core_ext/1.8.7/string/limit'
+ require 'asciidoctor/core_ext/1.8.7/symbol/length'
end
diff --git a/lib/asciidoctor/core_ext/string/chr.rb b/lib/asciidoctor/core_ext/1.8.7/string/chr.rb
similarity index 73%
rename from lib/asciidoctor/core_ext/string/chr.rb
rename to lib/asciidoctor/core_ext/1.8.7/string/chr.rb
index 8592ee6..b9b9c92 100644
--- a/lib/asciidoctor/core_ext/string/chr.rb
+++ b/lib/asciidoctor/core_ext/1.8.7/string/chr.rb
@@ -2,5 +2,5 @@
class String
def chr
self[0..0]
- end unless respond_to? :chr
+ end unless method_defined? :chr
end
diff --git a/lib/asciidoctor/core_ext/1.8.7/string/limit.rb b/lib/asciidoctor/core_ext/1.8.7/string/limit.rb
new file mode 100644
index 0000000..c778bae
--- /dev/null
+++ b/lib/asciidoctor/core_ext/1.8.7/string/limit.rb
@@ -0,0 +1,28 @@
+if RUBY_ENGINE_JRUBY
+ class String
+ # Safely truncate the string to the specified number of bytes.
+ # If a multibyte char gets split, the dangling fragment is removed.
+ def limit size
+ return self unless size < bytesize
+ result = (unpack %(a#{size}))[0]
+ begin
+ result.unpack 'U*'
+ rescue ArgumentError
+ result.chop!
+ retry
+ end
+ result
+ end unless method_defined? :limit
+ end
+else
+ class String
+ # Safely truncate the string to the specified number of bytes.
+ # If a multibyte char gets split, the dangling fragment is removed.
+ def limit size
+ return self unless size < bytesize
+ result = (unpack %(a#{size}))[0]
+ result.chop! until result.empty? || /.$/u =~ result
+ result
+ end unless method_defined? :limit
+ end
+end
diff --git a/lib/asciidoctor/core_ext/symbol/length.rb b/lib/asciidoctor/core_ext/1.8.7/symbol/length.rb
similarity index 72%
rename from lib/asciidoctor/core_ext/symbol/length.rb
rename to lib/asciidoctor/core_ext/1.8.7/symbol/length.rb
index 7e35bfd..c51de6f 100644
--- a/lib/asciidoctor/core_ext/symbol/length.rb
+++ b/lib/asciidoctor/core_ext/1.8.7/symbol/length.rb
@@ -2,5 +2,5 @@
class Symbol
def length
to_s.length
- end unless respond_to? :length
+ end unless method_defined? :length
end
diff --git a/lib/asciidoctor/core_ext/nil_or_empty.rb b/lib/asciidoctor/core_ext/nil_or_empty.rb
new file mode 100644
index 0000000..7e3f79a
--- /dev/null
+++ b/lib/asciidoctor/core_ext/nil_or_empty.rb
@@ -0,0 +1,23 @@
+# A core library extension that defines the method nil_or_empty? as an alias to
+# optimize checks for nil? or empty? on common object types such as NilClass,
+# String, Array, Hash, and Numeric.
+
+class NilClass
+ alias :nil_or_empty? :nil? unless method_defined? :nil_or_empty?
+end
+
+class String
+ alias :nil_or_empty? :empty? unless method_defined? :nil_or_empty?
+end
+
+class Array
+ alias :nil_or_empty? :empty? unless method_defined? :nil_or_empty?
+end
+
+class Hash
+ alias :nil_or_empty? :empty? unless method_defined? :nil_or_empty?
+end
+
+class Numeric
+ alias :nil_or_empty? :nil? unless method_defined? :nil_or_empty?
+end
diff --git a/lib/asciidoctor/core_ext/object/nil_or_empty.rb b/lib/asciidoctor/core_ext/object/nil_or_empty.rb
deleted file mode 100644
index 029ac61..0000000
--- a/lib/asciidoctor/core_ext/object/nil_or_empty.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# A core library extension that defines the method nil_or_empty? as an alias to
-# optimize checks for nil? or empty? on common object types such as NilClass,
-# String, Array and Hash.
-
-class NilClass
- alias :nil_or_empty? :nil? unless respond_to? :nil_or_empty?
-end
-
-class String
- alias :nil_or_empty? :empty? unless respond_to? :nil_or_empty?
-end
-
-class Array
- alias :nil_or_empty? :empty? unless respond_to? :nil_or_empty?
-end
-
-class Hash
- alias :nil_or_empty? :empty? unless respond_to? :nil_or_empty?
-end
-
-class Numeric
- alias :nil_or_empty? :nil? unless respond_to? :nil_or_empty?
-end
diff --git a/lib/asciidoctor/core_ext/string/limit.rb b/lib/asciidoctor/core_ext/string/limit.rb
new file mode 100644
index 0000000..8a20d54
--- /dev/null
+++ b/lib/asciidoctor/core_ext/string/limit.rb
@@ -0,0 +1,10 @@
+class String
+ # Safely truncate the string to the specified number of bytes.
+ # If a multibyte char gets split, the dangling fragment is removed.
+ def limit size
+ return self unless size < bytesize
+ # NOTE JRuby 1.7 & Rubinius fail to detect invalid encoding unless encoding is forced; impact is marginal.
+ size -= 1 until ((result = byteslice 0, size).force_encoding ::Encoding::UTF_8).valid_encoding?
+ result
+ end unless method_defined? :limit
+end
diff --git a/lib/asciidoctor/document.rb b/lib/asciidoctor/document.rb
index 65d4e50..4004891 100644
--- a/lib/asciidoctor/document.rb
+++ b/lib/asciidoctor/document.rb
@@ -225,7 +225,7 @@ class Document < AbstractBlock
# safely resolve the safe mode from const, int or string
if !(safe_mode = options[:safe])
@safe = SafeMode::SECURE
- elsif ::Fixnum === safe_mode
+ elsif ::Integer === safe_mode
# be permissive in case API user wants to define new levels
@safe = safe_mode
else
@@ -236,8 +236,8 @@ class Document < AbstractBlock
@safe = SafeMode::SECURE
end
end
+ @compat_mode = attr_overrides.key? 'compat-mode'
@sourcemap = options[:sourcemap]
- @compat_mode = false
@converter = nil
initialize_extensions = defined? ::Asciidoctor::Extensions
@extensions = nil # initialize furthur down
@@ -287,7 +287,7 @@ class Document < AbstractBlock
attr_overrides['asciidoctor'] = ''
attr_overrides['asciidoctor-version'] = VERSION
- safe_mode_name = SafeMode.constants.detect {|l| SafeMode.const_get(l) == @safe }.to_s.downcase
+ safe_mode_name = SafeMode.constants.find {|l| SafeMode.const_get(l) == @safe }.to_s.downcase
attr_overrides['safe-mode-name'] = safe_mode_name
attr_overrides["safe-mode-#{safe_mode_name}"] = ''
attr_overrides['safe-mode-level'] = @safe
@@ -295,14 +295,11 @@ class Document < AbstractBlock
# sync the embedded attribute w/ the value of options...do not allow override
attr_overrides['embedded'] = header_footer ? nil : ''
- # the only way to set the max-include-depth attribute is via the document options
- # 64 is the AsciiDoc default
+ # the only way to set the max-include-depth attribute is via the API; default to 64 like AsciiDoc Python
attr_overrides['max-include-depth'] ||= 64
- # the only way to enable uri reads is via the document options, disabled by default
- unless !attr_overrides['allow-uri-read'].nil?
- attr_overrides['allow-uri-read'] = nil
- end
+ # the only way to set the allow-uri-read attribute is via the API; disabled by default
+ attr_overrides['allow-uri-read'] ||= nil
attr_overrides['user-home'] = USER_HOME
@@ -344,6 +341,7 @@ class Document < AbstractBlock
attr_overrides['docdir'] = ''
attr_overrides['user-home'] = '.'
if @safe >= SafeMode::SECURE
+ attr_overrides['max-attribute-value-size'] = 4096 unless attr_overrides.key? 'max-attribute-value-size'
# assign linkcss (preventing css embedding) unless explicitly disabled from the commandline or API
# effectively the same has "has key 'linkcss' and value == nil"
unless attr_overrides.fetch('linkcss', '').nil?
@@ -354,6 +352,9 @@ class Document < AbstractBlock
end
end
+ # the only way to set the max-attribute-value-size attribute is via the API; disabled by default
+ @max_attribute_value_size = (val = (attr_overrides['max-attribute-value-size'] ||= nil)) ? val.to_i.abs : nil
+
attr_overrides.delete_if do |key, val|
verdict = false
# a nil value undefines the attribute
@@ -371,8 +372,6 @@ class Document < AbstractBlock
verdict
end
- @compat_mode = true if attrs.key? 'compat-mode'
-
if parent_doc
# setup default doctype (backend is fixed)
attrs['doctype'] ||= DEFAULT_DOCTYPE
@@ -401,13 +400,15 @@ class Document < AbstractBlock
#attrs['infile'] = attrs['docfile']
# dynamic intrinstic attribute values
- now = ::Time.now
+
+ # See https://reproducible-builds.org/specs/source-date-epoch/
+ now = ::ENV['SOURCE_DATE_EPOCH'] ? (::Time.at ::ENV['SOURCE_DATE_EPOCH'].to_i).utc : ::Time.now
localdate = (attrs['localdate'] ||= now.strftime('%Y-%m-%d'))
unless (localtime = attrs['localtime'])
begin
localtime = attrs['localtime'] = now.strftime('%H:%M:%S %Z')
- rescue
- localtime = attrs['localtime'] = now.strftime('%H:%M:%S')
+ rescue # Asciidoctor.js fails if timezone string has characters outside basic Latin (see asciidoctor.js#23)
+ localtime = attrs['localtime'] = now.strftime('%H:%M:%S %z')
end
end
attrs['localdatetime'] ||= %(#{localdate} #{localtime})
@@ -679,7 +680,7 @@ class Document < AbstractBlock
# QUESTION move to AbstractBlock?
def first_section
- has_header? ? @header : (@blocks || []).detect{|e| e.context == :section }
+ has_header? ? @header : (@blocks || []).find {|e| e.context == :section }
end
def has_header?
@@ -835,13 +836,18 @@ class Document < AbstractBlock
if attribute_locked?(name)
false
else
+ if @max_attribute_value_size
+ resolved_value = (apply_attribute_value_subs value).limit @max_attribute_value_size
+ else
+ resolved_value = apply_attribute_value_subs value
+ end
case name
when 'backend'
- update_backend_attributes apply_attribute_value_subs(value), !!@attributes_modified.delete?('htmlsyntax')
+ update_backend_attributes resolved_value, !!@attributes_modified.delete?('htmlsyntax')
when 'doctype'
- update_doctype_attributes apply_attribute_value_subs(value)
+ update_doctype_attributes resolved_value
else
- @attributes[name] = apply_attribute_value_subs(value)
+ @attributes[name] = resolved_value
end
@attributes_modified << name
true
@@ -1110,17 +1116,18 @@ class Document < AbstractBlock
# attribute is set, read the doc-name.docinfo.ext file. If the docinfo2
# attribute is set, read both files in that order.
#
- # location - The Symbol location of the docinfo, either :header or :footer. (default: :header)
- # ext - The extension of the docinfo file(s). If not set, the extension
- # will be determined based on the basebackend. (default: nil)
+ # location - The Symbol location of the docinfo (e.g., :head, :footer, etc). (default: :head)
+ # suffix - The suffix of the docinfo file(s). If not set, the extension
+ # will be set to the outfilesuffix. (default: nil)
#
- # returns The contents of the docinfo file(s)
- def docinfo(location = :head, ext = nil)
+ # returns The contents of the docinfo file(s) or empty string if no files are
+ # found or the safe mode is secure or greater.
+ def docinfo location = :head, suffix = nil
if safe >= SafeMode::SECURE
''
else
- qualifier = (location == :footer ? '-footer' : nil)
- ext = @outfilesuffix unless ext
+ qualifier = location == :head ? nil : %(-#{location})
+ suffix = @outfilesuffix unless suffix
docinfodir = @attributes['docinfodir']
content = nil
@@ -1138,7 +1145,7 @@ class Document < AbstractBlock
end
if docinfo
- docinfo_filename = %(docinfo#{qualifier}#{ext})
+ docinfo_filename = %(docinfo#{qualifier}#{suffix})
unless (docinfo & ['shared', %(shared-#{location})]).empty?
docinfo_path = normalize_system_path(docinfo_filename, docinfodir)
# NOTE normalizing the lines is essential if we're performing substitutions
diff --git a/lib/asciidoctor/extensions.rb b/lib/asciidoctor/extensions.rb
index 752e158..7e86d5a 100644
--- a/lib/asciidoctor/extensions.rb
+++ b/lib/asciidoctor/extensions.rb
@@ -106,16 +106,16 @@ module Extensions
# Public: Parses blocks in the content and attaches the block to the parent.
#
- # Returns nothing
+ # Returns The parent node into which the blocks are parsed.
#--
# QUESTION is parse_content the right method name? should we wrap in open block automatically?
- def parse_content parent, content, attributes = {}
- reader = (content.is_a? Reader) ? content : (Reader.new content)
+ def parse_content parent, content, attributes = nil
+ reader = Reader === content ? content : (Reader.new content)
while reader.has_more_lines?
- block = Parser.next_block reader, parent, attributes
+ block = Parser.next_block reader, parent, (attributes ? attributes.dup : {})
parent << block if block
end
- nil
+ parent
end
# TODO fill out remaining methods
@@ -145,7 +145,7 @@ module Extensions
def process *args, &block
# need to check for both block/proc and lambda
# TODO need test for this!
- #if block_given? || (args.size == 1 && ((block = args[0]).is_a? ::Proc))
+ #if block_given? || (args.size == 1 && ::Proc === (block = args[0]))
if block_given?
@process_block = block
elsif @process_block
@@ -326,7 +326,7 @@ module Extensions
# FIXME this isn't the prettiest thing
def named value
- if self.is_a? Processor
+ if Processor === self
@name = value
else
option :name, value
@@ -379,7 +379,7 @@ module Extensions
# QUESTION perhaps include a SyntaxDsl?
def named value
- if self.is_a? Processor
+ if Processor === self
@name = value
else
option :name, value
@@ -803,7 +803,7 @@ module Extensions
def docinfo_processors? location = nil
if @docinfo_processor_extensions
if location
- @docinfo_processor_extensions.find {|ext| ext.config[:location] == location }
+ @docinfo_processor_extensions.any? {|ext| ext.config[:location] == location }
else
true
end
@@ -1133,7 +1133,7 @@ module Extensions
else
processor, config = resolve_args args, 2
# style 2: specified as class or class name
- if (processor.is_a? ::Class) || ((processor.is_a? ::String) && (processor = Extensions.class_for_name processor))
+ if ::Class === processor || (::String === processor && (processor = Extensions.class_for_name processor))
unless processor < kind_class || (kind_java_class && processor < kind_java_class)
raise ::ArgumentError.new %(Invalid type for #{kind_name} extension: #{processor})
end
@@ -1141,7 +1141,7 @@ module Extensions
processor_instance.freeze
ProcessorExtension.new kind, processor_instance
# style 3: specified as instance
- elsif (processor.is_a? kind_class) || (kind_java_class && (processor.is_a? kind_java_class))
+ elsif kind_class === processor || (kind_java_class && kind_java_class === processor)
processor.update_config config
processor.freeze
ProcessorExtension.new kind, processor
@@ -1190,7 +1190,7 @@ module Extensions
else
processor, name, config = resolve_args args, 3
# style 2: specified as class or class name
- if (processor.is_a? ::Class) || ((processor.is_a? ::String) && (processor = Extensions.class_for_name processor))
+ if ::Class === processor || (::String === processor && (processor = Extensions.class_for_name processor))
unless processor < kind_class || (kind_java_class && processor < kind_java_class)
raise ::ArgumentError.new %(Class specified for #{kind_name} extension does not inherit from #{kind_class}: #{processor})
end
@@ -1201,7 +1201,7 @@ module Extensions
processor.freeze
kind_store[name] = ProcessorExtension.new kind, processor_instance
# style 3: specified as instance
- elsif (processor.is_a? kind_class) || (kind_java_class && (processor.is_a? kind_java_class))
+ elsif kind_class === processor || (kind_java_class && kind_java_class === processor)
processor.update_config config
# TODO need a test for this override!
unless (name = name ? (processor.name = as_symbol name) : (as_symbol processor.name))
@@ -1216,7 +1216,7 @@ module Extensions
end
def resolve_args args, expect
- opts = (args[-1].is_a? ::Hash) ? args.pop : {}
+ opts = ::Hash === args[-1] ? args.pop : {}
return opts if expect == 1
num_args = args.size
if (missing = expect - 1 - num_args) > 0
@@ -1229,7 +1229,7 @@ module Extensions
end
def as_symbol name
- name ? ((name.is_a? ::Symbol) ? name : name.to_sym) : nil
+ name ? name.to_sym : nil
end
end
@@ -1323,7 +1323,7 @@ module Extensions
# unused atm, but tested
def resolve_class object
- (object.is_a? ::Class) ? object : (class_for_name object.to_s)
+ ::Class === object ? object : (class_for_name object.to_s)
end
# Public: Resolves the Class object for the qualified name.
diff --git a/lib/asciidoctor/helpers.rb b/lib/asciidoctor/helpers.rb
index 3b24067..c588c80 100644
--- a/lib/asciidoctor/helpers.rb
+++ b/lib/asciidoctor/helpers.rb
@@ -189,7 +189,7 @@ module Helpers
# Returns the String filename with leading directories removed and, if specified, the extension removed
def self.basename(file_name, drop_extname = false)
if drop_extname
- ::File.basename file_name, ((::File.extname file_name) || '')
+ ::File.basename file_name, (::File.extname file_name)
else
::File.basename file_name
end
diff --git a/lib/asciidoctor/list.rb b/lib/asciidoctor/list.rb
index f14fcb6..d8143da 100644
--- a/lib/asciidoctor/list.rb
+++ b/lib/asciidoctor/list.rb
@@ -43,6 +43,9 @@ end
# Public: Methods for managing items for AsciiDoc olists, ulist, and dlists.
class ListItem < AbstractBlock
+ # A contextual alias for the list parent node; counterpart to the items alias on List
+ alias :list :parent
+
# Public: Get/Set the String used to mark this list item
attr_accessor :marker
diff --git a/lib/asciidoctor/parser.rb b/lib/asciidoctor/parser.rb
index df97104..b73b6f2 100644
--- a/lib/asciidoctor/parser.rb
+++ b/lib/asciidoctor/parser.rb
@@ -437,7 +437,7 @@ class Parser
else
block_extensions = block_macro_extensions = false
end
- #parent_context = parent.is_a?(Block) ? parent.context : nil
+ #parent_context = Block === parent ? parent.context : nil
in_list = ListItem === parent
block = nil
style = nil
@@ -523,9 +523,11 @@ class Parser
posattrs = []
end
- unless !style || explicit_style
+ # QUESTION why did we make exception for explicit style?
+ #if style && !explicit_style
+ if style
attributes['alt'] = style if blk_ctx == :image
- attributes.delete('style')
+ attributes.delete 'style'
style = nil
end
@@ -633,7 +635,7 @@ class Parser
elsif (match = OrderedListRx.match(this_line))
reader.unshift_line this_line
block = next_outline_list(reader, :olist, parent)
- # QUESTION move this logic to next_outline_list?
+ # TODO move this logic into next_outline_list
if !attributes['style'] && !block.attributes['style']
marker = block.items[0].marker
if marker.start_with? '.'
@@ -641,13 +643,13 @@ class Parser
#attributes['style'] = (ORDERED_LIST_STYLES[block.level - 1] || ORDERED_LIST_STYLES[0]).to_s
attributes['style'] = (ORDERED_LIST_STYLES[marker.length - 1] || ORDERED_LIST_STYLES[0]).to_s
else
- style = ORDERED_LIST_STYLES.detect{|s| OrderedListMarkerRxMap[s] =~ marker }
+ style = ORDERED_LIST_STYLES.find {|s| OrderedListMarkerRxMap[s] =~ marker }
attributes['style'] = (style || ORDERED_LIST_STYLES[0]).to_s
end
end
break
- elsif (match = DefinitionListRx.match(this_line))
+ elsif (match = DescriptionListRx.match(this_line))
reader.unshift_line this_line
block = next_labeled_list(reader, match, parent)
break
@@ -710,7 +712,7 @@ class Parser
adjust_indentation! lines
block = Block.new(parent, :literal, :content_model => :verbatim, :source => lines, :attributes => attributes)
- # a literal gets special meaning inside of a definition list
+ # a literal gets special meaning inside of a description list
# TODO this feels hacky, better way to distinguish from explicit literal block?
block.set_option('listparagraph') if in_list
@@ -901,7 +903,7 @@ class Parser
if block
block.source_location = source_location if source_location
# REVIEW seems like there is a better way to organize this wrap-up
- block.title = attributes['title'] unless block.title?
+ block.title = attributes['title'] unless block.title?
# FIXME HACK don't hardcode logic for alt, caption and scaledwidth on images down here
if block.context == :image
resolved_target = attributes['target']
@@ -1034,7 +1036,7 @@ class Parser
end
end
- # whether a block supports complex content should be a config setting
+ # whether a block supports compound content should be a config setting
# if terminator is false, that means the all the lines in the reader should be parsed
# NOTE could invoke filter in here, before and after parsing
def self.build_block(block_context, content_model, terminator, parent, reader, attributes, options = {})
@@ -1237,7 +1239,7 @@ class Parser
nil
end
- # Internal: Parse and construct a labeled (e.g., definition) list Block from the current position of the Reader
+ # Internal: Parse and construct a description list Block from the current position of the Reader
#
# reader - The Reader from which to retrieve the labeled list
# match - The Regexp match for the head of the list
@@ -1249,7 +1251,7 @@ class Parser
previous_pair = nil
# allows us to capture until we find a labeled item
# that uses the same delimiter (::, :::, :::: or ;;)
- sibling_pattern = DefinitionListSiblingRx[match[2]]
+ sibling_pattern = DescriptionListSiblingRx[match[2]]
# NOTE skip the match on the first time through as we've already done it (emulates begin...while)
while match || (reader.has_more_lines? && (match = sibling_pattern.match(reader.peek_line)))
@@ -1270,12 +1272,12 @@ class Parser
# Internal: Parse and construct the next ListItem for the current bulleted
# (unordered or ordered) list Block, callout lists included, or the next
- # term ListItem and definition ListItem pair for the labeled list Block.
+ # term ListItem and description ListItem pair for the labeled list Block.
#
# First collect and process all the lines that constitute the next list
# item for the parent list (according to its type). Next, parse those lines
# into blocks and associate them with the ListItem (in the case of a
- # labeled list, the definition ListItem). Finally, fold the first block
+ # labeled list, the description ListItem). Finally, fold the first block
# into the item's text attribute according to rules described in ListItem.
#
# reader - The Reader from which to retrieve the next list item
@@ -1370,7 +1372,7 @@ class Parser
# through all the rules that determine what comprises a list item.
#
# Grab lines until a sibling list item is found, or the block is broken by a
- # terminator (such as a line comment). Definition lists are more greedy if
+ # terminator (such as a line comment). Description lists are more greedy if
# they don't have optional inline item text...they want that text
#
# reader - The Reader from which to retrieve the lines.
@@ -1464,7 +1466,7 @@ class Parser
elsif BlockTitleRx =~ this_line || BlockAttributeLineRx =~ this_line || AttributeEntryRx =~ this_line
buffer << this_line
else
- if nested_list_type = (within_nested_list ? [:dlist] : NESTABLE_LIST_CONTEXTS).detect {|ctx| ListRxMap[ctx] =~ this_line }
+ if nested_list_type = (within_nested_list ? [:dlist] : NESTABLE_LIST_CONTEXTS).find {|ctx| ListRxMap[ctx] =~ this_line }
within_nested_list = true
if nested_list_type == :dlist && $~[3].nil_or_empty?
# get greedy again
@@ -1494,7 +1496,7 @@ class Parser
# TODO any way to combine this with the check after skipping blank lines?
if is_sibling_list_item?(this_line, list_type, sibling_trait)
break
- elsif nested_list_type = NESTABLE_LIST_CONTEXTS.detect {|ctx| ListRxMap[ctx] =~ this_line }
+ elsif nested_list_type = NESTABLE_LIST_CONTEXTS.find {|ctx| ListRxMap[ctx] =~ this_line }
buffer << this_line
within_nested_list = true
if nested_list_type == :dlist && $~[3].nil_or_empty?
@@ -1525,7 +1527,7 @@ class Parser
end
else
has_text = true if !this_line.empty?
- if nested_list_type = (within_nested_list ? [:dlist] : NESTABLE_LIST_CONTEXTS).detect {|ctx| ListRxMap[ctx] =~ this_line }
+ if nested_list_type = (within_nested_list ? [:dlist] : NESTABLE_LIST_CONTEXTS).find {|ctx| ListRxMap[ctx] =~ this_line }
within_nested_list = true
if nested_list_type == :dlist && $~[3].nil_or_empty?
# get greedy again
@@ -1818,7 +1820,7 @@ class Parser
# apply header subs and assign to document
author_metadata.each do |key, val|
unless document.attributes.has_key? key
- document.attributes[key] = ((val.is_a? ::String) ? document.apply_header_subs(val) : val)
+ document.attributes[key] = ::String === val ? (document.apply_header_subs val) : val
end
end
@@ -1838,7 +1840,7 @@ class Parser
rev_line = reader.read_line
if (match = RevisionInfoLineRx.match(rev_line))
rev_metadata['revnumber'] = match[1].rstrip if match[1]
- unless (component = match[2].strip) == ''
+ unless (component = match[2].strip).empty?
# version must begin with 'v' if date is absent
if !match[1] && (component.start_with? 'v')
rev_metadata['revnumber'] = component[1..-1]
@@ -1928,7 +1930,7 @@ class Parser
author_entries.each_with_index do |author_entry, idx|
next if author_entry.empty?
key_map = {}
- if idx.zero?
+ if idx == 0
keys.each do |key|
key_map[key.to_sym] = key
end
@@ -1977,7 +1979,7 @@ class Parser
author_metadata[%(#{key}_1)] = author_metadata[key] if author_metadata.has_key? key
end
end
- if idx.zero?
+ if idx == 0
author_metadata['authors'] = author_metadata[key_map[:author]]
else
author_metadata['authors'] = %(#{author_metadata['authors']}, #{author_metadata[key_map[:author]]})
@@ -2193,7 +2195,7 @@ class Parser
#
# Returns the String of the first marker in this number series
def self.resolve_ordered_list_marker(marker, ordinal = 0, validate = false, reader = nil)
- number_style = ORDERED_LIST_STYLES.detect {|s| OrderedListMarkerRxMap[s] =~ marker }
+ number_style = ORDERED_LIST_STYLES.find {|s| OrderedListMarkerRxMap[s] =~ marker }
expected = actual = nil
case number_style
when :arabic
@@ -2247,7 +2249,7 @@ class Parser
# Returns a Boolean indicating whether this line is a sibling list item given
# the criteria provided
def self.is_sibling_list_item?(line, list_type, sibling_trait)
- if sibling_trait.is_a? ::Regexp
+ if ::Regexp === sibling_trait
matcher = sibling_trait
expected_marker = false
else
@@ -2280,25 +2282,27 @@ class Parser
table.assign_caption attributes.delete('caption')
end
- if (attributes.key? 'cols') && !(col_specs = parse_col_specs attributes['cols']).empty?
- table.create_columns col_specs
- explicit_col_specs = true
+ if (attributes.key? 'cols') && !(colspecs = parse_colspecs attributes['cols']).empty?
+ table.create_columns colspecs
+ explicit_colspecs = true
else
- explicit_col_specs = false
+ explicit_colspecs = false
end
skipped = table_reader.skip_blank_lines
parser_ctx = Table::ParserContext.new(table_reader, table, attributes)
+ skip_implicit_header = (attributes.key? 'header-option') || (attributes.key? 'noheader-option')
loop_idx = -1
while table_reader.has_more_lines?
loop_idx += 1
line = table_reader.read_line
- if skipped == 0 && loop_idx.zero? && !attributes.has_key?('options') &&
+ if !skip_implicit_header && skipped == 0 && loop_idx == 0 &&
!(next_line = table_reader.peek_line).nil? && next_line.empty?
table.has_header_option = true
- table.set_option 'header'
+ attributes['header-option'] = ''
+ attributes['options'] = (attributes.key? 'options') ? %(#{attributes['options']},header) : 'header'
end
if parser_ctx.format == 'psv'
@@ -2307,10 +2311,10 @@ class Parser
# push an empty cell spec if boundary at start of line
parser_ctx.close_open_cell
else
- next_cell_spec, line = parse_cell_spec(line, :start, parser_ctx.delimiter)
+ next_cellspec, line = parse_cellspec(line, :start, parser_ctx.delimiter)
# if the cell spec is not null, then we're at a cell boundary
- if !next_cell_spec.nil?
- parser_ctx.close_open_cell next_cell_spec
+ if !next_cellspec.nil?
+ parser_ctx.close_open_cell next_cellspec
else
# QUESTION do we not advance to next line? if so, when will we if we came into this block?
end
@@ -2341,14 +2345,14 @@ class Parser
end
if parser_ctx.format == 'psv'
- next_cell_spec, cell_text = parse_cell_spec(m.pre_match, :end)
- parser_ctx.push_cell_spec next_cell_spec
+ next_cellspec, cell_text = parse_cellspec(m.pre_match, :end)
+ parser_ctx.push_cellspec next_cellspec
parser_ctx.buffer = %(#{parser_ctx.buffer}#{cell_text})
else
parser_ctx.buffer = %(#{parser_ctx.buffer}#{m.pre_match})
end
- if (line = m.post_match) == ''
+ if (line = m.post_match).empty?
# hack to prevent dropping empty cell found at end of line (see issue #1106)
seen = false
end
@@ -2380,8 +2384,8 @@ class Parser
end
end
- unless (table.attributes['colcount'] ||= table.columns.size) == 0 || explicit_col_specs
- table.assign_col_widths
+ unless (table.attributes['colcount'] ||= table.columns.size) == 0 || explicit_colspecs
+ table.assign_column_widths
end
table.partition_header_footer attributes
@@ -2400,7 +2404,7 @@ class Parser
#
# returns a Hash of attributes that specify how to format
# and layout the cells in the table.
- def self.parse_col_specs records
+ def self.parse_colspecs records
records = records.tr ' ', '' if records.include? ' '
# check for deprecated syntax: single number, equal column spread
if records == records.to_i.to_s
@@ -2410,7 +2414,7 @@ class Parser
specs = []
# NOTE -1 argument ensures we don't drop empty records
records.split(',', -1).each {|record|
- if record == ''
+ if record.empty?
specs << { 'width' => 1 }
# TODO might want to use scan rather than this mega-regexp
elsif (m = ColumnSpecRx.match(record))
@@ -2458,7 +2462,7 @@ class Parser
#
# returns the Hash of attributes that indicate how to layout
# and style this cell in the table.
- def self.parse_cell_spec(line, pos = :start, delimiter = nil)
+ def self.parse_cellspec(line, pos = :start, delimiter = nil)
m = nil
rest = ''
@@ -2665,13 +2669,13 @@ class Parser
lines.map! do |line|
next line if line.empty?
- if line.start_with? TAB
- line.sub!(TabIndentRx) {|tabs| full_tab_space * tabs.length }
- end
+ # NOTE Opal has to patch this use of sub!
+ line.sub!(TabIndentRx) {|tabs| full_tab_space * tabs.length } if line.start_with? TAB
if line.include? TAB
# keeps track of how many spaces were added to adjust offset in match data
spaces_added = 0
+ # NOTE Opal has to patch this use of gsub!
line.gsub!(TabRx) {
# calculate how many spaces this tab represents, then replace tab with spaces
if (offset = ($~.begin 0) + spaces_added) % tab_size == 0
diff --git a/lib/asciidoctor/path_resolver.rb b/lib/asciidoctor/path_resolver.rb
index 32061e1..f047c39 100644
--- a/lib/asciidoctor/path_resolver.rb
+++ b/lib/asciidoctor/path_resolver.rb
@@ -417,7 +417,7 @@ class PathResolver
uri_prefix = nil
unless start.nil_or_empty? || (is_web_root? target)
- target = %(#{start}#{SLASH}#{target})
+ target = %(#{start.chomp '/'}#{SLASH}#{target})
if (uri_prefix = Helpers.uri_prefix target)
target = target[uri_prefix.length..-1]
end
@@ -448,6 +448,8 @@ class PathResolver
end
else
resolved_segments << segment
+ # checking for empty would eliminate repeating forward slashes
+ #resolved_segments << segment unless segment.empty?
end
end
diff --git a/lib/asciidoctor/reader.rb b/lib/asciidoctor/reader.rb
index 993e51f..6113551 100644
--- a/lib/asciidoctor/reader.rb
+++ b/lib/asciidoctor/reader.rb
@@ -41,7 +41,7 @@ class Reader
@file = @dir = nil
@path = '<stdin>'
@lineno = 1 # IMPORTANT lineno assignment must proceed prepare_lines call!
- elsif cursor.is_a? ::String
+ elsif ::String === cursor
@file = cursor
@dir, @path = ::File.split @file
@lineno = 1 # IMPORTANT lineno assignment must proceed prepare_lines call!
@@ -84,7 +84,7 @@ class Reader
#
# Returns The String lines extracted from the data
def prepare_lines data, opts = {}
- if data.is_a? ::String
+ if ::String === data
if opts[:normalize]
Helpers.normalize_lines_from_string data
else
@@ -732,10 +732,10 @@ class PreprocessorReader < Reader
skip = !@document.attributes.has_key?(target)
when ','
# if any attribute is defined, then don't skip
- skip = !target.split(',').detect {|name| @document.attributes.has_key? name }
+ skip = target.split(',').none? {|name| @document.attributes.has_key? name }
when '+'
# if any attribute is undefined, then skip
- skip = target.split('+').detect {|name| !@document.attributes.has_key? name }
+ skip = target.split('+').any? {|name| !@document.attributes.has_key? name }
end
when 'ifndef'
case delimiter
@@ -744,10 +744,10 @@ class PreprocessorReader < Reader
skip = @document.attributes.has_key?(target)
when ','
# if any attribute is undefined, then don't skip
- skip = !target.split(',').detect {|name| !@document.attributes.has_key? name }
+ skip = target.split(',').none? {|name| !@document.attributes.has_key? name }
when '+'
# if any attribute is defined, then skip
- skip = target.split('+').detect {|name| @document.attributes.has_key? name }
+ skip = target.split('+').any? {|name| @document.attributes.has_key? name }
end
when 'ifeval'
# the text in brackets must match an expression
@@ -830,10 +830,11 @@ class PreprocessorReader < Reader
# FIXME we don't want to use a link macro if we are in a verbatim context
replace_next_line %(link:#{target}[])
true
- elsif (abs_maxdepth = @maxdepth[:abs]) > 0 && @include_stack.size >= abs_maxdepth
- warn %(asciidoctor: ERROR: #{line_info}: maximum include depth of #{@maxdepth[:rel]} exceeded)
- false
- elsif abs_maxdepth > 0
+ elsif (abs_maxdepth = @maxdepth[:abs]) > 0
+ if @include_stack.size >= abs_maxdepth
+ warn %(asciidoctor: ERROR: #{line_info}: maximum include depth of #{@maxdepth[:rel]} exceeded)
+ return false
+ end
if ::RUBY_ENGINE_OPAL
# NOTE resolves uri relative to currently loaded document
# NOTE we defer checking if file exists and catch the 404 error if it does not
@@ -883,7 +884,7 @@ class PreprocessorReader < Reader
inc_lines = []
attributes['lines'].split(DataDelimiterRx).each do |linedef|
if linedef.include?('..')
- from, to = linedef.split('..').map(&:to_i)
+ from, to = linedef.split('..', 2).map(&:to_i)
if to == -1
inc_lines << from
inc_lines << 1.0/0.0
@@ -911,7 +912,7 @@ class PreprocessorReader < Reader
f.each_line do |l|
inc_lineno += 1
take = inc_lines[0]
- if take.is_a?(::Float) && take.infinite?
+ if ::Float === take && take.infinite?
selected.push l
inc_line_offset = inc_lineno if inc_line_offset == 0
else
@@ -1010,7 +1011,7 @@ class PreprocessorReader < Reader
# data = IO.read file
# reader.push_include data, file, path
#
- # Returns nothing.
+ # Returns this Reader object.
def push_include data, file = nil, path = nil, lineno = 1, attributes = {}
@include_stack << [@lines, @file, @dir, @path, @lineno, @maxdepth, @process_lines]
if file
@@ -1064,7 +1065,7 @@ class PreprocessorReader < Reader
@eof = false
@look_ahead = 0
end
- nil
+ self
end
def pop_include
diff --git a/lib/asciidoctor/section.rb b/lib/asciidoctor/section.rb
index 10bb817..651fc85 100644
--- a/lib/asciidoctor/section.rb
+++ b/lib/asciidoctor/section.rb
@@ -87,8 +87,8 @@ class Section < AbstractBlock
sep = @document.attributes['idseparator'] || '_'
pre = @document.attributes['idprefix'] || '_'
base_id = %(#{pre}#{title.downcase.gsub(InvalidSectionIdCharsRx, sep).tr_s(sep, sep).chomp(sep)})
- # ensure id doesn't begin with idprefix if requested it doesn't
- if pre.empty? && base_id.start_with?(sep)
+ # ensure id doesn't begin with idseparator if idprefix is empty and idseparator is not empty
+ if pre.empty? && !sep.empty? && base_id.start_with?(sep)
base_id = base_id[1..-1]
base_id = base_id[1..-1] while base_id.start_with?(sep)
end
diff --git a/lib/asciidoctor/stylesheets.rb b/lib/asciidoctor/stylesheets.rb
index 0d6f1dd..d55369f 100644
--- a/lib/asciidoctor/stylesheets.rb
+++ b/lib/asciidoctor/stylesheets.rb
@@ -71,7 +71,8 @@ class Stylesheets
def pygments_stylesheet_data style = nil
if load_pygments
(@pygments_stylesheet_data ||= {})[style || DEFAULT_PYGMENTS_STYLE] ||=
- ::Pygments.css '.listingblock .pygments', :classprefix => 'tok-', :style => (style || DEFAULT_PYGMENTS_STYLE)
+ (::Pygments.css '.listingblock .pygments', :classprefix => 'tok-', :style => (style || DEFAULT_PYGMENTS_STYLE)).
+ sub('.listingblock .pygments {', '.listingblock .pygments, .listingblock .pygments code {')
else
'/* Pygments styles disabled. Pygments is not available. */'
end
diff --git a/lib/asciidoctor/substitutors.rb b/lib/asciidoctor/substitutors.rb
index 006dd56..ec52c24 100644
--- a/lib/asciidoctor/substitutors.rb
+++ b/lib/asciidoctor/substitutors.rb
@@ -363,54 +363,50 @@ module Substitutors
end
alias :sub_specialcharacters :sub_specialchars
- # Public: Substitute quoted text (includes emphasis, strong, monospaced, etc)
- #
- # text - The String text to process
- #
- # returns The converted String text
- def sub_quotes(text)
- if ::RUBY_ENGINE_OPAL
- result = text
- QUOTE_SUBS[@document.compat_mode].each {|type, scope, pattern|
- result = result.gsub(pattern) { convert_quoted_text $~, type, scope }
- }
- else
+ if RUBY_ENGINE == 'opal'
+ def sub_quotes text
+ QUOTE_SUBS[@document.compat_mode].each do |type, scope, pattern|
+ text = text.gsub(pattern) { convert_quoted_text $~, type, scope }
+ end
+ text
+ end
+
+ def sub_replacements text
+ REPLACEMENTS.each do |pattern, replacement, restore|
+ text = text.gsub(pattern) { do_replacement $~, replacement, restore }
+ end
+ text
+ end
+ else
+ # Public: Substitute quoted text (includes emphasis, strong, monospaced, etc)
+ #
+ # text - The String text to process
+ #
+ # returns The converted String text
+ def sub_quotes text
# NOTE interpolation is faster than String#dup
- result = %(#{text})
+ text = %(#{text})
# NOTE using gsub! here as an MRI Ruby optimization
- QUOTE_SUBS[@document.compat_mode].each {|type, scope, pattern|
- result.gsub!(pattern) { convert_quoted_text $~, type, scope }
- }
+ QUOTE_SUBS[@document.compat_mode].each do |type, scope, pattern|
+ text.gsub!(pattern) { convert_quoted_text $~, type, scope }
+ end
+ text
end
- result
- end
-
- # Public: Substitute replacement characters (e.g., copyright, trademark, etc)
- #
- # text - The String text to process
- #
- # returns The String text with the replacement characters substituted
- def sub_replacements(text)
- if ::RUBY_ENGINE_OPAL
- result = text
- REPLACEMENTS.each {|pattern, replacement, restore|
- result = result.gsub(pattern) {
- do_replacement $~, replacement, restore
- }
- }
- else
+ # Public: Substitute replacement characters (e.g., copyright, trademark, etc)
+ #
+ # text - The String text to process
+ #
+ # returns The String text with the replacement characters substituted
+ def sub_replacements text
# NOTE interpolation is faster than String#dup
- result = %(#{text})
+ text = %(#{text})
# NOTE Using gsub! as optimization
- REPLACEMENTS.each {|pattern, replacement, restore|
- result.gsub!(pattern) {
- do_replacement $~, replacement, restore
- }
- }
+ REPLACEMENTS.each do |pattern, replacement, restore|
+ text.gsub!(pattern) { do_replacement $~, replacement, restore }
+ end
+ text
end
-
- result
end
# Internal: Substitute replacement text for matched location
@@ -642,6 +638,8 @@ module Substitutors
target = m[1]
attributes = if extension.config[:format] == :short
+ # TODO if content_model is :attributes, set target to nil and parse attributes
+ # maybe if content_model is :text, we should put content into text attribute
{}
else
if extension.config[:content_model] == :attributes
@@ -1403,7 +1401,7 @@ module Substitutors
unless (highlighter_loaded = defined? ::CodeRay) || @document.attributes['coderay-unavailable']
if (Helpers.require_library 'coderay', true, :warn).nil?
# prevent further attempts to load CodeRay
- @document.set_attr 'coderay-unavailable', true
+ @document.set_attr 'coderay-unavailable', ''
else
highlighter_loaded = true
end
@@ -1412,7 +1410,7 @@ module Substitutors
unless (highlighter_loaded = defined? ::Pygments) || @document.attributes['pygments-unavailable']
if (Helpers.require_library 'pygments', 'pygments.rb', :warn).nil?
# prevent further attempts to load Pygments
- @document.set_attr 'pygments-unavailable', true
+ @document.set_attr 'pygments-unavailable', ''
else
highlighter_loaded = true
end
@@ -1460,7 +1458,7 @@ module Substitutors
when 'coderay'
if (linenums_mode = (attr? 'linenums') ? (@document.attributes['coderay-linenums-mode'] || :table).to_sym : nil)
if attr? 'highlight', nil, false
- highlight_lines = resolve_lines_to_highlight(attr 'highlight', nil, false)
+ highlight_lines = resolve_highlight_lines(attr 'highlight', nil, false)
end
end
result = ::CodeRay::Duo[attr('language', :text, false).to_sym, :html, {
@@ -1477,7 +1475,7 @@ module Substitutors
opts[:style] = (@document.attributes['pygments-style'] || Stylesheets::DEFAULT_PYGMENTS_STYLE)
end
if attr? 'highlight', nil, false
- unless (highlight_lines = resolve_lines_to_highlight(attr 'highlight', nil, false)).empty?
+ unless (highlight_lines = resolve_highlight_lines(attr 'highlight', nil, false)).empty?
opts[:hl_lines] = highlight_lines * ' '
end
end
@@ -1545,7 +1543,7 @@ module Substitutors
end
# e.g., highlight="1-5, !2, 10" or highlight=1-5;!2,10
- def resolve_lines_to_highlight spec
+ def resolve_highlight_lines spec
lines = []
spec.delete(' ').split(DataDelimiterRx).map do |entry|
negate = false
diff --git a/lib/asciidoctor/table.rb b/lib/asciidoctor/table.rb
index 9587388..832be8c 100644
--- a/lib/asciidoctor/table.rb
+++ b/lib/asciidoctor/table.rb
@@ -77,9 +77,11 @@ class Table < AbstractBlock
# smell like we need a utility method here
# to resolve an integer width from potential bogus input
- pcwidth = attributes['width']
- pcwidth_intval = pcwidth.to_i.abs
- if pcwidth_intval == 0 && pcwidth != '0' || pcwidth_intval > 100
+ if (pcwidth = attributes['width'])
+ if (pcwidth_intval = pcwidth.to_i) > 100 || pcwidth_intval < 1
+ pcwidth_intval = 100 unless pcwidth_intval == 0 && (pcwidth == '0' || pcwidth == '0%')
+ end
+ else
pcwidth_intval = 100
end
@attributes['tablepcwidth'] = pcwidth_intval
@@ -88,6 +90,8 @@ class Table < AbstractBlock
@attributes['tableabswidth'] ||=
((@attributes['tablepcwidth'].to_f / 100) * @document.attributes['pagewidth']).round
end
+
+ attributes['orientation'] = 'landscape' if attributes.key? 'rotate-option'
end
# Internal: Returns whether the current row being processed is
@@ -99,16 +103,16 @@ class Table < AbstractBlock
# Internal: Creates the Column objects from the column spec
#
# returns nothing
- def create_columns col_specs
+ def create_columns colspecs
cols = []
width_base = 0
- col_specs.each do |col_spec|
- width_base += col_spec['width']
- cols << (Column.new self, cols.size, col_spec)
+ colspecs.each do |colspec|
+ width_base += colspec['width']
+ cols << (Column.new self, cols.size, colspec)
end
unless (@columns = cols).empty?
@attributes['colcount'] = cols.size
- assign_col_widths(width_base == 0 ? nil : width_base)
+ assign_column_widths(width_base == 0 ? nil : width_base)
end
nil
end
@@ -123,7 +127,7 @@ class Table < AbstractBlock
# width_base - the total of the relative column values used for calculating percentage widths (default: nil)
#
# returns nothing
- def assign_col_widths width_base = nil
+ def assign_column_widths width_base = nil
pf = 10.0 ** 4 # precision factor (multipler / divisor) for managing precision of calculated result
total_width = col_pcwidth = 0
@@ -301,10 +305,10 @@ class Table::ParserContext
# Public: Get the expected column count for a row
#
- # col_count is the number of columns to pull into a row
+ # colcount is the number of columns to pull into a row
# A value of -1 means we use the number of columns found
- # in the first line as the col_count
- attr_reader :col_count
+ # in the first line as the colcount
+ attr_reader :colcount
# Public: The String buffer of the currently open cell
attr_accessor :buffer
@@ -334,12 +338,12 @@ class Table::ParserContext
attributes['separator'] || Table::DEFAULT_DELIMITERS[@format]
end
@delimiter_re = /#{Regexp.escape @delimiter}/
- @col_count = table.columns.empty? ? -1 : table.columns.size
+ @colcount = table.columns.empty? ? -1 : table.columns.size
@buffer = ''
- @cell_specs = []
+ @cellspecs = []
@cell_open = false
@active_rowspans = [0]
- @col_visits = 0
+ @column_visits = 0
@current_row = []
@linenum = -1
end
@@ -392,17 +396,17 @@ class Table::ParserContext
# when the cell is being closed.
#
# returns The cell spec Hash captured from parsing the previous cell
- def take_cell_spec()
- @cell_specs.shift
+ def take_cellspec
+ @cellspecs.shift
end
# Public: Puts a cell spec onto the stack. Cell specs precede the delimiter, so a
# stack is used to carry over the spec to the next cell.
#
# returns nothing
- def push_cell_spec(cell_spec = {})
+ def push_cellspec(cellspec = {})
# this shouldn't be nil, but we check anyway
- @cell_specs << (cell_spec || {})
+ @cellspecs << (cellspec || {})
nil
end
@@ -443,8 +447,8 @@ class Table::ParserContext
# by the next cell.
#
# returns nothing
- def close_open_cell(next_cell_spec = {})
- push_cell_spec next_cell_spec
+ def close_open_cell(next_cellspec = {})
+ push_cellspec next_cellspec
close_cell(true) if cell_open?
advance
nil
@@ -459,17 +463,16 @@ class Table::ParserContext
cell_text = @buffer.strip
@buffer = ''
if @format == 'psv'
- cell_spec = take_cell_spec
- if cell_spec
- repeat = cell_spec.fetch('repeatcol', 1)
- cell_spec.delete('repeatcol')
+ cellspec = take_cellspec
+ if cellspec
+ repeat = cellspec.delete('repeatcol') || 1
else
warn %(asciidoctor: ERROR: #{@last_cursor.line_info}: table missing leading separator, recovering automatically)
- cell_spec = {}
+ cellspec = {}
repeat = 1
end
else
- cell_spec = nil
+ cellspec = nil
repeat = 1
if @format == 'csv'
if !cell_text.empty? && cell_text.include?('"')
@@ -487,9 +490,9 @@ class Table::ParserContext
1.upto(repeat) do |i|
# TODO make column resolving an operation
- if @col_count == -1
+ if @colcount == -1
@table.columns << (column = Table::Column.new(@table, @table.columns.size + i - 1))
- if cell_spec && (cell_spec.key? 'colspan') && (extra_cols = cell_spec['colspan'].to_i - 1) > 0
+ if cellspec && (cellspec.key? 'colspan') && (extra_cols = cellspec['colspan'].to_i - 1) > 0
offset = @table.columns.size
extra_cols.times do |j|
@table.columns << Table::Column.new(@table, offset + j)
@@ -503,16 +506,16 @@ class Table::ParserContext
end
end
- cell = Table::Cell.new(column, cell_text, cell_spec, @last_cursor)
+ cell = Table::Cell.new(column, cell_text, cellspec, @last_cursor)
@last_cursor = @reader.cursor
unless !cell.rowspan || cell.rowspan == 1
activate_rowspan(cell.rowspan, (cell.colspan || 1))
end
- @col_visits += (cell.colspan || 1)
+ @column_visits += (cell.colspan || 1)
@current_row << cell
# don't close the row if we're on the first line and the column count has not been set explicitly
- # TODO perhaps the col_count/linenum logic should be in end_of_row? (or a should_end_row? method)
- close_row if end_of_row? && (@col_count != -1 || @linenum > 0 || (eol && i == repeat))
+ # TODO perhaps the colcount/linenum logic should be in end_of_row? (or a should_end_row? method)
+ close_row if end_of_row? && (@colcount != -1 || @linenum > 0 || (eol && i == repeat))
end
@cell_open = false
nil
@@ -526,8 +529,8 @@ class Table::ParserContext
@table.rows.body << @current_row
# don't have to account for active rowspans here
# since we know this is first row
- @col_count = @col_visits if @col_count == -1
- @col_visits = 0
+ @colcount = @column_visits if @colcount == -1
+ @column_visits = 0
@current_row = []
@active_rowspans.shift
@active_rowspans[0] ||= 0
@@ -548,13 +551,13 @@ class Table::ParserContext
# Public: Check whether we've met the number of effective columns for the current row.
def end_of_row?
- @col_count == -1 || effective_col_visits == @col_count
+ @colcount == -1 || effective_column_visits == @colcount
end
# Public: Calculate the effective column visits, which consists of the number of
# cells plus any active rowspans.
- def effective_col_visits
- @col_visits + @active_rowspans[0]
+ def effective_column_visits
+ @column_visits + @active_rowspans[0]
end
# Internal: Advance to the next line (which may come after the parser begins processing
diff --git a/lib/asciidoctor/version.rb b/lib/asciidoctor/version.rb
index be5825c..ac83829 100644
--- a/lib/asciidoctor/version.rb
+++ b/lib/asciidoctor/version.rb
@@ -1,3 +1,3 @@
module Asciidoctor
- VERSION = '1.5.4'
+ VERSION = '1.5.5'
end
diff --git a/man/asciidoctor.1 b/man/asciidoctor.1
index 36bb476..46ed1d1 100644
--- a/man/asciidoctor.1
+++ b/man/asciidoctor.1
@@ -1,13 +1,13 @@
'\" t
.\" Title: asciidoctor
.\" Author: Dan Allen, Sarah White, Ryan Waldron
-.\" Generator: Asciidoctor 1.5.4
-.\" Date: 2016-01-05
+.\" Generator: Asciidoctor 1.5.5
+.\" Date: 2016-10-05
.\" Manual: Asciidoctor Manual
-.\" Source: Asciidoctor 1.5.4
+.\" Source: Asciidoctor 1.5.5
.\" Language: English
.\"
-.TH "ASCIIDOCTOR" "1" "2016-01-05" "Asciidoctor 1.5.4" "Asciidoctor Manual"
+.TH "ASCIIDOCTOR" "1" "2016-10-05" "Asciidoctor 1.5.5" "Asciidoctor Manual"
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.ss \n[.ss] 0
@@ -191,6 +191,13 @@ Print program version number.
.sp
\f[CR]\-v\fP can also be used if no other flags or arguments are present.
.RE
+.SH "ENVIRONMENT"
+.sp
+\fBAsciidoctor\fP honors the SOURCE_DATE_EPOCH environment variable.
+If this variable is assigned an integer value, that value is used as the epoch of all input documents and as the local date and time.
+See \c
+.URL "https://reproducible\-builds.org/specs/source\-date\-epoch/" "" " "
+for more information about this environment variable.
.SH "EXIT STATUS"
.sp
\fB0\fP
diff --git a/man/asciidoctor.adoc b/man/asciidoctor.adoc
index b9a1873..d8d518e 100644
--- a/man/asciidoctor.adoc
+++ b/man/asciidoctor.adoc
@@ -2,7 +2,7 @@
Dan Allen; Sarah White; Ryan Waldron
:doctype: manpage
:man manual: Asciidoctor Manual
-:man source: Asciidoctor 1.5.4
+:man source: Asciidoctor 1.5.5
:page-layout: base
== NAME
@@ -144,6 +144,12 @@ Matching templates found in subsequent directories override ones previously disc
+
`-v` can also be used if no other flags or arguments are present.
+== ENVIRONMENT
+
+*Asciidoctor* honors the SOURCE_DATE_EPOCH environment variable.
+If this variable is assigned an integer value, that value is used as the epoch of all input documents and as the local date and time.
+See https://reproducible-builds.org/specs/source-date-epoch/ for more information about this environment variable.
+
== EXIT STATUS
*0*::
diff --git a/test/attributes_test.rb b/test/attributes_test.rb
index 2b10181..00b4d57 100644
--- a/test/attributes_test.rb
+++ b/test/attributes_test.rb
@@ -124,6 +124,58 @@ content
assert result.include? '<em>big</em>foot'
end
+ test 'should limit maximum size of attribute value if safe mode is SECURE' do
+ expected = 'a' * 4096
+ input = <<-EOS
+:name: #{'a' * 5000}
+
+{name}
+ EOS
+
+ result = render_embedded_string input, :doctype => :inline
+ assert_equal expected, result
+ assert_equal 4096, result.bytesize
+ end
+
+ test 'should handle multibyte characters when limiting attribute value size' do
+ expected = '日本'
+ input = <<-EOS
+:name: 日本語
+
+{name}
+ EOS
+
+ result = render_embedded_string input, :doctype => :inline, :attributes => { 'max-attribute-value-size' => 6 }
+ assert_equal expected, result
+ assert_equal 6, result.bytesize
+ end
+
+ test 'should not mangle multibyte characters when limiting attribute value size' do
+ expected = '日本'
+ input = <<-EOS
+:name: 日本語
+
+{name}
+ EOS
+
+ result = render_embedded_string input, :doctype => :inline, :attributes => { 'max-attribute-value-size' => 8 }
+ assert_equal expected, result
+ assert_equal 6, result.bytesize
+ end
+
+ test 'should allow maximize size of attribute value to be disabled' do
+ expected = 'a' * 5000
+ input = <<-EOS
+:name: #{'a' * 5000}
+
+{name}
+ EOS
+
+ result = render_embedded_string input, :doctype => :inline, :attributes => { 'max-attribute-value-size' => nil }
+ assert_equal expected, result
+ assert_equal 5000, result.bytesize
+ end
+
test 'resolves user-home attribute if safe mode is less than SERVER' do
input = <<-EOS
:imagesdir: {user-home}/etc/images
diff --git a/test/blocks_test.rb b/test/blocks_test.rb
index f541229..62c9d36 100644
--- a/test/blocks_test.rb
+++ b/test/blocks_test.rb
@@ -1523,10 +1523,10 @@ image::circle.svg[Tiger,100]
EOS
output = render_embedded_string input, :safe => Asciidoctor::SafeMode::SERVER, :attributes => { 'docdir' => ::File.dirname(__FILE__) }
- assert_match(/<svg [^>]*width="100px"[^>]*>/, output, 1)
- refute_match(/<svg [^>]*width="500px"[^>]*>/, output)
- refute_match(/<svg [^>]*height="500px"[^>]*>/, output)
- refute_match(/<svg [^>]*style="width:500px;height:500px"[^>]*>/, output)
+ assert_match(/<svg\s[^>]*width="100px"[^>]*>/, output, 1)
+ refute_match(/<svg\s[^>]*width="500px"[^>]*>/, output)
+ refute_match(/<svg\s[^>]*height="500px"[^>]*>/, output)
+ refute_match(/<svg\s[^>]*style="width:500px;height:500px"[^>]*>/, output)
end
test 'renders inline SVG image using svg element even when data-uri is set' do
@@ -1539,7 +1539,7 @@ image::circle.svg[Tiger,100]
EOS
output = render_embedded_string input, :safe => Asciidoctor::SafeMode::SERVER, :attributes => { 'docdir' => ::File.dirname(__FILE__) }
- assert_match(/<svg [^>]*width="100px">/, output, 1)
+ assert_match(/<svg\s[^>]*width="100px">/, output, 1)
end
test 'renders alt text for inline svg element if svg cannot be read' do
@@ -2162,7 +2162,7 @@ You can use icons for admonitions by setting the 'icons' attribute.
EOS
output = render_string input, :safe => Asciidoctor::SafeMode::SERVER
- assert_css 'html > head > link[rel="stylesheet"][href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css"]', output, 1
+ assert_css 'html > head > link[rel="stylesheet"][href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css"]', output, 1
assert_xpath '//*[@class="admonitionblock tip"]//*[@class="icon"]/i[@class="fa icon-tip"]', output, 1
end
@@ -2193,7 +2193,7 @@ puts "AsciiDoc, FTW!"
EOS
output = render_string input, :safe => Asciidoctor::SafeMode::SAFE
- assert_css 'html > head > link[rel="stylesheet"][href="http://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css"]', output, 1
+ assert_css 'html > head > link[rel="stylesheet"][href="http://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css"]', output, 1
assert_css 'html > body > script[src="http://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.9.1/highlight.min.js"]', output, 1
end
@@ -2210,7 +2210,7 @@ puts "AsciiDoc, FTW!"
EOS
output = render_string input, :safe => Asciidoctor::SafeMode::SAFE
- assert_css 'html > head > link[rel="stylesheet"][href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css"]', output, 1
+ assert_css 'html > head > link[rel="stylesheet"][href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css"]', output, 1
assert_css 'html > body > script[src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/8.9.1/highlight.min.js"]', output, 1
end
end
diff --git a/test/document_test.rb b/test/document_test.rb
index 40c4680..3c876ec 100644
--- a/test/document_test.rb
+++ b/test/document_test.rb
@@ -520,6 +520,18 @@ term without description::
assert_xpath '/html/body/*[@id="header"]/h1[text() = "Document Title"]', output, 1
end
+ test 'lines in output should be separated by line feed' do
+ sample_input_path = fixture_path('sample.asciidoc')
+
+ output = Asciidoctor.convert_file sample_input_path, :header_footer => true, :to_file => false
+ assert !output.empty?
+ lines = output.split("\n")
+ assert lines.size == output.split(/\r\n|\r|\n/).size
+ raw_lengths = lines.map(&:length)
+ trimmed_lengths = lines.map {|line| line.rstrip.length }
+ assert raw_lengths == trimmed_lengths
+ end
+
test 'should accept attributes as array' do
sample_input_path = fixture_path('sample.asciidoc')
output = Asciidoctor.convert_file sample_input_path, :attributes => %w(sectnums idprefix idseparator=-), :to_file => false
@@ -1674,7 +1686,7 @@ image::tiger.png[]
|===
[horizontal, labelwidth="25%", itemwidth="75%"]
-term:: definition
+term:: description
NOTE: note
diff --git a/test/extensions_test.rb b/test/extensions_test.rb
index 0fa87cb..69808bc 100644
--- a/test/extensions_test.rb
+++ b/test/extensions_test.rb
@@ -665,6 +665,44 @@ content
end
end
+ test 'parse_content should not share attributes between parsed blocks' do
+ begin
+ Asciidoctor::Extensions.register do
+ block do
+ named :wrap
+ on_context :open
+ process do |parent, reader, attrs|
+ wrap = create_open_block parent, nil, attrs
+ parse_content wrap, reader.read_lines
+ end
+ end
+ end
+ input = <<-EOS
+[wrap]
+--
+[foo=bar]
+====
+content
+====
+
+[baz=qux]
+====
+content
+====
+--
+ EOS
+ doc = document_from_string input
+ assert_equal 1, doc.blocks.size
+ wrap = doc.blocks[0]
+ assert_equal 2, wrap.blocks.size
+ assert_equal 2, wrap.blocks[0].attributes.size
+ assert_equal 2, wrap.blocks[1].attributes.size
+ assert_nil wrap.blocks[1].attributes['foo']
+ ensure
+ Asciidoctor::Extensions.unregister_all
+ end
+ end
+
test 'should add docinfo to document' do
input = <<-EOS
= Document Title
diff --git a/test/fixtures/circle.svg b/test/fixtures/circle.svg
index 7e05910..6396975 100644
--- a/test/fixtures/circle.svg
+++ b/test/fixtures/circle.svg
@@ -1,7 +1,8 @@
<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- An SVG of a black circle -->
-<svg viewBox="0 0 120 120" version="1.1"
+<svg
+viewBox="0 0 120 120" version="1.1"
xmlns="http://www.w3.org/2000/svg" style="width:500px;height:500px"
width="500px" height="500px">
<circle cx="60" cy="60" r="50"/>
diff --git a/test/invoker_test.rb b/test/invoker_test.rb
index 6e03ef1..0d05831 100644
--- a/test/invoker_test.rb
+++ b/test/invoker_test.rb
@@ -550,4 +550,19 @@ context 'Invoker' do
assert_match(/Total time/, error)
end
+ test 'should use SOURCE_DATE_EPOCH as modified time of input file and local time' do
+ old_source_date_epoch = ENV.delete 'SOURCE_DATE_EPOCH'
+ begin
+ ENV['SOURCE_DATE_EPOCH'] = '1234123412'
+ sample_filepath = File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', 'sample.asciidoc'))
+ invoker = invoke_cli_to_buffer %w(-o /dev/null), sample_filepath
+ doc = invoker.document
+ assert_equal '2009-02-08', (doc.attr 'docdate')
+ assert_match(/2009-02-08 20:03:32 (GMT|UTC)/, (doc.attr 'docdatetime'))
+ assert_equal '2009-02-08', (doc.attr 'localdate')
+ assert_match(/2009-02-08 20:03:32 (GMT|UTC)/, (doc.attr 'localdatetime'))
+ ensure
+ ENV['SOURCE_DATE_EPOCH'] = old_source_date_epoch if old_source_date_epoch
+ end
+ end
end
diff --git a/test/lists_test.rb b/test/lists_test.rb
index eb00070..8545388 100644
--- a/test/lists_test.rb
+++ b/test/lists_test.rb
@@ -258,6 +258,18 @@ second wrapped line
assert !output.include?('* Foo')
end
+ test 'a list item that starts with a sequence of list markers characters should not match a nested list' do
+ input = <<-EOS
+ * first item
+ *. normal text
+ EOS
+
+ output = render_embedded_string input
+ assert_css 'ul', output, 1
+ assert_css 'ul li', output, 1
+ assert_xpath "//ul/li/p[text()='first item\n*. normal text']", output, 1
+ end
+
test 'a list item for a different list terminates indented paragraph for text of list item' do
input = <<-EOS
== Example 1
@@ -1472,11 +1484,11 @@ attached paragraph
input = <<-EOS
* item 1
- term a:: definition a
+ term a:: description a
+
attached paragraph
- term b:: definition b
+ term b:: description b
+
attached paragraph
@@ -1595,6 +1607,19 @@ List
assert_css '.olist ol.loweralpha', output, 1
end
+ test 'should set reversed attribute on list if reversed option is set' do
+ input = <<-EOS
+[%reversed, start=3]
+. three
+. two
+. one
+. blast off!
+ EOS
+
+ output = render_embedded_string input
+ assert_css 'ol[reversed][start="3"]', output, 1
+ end
+
test 'should represent implicit role attribute as style class' do
input = <<-EOS
[.dry]
@@ -1952,7 +1977,7 @@ def2
input = <<-EOS
term::
alt term::
-definition
+description
last::
EOS
@@ -2111,7 +2136,7 @@ anotherterm:: def
term::
+
--
-Open block as definition of term.
+Open block as description of term.
And some more detail...
--
@@ -2201,7 +2226,7 @@ term2:: def
assert_xpath '((//dl/dd)[1]//ul)[1]//ul', output, 1
end
- test "should only grab one line following last item if item has no inline definition" do
+ test "should only grab one line following last item if item has no inline description" do
input = <<-EOS
term1::
@@ -2225,7 +2250,7 @@ Another new paragraph
assert_xpath '(//*[@class="dlist"]/following-sibling::*[@class="paragraph"])[2]/p[text() = "Another new paragraph"]', output, 1
end
- test "should only grab one literal line following last item if item has no inline definition" do
+ test "should only grab one literal line following last item if item has no inline description" do
input = <<-EOS
term1::
@@ -2509,7 +2534,7 @@ term 2:: def 2
[glossary]
term::
alt term::
-definition
+description
last::
EOS
@@ -2524,11 +2549,11 @@ last::
test 'should render horizontal list with proper markup' do
input = <<-EOS
[horizontal]
-first term:: definition
+first term:: description
+
more detail
-second term:: definition
+second term:: description
EOS
output = render_embedded_string input
assert_css '.hdlist', output, 1
@@ -2541,11 +2566,11 @@ second term:: definition
assert_xpath '/*[@class="hdlist"]/table/tr[1]/td[@class="hdlist2"]/p', output, 1
assert_xpath '/*[@class="hdlist"]/table/tr[1]/td[@class="hdlist2"]/p/following-sibling::*[@class="paragraph"]', output, 1
assert_xpath '((//tr)[1]/td)[1][normalize-space(text())="first term"]', output, 1
- assert_xpath '((//tr)[1]/td)[2]/p[normalize-space(text())="definition"]', output, 1
+ assert_xpath '((//tr)[1]/td)[2]/p[normalize-space(text())="description"]', output, 1
assert_xpath '/*[@class="hdlist"]/table/tr[2]/td', output, 2
assert_xpath '((//tr)[2]/td)[1][normalize-space(text())="second term"]', output, 1
- assert_xpath '((//tr)[2]/td)[2]/p[normalize-space(text())="definition"]', output, 1
+ assert_xpath '((//tr)[2]/td)[2]/p[normalize-space(text())="description"]', output, 1
end
test 'should set col widths of item and label if specified' do
@@ -2594,7 +2619,7 @@ term:: def
[horizontal]
term::
alt term::
-definition
+description
last::
EOS
@@ -2612,7 +2637,7 @@ last::
[horizontal]
term::
alt term::
-definition
+description
last::
EOS
@@ -2628,11 +2653,11 @@ last::
input = <<-EOS
.Terms
[horizontal]
-first term:: definition
+first term:: description
+
more detail
-second term:: definition
+second term:: description
EOS
output = render_embedded_string input, :backend => 'docbook'
assert_xpath '/table', output, 1
@@ -3010,7 +3035,7 @@ term1::
assert_xpath '//*[@class="dlist"]//dd/p/following-sibling::*[@class="literalblock"]//pre[text()="literal"]', output, 2
end
- test 'folds text of subsequent line and appends following literal line offset by blank line as block if term has no inline definition' do
+ test 'folds text of subsequent line and appends following literal line offset by blank line as block if term has no inline description' do
input = <<-EOS
== Lists
@@ -3030,7 +3055,7 @@ term2:: def2
assert_xpath '(//*[@class="dlist"]//dd)[1]/p/following-sibling::*[@class="literalblock"]//pre[text()="literal"]', output, 1
end
- test 'appends literal line attached by continuation as block if item has no inline definition' do
+ test 'appends literal line attached by continuation as block if item has no inline description' do
input = <<-EOS
== Lists
@@ -3047,7 +3072,7 @@ term1::
assert_xpath '//*[@class="dlist"]//dd/*[@class="literalblock"]//pre[text()="literal"]', output, 1
end
- test 'appends literal line attached by continuation as block if item has no inline definition followed by ruler' do
+ test 'appends literal line attached by continuation as block if item has no inline description followed by ruler' do
input = <<-EOS
== Lists
@@ -3067,7 +3092,7 @@ term1::
assert_xpath '//*[@class="dlist"]/following-sibling::hr', output, 1
end
- test 'appends line attached by continuation as block if item has no inline definition followed by ruler' do
+ test 'appends line attached by continuation as block if item has no inline description followed by ruler' do
input = <<-EOS
== Lists
@@ -3087,7 +3112,7 @@ para
assert_xpath '//*[@class="dlist"]/following-sibling::hr', output, 1
end
- test 'appends line attached by continuation as block if item has no inline definition followed by block' do
+ test 'appends line attached by continuation as block if item has no inline description followed by block' do
input = <<-EOS
== Lists
@@ -3134,7 +3159,7 @@ detached
assert_xpath '//*[@class="dlist"]/following-sibling::*[@class="literalblock"]//pre[text()="detached"]', output, 1
end
- test 'appends list if item has no inline definition' do
+ test 'appends list if item has no inline description' do
input = <<-EOS
== Lists
@@ -3177,13 +3202,13 @@ term2:: def2
== Lists
label 1::
- definition 1
+ description 1
* one
* two
* three
label 2::
- definition 2
+ description 2
paragraph
EOS
@@ -3193,8 +3218,8 @@ paragraph
assert_xpath '(//*[@class="dlist"]//dt)[1][normalize-space(text())="label 1"]', output, 1
assert_xpath '(//*[@class="dlist"]//dt)[2][normalize-space(text())="label 2"]', output, 1
assert_css '.dlist dd', output, 2
- assert_xpath '(//*[@class="dlist"]//dd)[1]/p[text()="definition 1"]', output, 1
- assert_xpath '(//*[@class="dlist"]//dd)[2]/p[text()="definition 2"]', output, 1
+ assert_xpath '(//*[@class="dlist"]//dd)[1]/p[text()="description 1"]', output, 1
+ assert_xpath '(//*[@class="dlist"]//dd)[2]/p[text()="description 2"]', output, 1
assert_xpath '(//*[@class="dlist"]//dd)[1]/p/following-sibling::*[@class="ulist"]', output, 1
assert_xpath '(//*[@class="dlist"]//dd)[1]/p/following-sibling::*[@class="ulist"]//li', output, 3
assert_css '.dlist + .paragraph', output, 1
@@ -3205,13 +3230,13 @@ paragraph
== Lists
label 1::
- definition 1
+ description 1
+
* one
* two
* three
label 2::
- definition 2
+ description 2
paragraph
EOS
@@ -3221,8 +3246,8 @@ paragraph
assert_xpath '(//*[@class="dlist"]//dt)[1][normalize-space(text())="label 1"]', output, 1
assert_xpath '(//*[@class="dlist"]//dt)[2][normalize-space(text())="label 2"]', output, 1
assert_css '.dlist dd', output, 2
- assert_xpath '(//*[@class="dlist"]//dd)[1]/p[text()="definition 1"]', output, 1
- assert_xpath '(//*[@class="dlist"]//dd)[2]/p[text()="definition 2"]', output, 1
+ assert_xpath '(//*[@class="dlist"]//dd)[1]/p[text()="description 1"]', output, 1
+ assert_xpath '(//*[@class="dlist"]//dd)[2]/p[text()="description 2"]', output, 1
assert_xpath '(//*[@class="dlist"]//dd)[1]/p/following-sibling::*[@class="ulist"]', output, 1
assert_xpath '(//*[@class="dlist"]//dd)[1]/p/following-sibling::*[@class="ulist"]//li', output, 3
assert_css '.dlist + .paragraph', output, 1
@@ -3297,7 +3322,7 @@ notnestedterm:::
assert_xpath %(//*[@class="dlist"]//dd/*[@class="literalblock"]//pre[text()=" literal\nnotnestedterm:::"]), output, 2
end
- test 'line attached by continuation is appended as paragraph if term has no inline definition' do
+ test 'line attached by continuation is appended as paragraph if term has no inline description' do
input = <<-EOS
== Lists
@@ -3318,7 +3343,7 @@ para
input = <<-EOS
term1:: def
+
-more definition
+more description
not a term::: def
EOS
@@ -3335,7 +3360,7 @@ not a term::: def
input = <<-EOS
term1:: def
+
-more definition
+more description
not a term:: def
EOS
@@ -3352,7 +3377,7 @@ not a term:: def
term1:: def
+
[quote]
-more definition
+more description
not a term::: def
EOS
@@ -3363,7 +3388,7 @@ not a term::: def
assert output.include?('not a term::: def')
end
- test 'appends line as paragraph if attached by continuation following blank line and line comment when term has no inline definition' do
+ test 'appends line as paragraph if attached by continuation following blank line and line comment when term has no inline description' do
input = <<-EOS
== Lists
@@ -3382,7 +3407,7 @@ para
assert_xpath '//*[@class="dlist"]//dd/*[@class="paragraph"]/p[text()="para"]', output, 1
end
- test 'line attached by continuation offset by blank line is appended as paragraph if term has no inline definition' do
+ test 'line attached by continuation offset by blank line is appended as paragraph if term has no inline description' do
input = <<-EOS
== Lists
@@ -3400,7 +3425,7 @@ para
assert_xpath '//*[@class="dlist"]//dd/*[@class="paragraph"]/p[text()="para"]', output, 1
end
- test 'delimited block breaks list even when term has no inline definition' do
+ test 'delimited block breaks list even when term has no inline description' do
input = <<-EOS
== Lists
@@ -3417,7 +3442,7 @@ detached
assert_xpath '//*[@class="dlist"]/following-sibling::*[@class="exampleblock"]//p[text()="detached"]', output, 1
end
- test 'attribute line breaks list even when term has no inline definition' do
+ test 'attribute line breaks list even when term has no inline description' do
input = <<-EOS
== Lists
@@ -3433,7 +3458,7 @@ detached
assert_xpath '//*[@class="dlist"]/following-sibling::*[@class="verseblock"]/pre[text()="detached"]', output, 1
end
- test 'id line breaks list even when term has no inline definition' do
+ test 'id line breaks list even when term has no inline description' do
input = <<-EOS
== Lists
@@ -3452,7 +3477,7 @@ detached
context 'Item with text inline' do
- test 'folds text from inline definition and subsequent line' do
+ test 'folds text from inline description and subsequent line' do
input = <<-EOS
== Lists
@@ -3466,7 +3491,7 @@ continued
assert_xpath %(//*[@class="dlist"]//dd/p[text()="def1\ncontinued"]), output, 1
end
- test 'folds text from inline definition and subsequent lines' do
+ test 'folds text from inline description and subsequent lines' do
input = <<-EOS
== Lists
@@ -3481,7 +3506,7 @@ continued
assert_xpath %(//*[@class="dlist"]//dd/p[text()="def1\ncontinued\ncontinued"]), output, 1
end
- test 'folds text from inline definition and line following comment line' do
+ test 'folds text from inline description and line following comment line' do
input = <<-EOS
== Lists
@@ -3496,7 +3521,7 @@ continued
assert_xpath %(//*[@class="dlist"]//dd/p[text()="def1\ncontinued"]), output, 1
end
- test 'folds text from inline definition and subsequent indented line' do
+ test 'folds text from inline description and subsequent indented line' do
input = <<-EOS
== Lists
@@ -3510,7 +3535,7 @@ term1:: def1
assert_xpath %(//*[@class="dlist"]//dd/p[text()="def1\ncontinued"]), output, 1
end
- test 'appends literal line offset by blank line as block if item has inline definition' do
+ test 'appends literal line offset by blank line as block if item has inline description' do
input = <<-EOS
== Lists
@@ -3527,7 +3552,7 @@ term1:: def1
assert_xpath '//*[@class="dlist"]//dd/p/following-sibling::*[@class="literalblock"]//pre[text()="literal"]', output, 1
end
- test 'appends literal line offset by blank line as block and appends line after continuation as block if item has inline definition' do
+ test 'appends literal line offset by blank line as block and appends line after continuation as block if item has inline description' do
input = <<-EOS
== Lists
@@ -3548,7 +3573,7 @@ para
assert_xpath '//*[@class="dlist"]//dd/*[@class="literalblock"]/following-sibling::*[@class="paragraph"]/p[text()="para"]', output, 1
end
- test 'appends line after continuation as block and literal line offset by blank line as block if item has inline definition' do
+ test 'appends line after continuation as block and literal line offset by blank line as block if item has inline description' do
input = <<-EOS
== Lists
@@ -3569,7 +3594,7 @@ para
assert_xpath '//*[@class="dlist"]//dd/*[@class="paragraph"]/following-sibling::*[@class="literalblock"]//pre[text()="literal"]', output, 1
end
- test 'appends list if item has inline definition' do
+ test 'appends list if item has inline description' do
input = <<-EOS
== Lists
@@ -3587,7 +3612,7 @@ term1:: def1
assert_xpath '//*[@class="dlist"]//dd/p/following-sibling::*[@class="ulist"]/ul/li', output, 3
end
- test 'appends literal line attached by continuation as block if item has inline definition followed by ruler' do
+ test 'appends literal line attached by continuation as block if item has inline description followed by ruler' do
input = <<-EOS
== Lists
@@ -3607,7 +3632,7 @@ term1:: def1
assert_xpath '//*[@class="dlist"]/following-sibling::hr', output, 1
end
- test 'line offset by blank line breaks list if term has inline definition' do
+ test 'line offset by blank line breaks list if term has inline description' do
input = <<-EOS
== Lists
@@ -3624,7 +3649,7 @@ detached
assert_xpath '//*[@class="dlist"]/following-sibling::*[@class="paragraph"]/p[text()="detached"]', output, 1
end
- test 'nested term with definition does not consume following heading' do
+ test 'nested term with description does not consume following heading' do
input = <<-EOS
== Lists
@@ -3649,7 +3674,7 @@ Detached
assert_xpath '//*[@class="dlist"]/following-sibling::*[@class="sect2"]/h3[text()="Detached"]', output, 1
end
- test 'line attached by continuation is appended as paragraph if term has inline definition followed by detached paragraph' do
+ test 'line attached by continuation is appended as paragraph if term has inline description followed by detached paragraph' do
input = <<-EOS
== Lists
@@ -3670,7 +3695,7 @@ detached
assert_xpath '//*[@class="dlist"]/following-sibling::*[@class="paragraph"]/p[text()="detached"]', output, 1
end
- test 'line attached by continuation is appended as paragraph if term has inline definition followed by detached block' do
+ test 'line attached by continuation is appended as paragraph if term has inline description followed by detached block' do
input = <<-EOS
== Lists
@@ -3693,7 +3718,7 @@ detached
assert_xpath '//*[@class="dlist"]/following-sibling::*[@class="sidebarblock"]//p[text()="detached"]', output, 1
end
- test 'line attached by continuation offset by line comment is appended as paragraph if term has inline definition' do
+ test 'line attached by continuation offset by line comment is appended as paragraph if term has inline description' do
input = <<-EOS
== Lists
@@ -3711,7 +3736,7 @@ para
assert_xpath '//*[@class="dlist"]//dd/p/following-sibling::*[@class="paragraph"]/p[text()="para"]', output, 1
end
- test 'line attached by continuation offset by blank line is appended as paragraph if term has inline definition' do
+ test 'line attached by continuation offset by blank line is appended as paragraph if term has inline description' do
input = <<-EOS
== Lists
diff --git a/test/manpage_test.rb b/test/manpage_test.rb
index bac232b..101b9b2 100644
--- a/test/manpage_test.rb
+++ b/test/manpage_test.rb
@@ -200,4 +200,19 @@ T}
.TE'
end
end
+
+ context 'Environment' do
+ test 'should use SOURCE_DATE_EPOCH as modified time of input file and local time' do
+ old_source_date_epoch = ENV.delete 'SOURCE_DATE_EPOCH'
+ begin
+ ENV['SOURCE_DATE_EPOCH'] = '1234123412'
+ output = Asciidoctor.convert SAMPLE_MANPAGE_HEADER, :backend => :manpage, :header_footer => true
+ assert_match(/Date: 2009-02-08/, output)
+ assert_match(/^\.TH "COMMAND" "1" "2009-02-08" "Command 1.2.3" "Command Manual"$/, output)
+ ensure
+ ENV['SOURCE_DATE_EPOCH'] = old_source_date_epoch if old_source_date_epoch
+ end
+ end
+ end
+
end
diff --git a/test/paths_test.rb b/test/paths_test.rb
index d47b951..bf9f73b 100644
--- a/test/paths_test.rb
+++ b/test/paths_test.rb
@@ -43,7 +43,10 @@ context 'Path Resolver' do
test 'target with relative path appended to start path' do
assert_equal 'assets/images', @resolver.web_path('images', 'assets')
assert_equal '/assets/images', @resolver.web_path('images', '/assets')
+ #assert_equal '/assets/images/tiger.png', @resolver.web_path('tiger.png', '/assets//images')
assert_equal './assets/images', @resolver.web_path('images', './assets')
+ assert_equal '/theme.css', @resolver.web_path('theme.css', '/')
+ assert_equal '/css/theme.css', @resolver.web_path('theme.css', '/css/')
end
test 'target with path relative to current directory appended to start path' do
diff --git a/test/reader_test.rb b/test/reader_test.rb
index 281d7f0..b70908a 100644
--- a/test/reader_test.rb
+++ b/test/reader_test.rb
@@ -455,11 +455,11 @@ preamble
end
context 'Include Stack' do
- test 'PreprocessorReader#push_include method should return nil' do
+ test 'PreprocessorReader#push_include method should return reader' do
reader = empty_document.reader
append_lines = %w(one two three)
result = reader.push_include append_lines, '<stdin>', '<stdin>'
- assert_nil result
+ assert_equal reader, result
end
test 'PreprocessorReader#push_include method should put lines on top of stack' do
diff --git a/test/sections_test.rb b/test/sections_test.rb
index 344efd4..2568abb 100644
--- a/test/sections_test.rb
+++ b/test/sections_test.rb
@@ -51,6 +51,16 @@ context 'Sections' do
assert_equal '_sectionone', sec.id
end
+ test 'synthetic id separator can be set to blank when idprefix is blank' do
+ sec = block_from_string(":idprefix:\n:idseparator:\n\n== Section One")
+ assert_equal 'sectionone', sec.id
+ end
+
+ test 'synthetic id separator is removed from beginning of id when idprefix is blank' do
+ sec = block_from_string(":idprefix:\n:idseparator: _\n\n== +Section One")
+ assert_equal 'section_one', sec.id
+ end
+
test 'synthetic ids can be disabled' do
sec = block_from_string(":sectids!:\n\n== Section One\n")
assert sec.id.nil?
diff --git a/test/substitutions_test.rb b/test/substitutions_test.rb
index d3a08ca..d44a5e0 100644
--- a/test/substitutions_test.rb
+++ b/test/substitutions_test.rb
@@ -655,15 +655,15 @@ context 'Substitutions' do
test 'an image macro with an inline SVG image should be converted to an svg element' do
para = block_from_string('image:circle.svg[Tiger,100,opts=inline]', :safe => Asciidoctor::SafeMode::SERVER, :attributes => { 'imagesdir' => 'fixtures', 'docdir' => ::File.dirname(__FILE__) })
result = para.sub_macros(para.source).gsub(/>\s+</, '><')
- assert_match(/<svg [^>]*width="100px"[^>]*>/, result)
- refute_match(/<svg [^>]*width="500px"[^>]*>/, result)
- refute_match(/<svg [^>]*height="500px"[^>]*>/, result)
- refute_match(/<svg [^>]*style="width:500px;height:500px"[^>]*>/, result)
+ assert_match(/<svg\s[^>]*width="100px"[^>]*>/, result)
+ refute_match(/<svg\s[^>]*width="500px"[^>]*>/, result)
+ refute_match(/<svg\s[^>]*height="500px"[^>]*>/, result)
+ refute_match(/<svg\s[^>]*style="width:500px;height:500px"[^>]*>/, result)
end
test 'an image macro with an inline SVG image should be converted to an svg element even when data-uri is set' do
para = block_from_string('image:circle.svg[Tiger,100,opts=inline]', :safe => Asciidoctor::SafeMode::SERVER, :attributes => { 'data-uri' => '', 'imagesdir' => 'fixtures', 'docdir' => ::File.dirname(__FILE__) })
- assert_match(/<svg [^>]*width="100px">/, para.sub_macros(para.source).gsub(/>\s+</, '><'))
+ assert_match(/<svg\s[^>]*width="100px">/, para.sub_macros(para.source).gsub(/>\s+</, '><'))
end
test 'an image macro with an SVG image should not use an object element when safe mode is secure' do
@@ -1500,11 +1500,17 @@ foo — '
end
test 'preserves entity references' do
- input = '& © ✔ •'
+ input = '& © ✔ 😀 • 😀'
result = render_embedded_string input, :doctype => :inline
assert_equal input, result
end
+ test 'only preserves named entities with two or more letters' do
+ input = '& &a; >'
+ result = render_embedded_string input, :doctype => :inline
+ assert_equal '& &a; >', result
+ end
+
test 'replaces punctuation' do
para = block_from_string %(John's Hideout is the Whites`' place... foo\\'bar)
assert_equal "John’s Hideout is the Whites’ place… foo'bar", para.sub_replacements(para.source)
diff --git a/test/tables_test.rb b/test/tables_test.rb
index 4c4d320..5b01bea 100644
--- a/test/tables_test.rb
+++ b/test/tables_test.rb
@@ -191,6 +191,22 @@ A | here| a | there
assert_css 'table colgroup col[width]', output, 0
end
+ test 'explicit table width is used even when autowidth option is specified' do
+ input = <<-EOS
+[%autowidth,width=75%]
+|=======
+|A |B |C
+|a |b |c
+|1 |2 |3
+|=======
+ EOS
+ output = render_embedded_string input
+ assert_css 'table', output, 1
+ assert_css 'table[style*="width"]', output, 1
+ assert_css 'table colgroup col', output, 3
+ assert_css 'table colgroup col[width]', output, 0
+ end
+
test 'first row sets number of columns when not specified' do
input = <<-EOS
|====
@@ -362,6 +378,21 @@ A | here| a | there
assert_css 'table > tgroup > tbody > row', output, 3
end
+ test 'table with landscape orientation in DocBook' do
+ ['orientation=landscape', '%rotate'].each do |attrs|
+ input = <<-EOS
+[#{attrs}]
+|===
+|Column A | Column B | Column C
+|===
+ EOS
+
+ output = render_embedded_string input, :backend => 'docbook'
+ assert_css 'informaltable', output, 1
+ assert_css 'informaltable[orient="land"]', output, 1
+ end
+ end
+
test 'table with implicit header row' do
input = <<-EOS
|===
@@ -384,6 +415,27 @@ A | here| a | there
assert_css 'table > tbody > tr', output, 2
end
+ test 'table with implicit header row when other options set' do
+ input = <<-EOS
+[%autowidth]
+|===
+|Column 1 |Column 2
+
+|Data A1
+|Data B1
+|===
+ EOS
+ output = render_embedded_string input
+ assert_css 'table', output, 1
+ assert_css 'table[style*="width"]', output, 0
+ assert_css 'table > colgroup > col', output, 2
+ assert_css 'table > thead', output, 1
+ assert_css 'table > thead > tr', output, 1
+ assert_css 'table > thead > tr > th', output, 2
+ assert_css 'table > tbody', output, 1
+ assert_css 'table > tbody > tr', output, 1
+ end
+
test 'no implicit header row if second line not blank' do
input = <<-EOS
|===
@@ -425,9 +477,9 @@ A | here| a | there
assert_css 'table > tbody > tr', output, 3
end
- test 'no implicit header row if options is specified' do
+ test 'no implicit header row if noheader option is specified' do
input = <<-EOS
-[options=""]
+[%noheader]
|===
|Column 1 |Column 2
@@ -671,6 +723,28 @@ d|9 2+>|10
assert_xpath '(//row)[2]/entry[@nameend]', output, 0
end
+ test 'assigns unique column names for table with implicit column count and colspans in first row' do
+ input = <<-EOS
+|====
+| 2+| Node 0 2+| Node 1
+
+| Host processes | Core 0 | Core 1 | Core 4 | Core 5
+| Guest processes | Core 2 | Core 3 | Core 6 | Core 7
+|====
+ EOS
+
+ output = render_embedded_string input, :backend => 'docbook'
+ assert_xpath '//colspec', output, 5
+ (1..5).each do |n|
+ assert_xpath %((//colspec)[#{n}][@colname="col_#{n}"]), output, 1
+ end
+ assert_xpath '(//row)[1]/entry', output, 3
+ assert_xpath '((//row)[1]/entry)[1][@namest]', output, 0
+ assert_xpath '((//row)[1]/entry)[1][@namend]', output, 0
+ assert_xpath '((//row)[1]/entry)[2][@namest="col_2"][@nameend="col_3"]', output, 1
+ assert_xpath '((//row)[1]/entry)[3][@namest="col_4"][@nameend="col_5"]', output, 1
+ end
+
test 'ignores cell with colspan that exceeds colspec' do
input = <<-EOS
[cols="1,1"]
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/asciidoctor.git
More information about the Pkg-ruby-extras-commits
mailing list