Migrate to Netlify Today

Netlify announces the next evolution of Gatsby Cloud. Learn more

ContactSign Up
Community Plugin
View plugin on GitHub

= gatsby-transformer-asciidoc :author-name: hitsuji no shippo :!author-email: :author: {author-name} :!email: {author-email} :revnumber: v1.35.0 :revdate: 2020-01-25T15:57:43+0900 :revmark: Add default value of enablesEmptyAttribute :doctype: article :copyright: Copyright (c) 2019 {author-name} :title-separtor: : :!showtitle: :!sectnums: :sectids: :toc: preamble :toclevels: 3 :sectlinks: :sectanchors: :idprefix: :idseparator: - :xrefstyle: full :!example-caption: :!figure-caption: :!table-caption: :!listing-caption: ifdef::env-github[] :caution-caption: :fire: :important-caption: :exclamation: :note-caption: :paperclip: :tip-caption: :bulb: :warning-caption: :warning: endif::[] ifndef::env-github[:icons: font] // Page Attributes :page-create-date: 2019-08-13T16:42:02+0900 // Variables :author-link-url: https://github.com/hitsuji-no-shippo :asciidoctor-official-docs-url: https://asciidoctor.org/docs :asciidoctor-js-docs-antora-url: https://asciidoctor-docs.netlify.com/asciidoctor.js :github-url: https://github.com :github-account-url: {github-url}/hitsuji-no-shippo :issues-url: {github-account-url}/gatsby-transformer-asciidoc/issues :yaml-example-url: https://en.wikipedia.org/wiki/YAML#Example

Parses AsciiDoc files using link:{asciidoctor-official-docs-url}/asciidoctor.js/[Asciidoctor.js].


Tested only with link:https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-source-filesystem[ gatsby-source-filesystem^]. Have not tested with other source plugins.

== Install

npm install --save @hitsuji_no_shippo/gatsby-transformer-asciidoc

== How to use

.gatsby-config.js [source, JavaScript]

plugins: [gatsby-transformer-asciidoc]

A full explanation of asciidoc can be found here: link:{github-url}/asciidoctor/asciidoctor.js[Asciidoctor.js]

You can also pass all link:{asciidoctor-js-docs-antora-url}/processor/convert-options/[ Asciidoctor’s convert options] to the transformer. An example would be:

.gatsby-config.js [source, JavaScript]

plugins: [ { resolve: @hitsuji_no_shippo/gatsby-transformer-asciidoc, options: { attributes: { values: { showtitle: true, }, }, }, }, ]

[[use-boolean-to-value]] [CAUTION]

.Boolean [source, JavaScript]

attributes: { values: { page-index: true, // <1> page-draft: false, // <2> }, },

<1> same as :page-index: true. Not the same as :page-index: <2> same as :!page-draft:

== How to query

A sample GraphQL query to get AsciiDoc nodes:

[source, GraphQL]

{ allAsciidoc { edges { node { html timeToRead document { title subtitle main description } author { fullName firstName lastName middleName authorInitials email } revision { date number remark } paths { absolute { file // <1> } from { project { dir full } source { file // <2> full // <3> } } } } } } }

<1> node.absolutePath <2> [[path-file-from-source-dir-field]] Relative Directory (node.relativeDirectory) + Name (node.name) <3> node.relativePath

[[paths-field-example]] [example]

.gatsby-config.js [source, JavaScript]

{ resolve: gatsby-source-filesystem, options: { path: ${__dirname}/content/blog, name: blog, }, },

[cols=“5*m”, options=“header, autowidth”] |=== |path |paths.from.project.dir |paths.from.project.full |paths.from.source.file |paths.from.source.full

|/content/blog/about.adoc |content/blog |content/blog/about.adoc |about |about.adoc

|/content/blog/post/gatsby.adoc |content/blog/post |content/blog/post/gatsby.adoc |post/gatsby |post/gatsby.adoc |===

== Parsing algorithm

It recognizes files with the following link:{asciidoctor-official-docs-url}/asciidoc-recommended-practices/#document-extension[ extensions] as AsciiDoc:

  • adoc
  • asciidoc

Additional extensions can be configured via the fileExtensions option:

.gatsby-config.js [source, JavaScript]

plugins: [ { resolve: @hitsuji_no_shippo/gatsby-transformer-asciidoc, options: { attributes: { values: { showtitle: true, }, }, fileExtensions: [ad, adoc], }, }, ]

Each AsciiDoc file is parsed into a node of type asciidoc.

== Set imagesdir

You also can define where the asciidoc file can find the images by setting the imagesdir attribute.

.gatsby-config.js [source, JavaScript]

plugins: [ { resolve: @hitsuji_no_shippo/gatsby-transformer-asciidoc, options: { attributes: { values: { ‘imagesdir@‘: /images, }, }, }, }, ]

In the asciidoc file you can insert your image just by using: image::myimage.png[]


  • If no imagesdir@ is set the default value is /images
  • Don’t use relative images paths because the images might not be copied automatically to the location where the converted asciidoc html file will to located.
  • In case a pathPrefix is set it will altered the images location.
  • In case you want to be able to override the defined imagesdir inside of your asciidoc file you have to end the attribute name with a @ (e.g. imagesdir@).


== Add new node attributes in the asciidoc file

You can define in the asciidoc file your own data that will be automatically be attached to the node attributes.

.Example [source, AsciiDoc]

= AsciiDoc Article Title Firstname Lastname author@example.org 1.0, July 29, 2018, Asciidoctor article template

:page-title: Article :page-path: /my-blog-entry :page-category: My Category

Each attribute with the prefix xref:pageAttributePrefix[] option value (default: page-) will be automatically added under pageAttributes so it can be used with GraphQL. Name is the attribute name with the prefix removed. Attribute value is processed as link:{yaml-example-url}[YAML] data.

[source, GraphQL]

{ allAsciidoc { edges { node { pageAttributes { title path category } } } } }



If the value starts with { (e.g. {github-url}/hitsuji_no_shippo), the following error occurs:

[literal] … YAMLException: end of the stream or a document separator is expected at line 1, column 13: {github-url}/hitsuji_no_shippo ^ …

There is a way to avoid the error, but I’m not sure if it should be avoided. (link:{issues-url}/56[#56])

== Options

=== Attributes

:self-reference-object-url: {github-account-url}/self-referenced-object/tree/60f18190c552116aa5a4e30879b7a7d4832b9362 ==== Refer to self attributes

You can use attributes.options.selfReferendObject to refer to the value in options.attributes.values.all. Please read link:{self-reference-object-url}[ self-reference-object] README for details.

.gatsby-config.js [source, JavaScript]

plugins: [ { resolve: @hitsuji_no_shippo/gatsby-transformer-asciidoc, options: { attributes: { values: { ‘github-’: { url: ’https://github.com‘, ‘my-’: { id: ‘hitsuji-no-shippo’, ‘page-url’: ’${this.(../url)}/${this.(./id)}’, } }, country: ‘Japan’, comment: ‘Live in ${this.country}. link:${this.github-my-page-url}[My page].’ }, options: { selfReferendObject: { runs: true, // <1> shouldConvert: true // <2> }, }, }, }, }, ]

<1> [[self-referenced-object-runs]] Whether to run refer processing. (Default is true) <2> [[self-referenced-should-convert]] Whether to convert reference from directory to key (e.g. this.(./id) => this.github-my-id) processing. (Default is true)

.Result [source, JavaScript]

{ ‘github-url’: ’https://github.com’, ‘github-my-id’: ‘hitsuji-no-shippo’, ‘github-my-page-url’: ’https://github.com/hitsuji-no-shippo’ country: ‘Japan’, comment: ‘Live in Japan. link:https://github.com/hitsuji-no-shippo[My page].’, }

==== Add partials attributes

Use attributes.options.partials to add attributes to files with specific path. Used path value is xref:path-file-from-source-dir-field[ paths.from.source.file field] value.

Please read link:{github-account-url}/extract-matching-values-in-patterns/tree/c8f32e9528a74d8be9c041c1d21c735393d63663[ README] for details.

.Example [%collapsible]

.gatsby-config.js [source, JavaScript]

plugins: [ { resolve: @hitsuji_no_shippo/gatsby-transformer-asciidoc, options: { enablesEmptyAttribute: true, // <5> pageAttributePrefix: page-, attributes: { values: { … }, options: { selfReferendObject: { … }, partials: { shouldReferSelf: true, // <1> shouldConvert: true, // <2> shouldReferToAttributesToAddToAll: true, // <3> attributes: { // <4> posts: { values: { page-posts: ”, // <5> page-index: ”, page-disqus: ”, }, } pages: { values: { page-pages: ”, }, }, }, }, }, }, }, }, ]

<1> Same xref:self-referenced-object-runs[selfReferendObject.runs]. The target is attributes.partials.attributes. (Default is true) <2> Same xref:self-referenced-should-convert[selfReferendObject.shouldConvert]. The target is attributes.partials.attributes. (Default is true) <3> link:{self-reference-object-url}#refer-another-object-key-values[ Whether to refer to attributes.values]. (Default is true) <4> An object that holds path and attributes to add. If the value is undefined, the process is not run. <5> xref:empty-value[enablesEmptyAttribute] useing to convert '' to true and null to false. If xref:use-boolean-to-value[use true and false], the value of field using false is null.

[cols=3*a, options=“header, autowidth”] |=== |paths.from.source.file |Additional attributes |GraphQL

|posts/gatsby |

[source, JavaScript]

{ page-posts: ”, <1> page-index: ”, page-disqus:” }

<1> same as :page-posts: |

[source, GraphQL]

“pageAttributes”: { “disqus”: true, “pages”: false, // <1> “index”: true, “posts”: true }

<1> If input page-pages: false, the value is null.

|pages/profile |

[source, JavaScript]

{ page-pages: ” }


[source, GraphQL]

“pageAttributes”: { “disqus”: false, “pages”: true, “index”: false, “posts”: false }


==== Replace attributes to field value

Values that cannot be referenced when createing a node, such as slug, can be replaced as attributes in HTML (node.html). Default is empty.

.gatsby-config.js [source, JavaScript]

plugins: [ { resolve: @hitsuji_no_shippo/gatsby-transformer-asciidoc, options: { attributes: { options: { replace: { slug: ‘fields.slug’ // <1> } }, }, }, }, ]

<1> Replace {slug} to node.fields.slug value.

==== Add path attributes

The values of xref:paths-field-example[ node.paths field] is avaliable as an attributes. Default is empty.

.gatsby-config.js [source, JavaScript]

plugins: [ { resolve: @hitsuji_no_shippo/gatsby-transformer-asciidoc, options: { attributes: { options: { paths: { dir: from.project.dir // <1> full: from.source.full // <2> } }, }, }, }, ]

.Asciidoc [source, AsciiDoc]

<1> Replace {dir} to node.paths.from.project.dir <2> Replace {full} to node.paths.from.source.full

=== pageAttributePrefix

The value specifies the prefix of attribute to be added to the pageAttributes field. Default is page-.

.gatsby-config.js [source, JavaScript]

plugins: [ { resolve: @hitsuji_no_shippo/gatsby-transformer-asciidoc, options: { pageAttributePrefix: gatsby-, }, }, ]

All attribute Add under pageAttributes when the value is ''.

=== Empty Value

Attribute with empty value (:page-draft:) is convert true. If attributes is not set for page, returns false instead of null.

If even one Attribute value is empty, all attributes with the same name will return Boolean. So non-boolean values are converted to false. true and false are not convert.

If Attribute is not set and only unset, the attribute is not defined in GraphQL field.


This process is not executed when enablesEmptyAttribute option is false (Default is false). The empty attribute is not defined in GraphQL field.

.gatsby-config.js [source, JavaScript]

plugins: [ { resolve: @hitsuji_no_shippo/gatsby-transformer-asciidoc, options: { enablesEmptyAttribute: false, } }, ]


.Examples [%collapsible]


=== Ignore

If the attribute matches the value, no Ascidoc node is created. Default is null.

.gatsby-config.js [source, JavaScript]

plugins: [ { resolve: @hitsuji_no_shippo/gatsby-transformer-asciidoc, options: { ignore: { unpublish: [”, ‘true’] // <1> } } }, ]

<1> '' is :unpublish:, 'true' is :unpublish: true, not true.

=== OptionFile

You can change the option file with the OptionFile option.

.gatsby-config.js [source, JavaScript]

plugins: [ { resolve: @hitsuji_no_shippo/gatsby-transformer-asciidoc, options: { OptionFile: { path: file-path <1> encoding: file-encoding <2> } }, }, ]

<1> Default ./asciidoctor-option.yaml <2> Default utf8


When reading, the attributes option must be of type object.

==== Option File

link:{yaml-example-url}[YAML] file can be load. Default option file path is ./asciidoctor-option.yaml. The value of gatsby-config.js takes precedence over YAML file.

.Example [source, YAML]

attributes: values: gatsby-url: https://www.gatsbyjs.org asciidoctor-url: https://asciidoctor

pageAttributePrefix: gatsby- enablesEmptyAttribute: true


You can also xref:refer-to-self-attributes[refer to the attributes value] in option file.

JSON is hard to write, so I chose yaml.

== Define a custom converter

You can define a custom converter by adding the converterFactory option.

.gatsby-config.js [source, JavaScript]

// Make sure to import or declare TemplateConverter plugins: [ { resolve: @hitsuji_no_shippo/gatsby-transformer-asciidoc, options: { converterFactory: TemplateConverter, }, }, ]

TemplateConverter is a custom javascript class you’ll need to create. Information on how to write a custom TemplateConverter can be found at the link:{asciidoctor-js-docs-antora-url}/extend/converter/custom-converter/[ asciidoctor docs].

In the example below, we will use a custom converter to convert paragraphs but the other nodes will be converted using the built-in HTML5 converter:

[source, JavaScript]

const asciidoc = require(asciidoctor.js)()

class TemplateConverter { constructor() { this.baseConverter = asciidoc.Html5Converter.$new() }

convert(node, transform) { if (node.getNodeName() === “paragraph”) { return <p>${node.getContent()}</p> }

return this.baseConverter.convert(node, transform)

} }

== Front Matter support

You can front matter as frontmatter fields. Front Matter value is processed link:{yaml-example-url}[YAML] data.

To make the same field name for each link:{github-url}/gatsbyjs/gatsby/tree/master/packages/gatsby-transformer-remark#how-to-query[ gatsby-transformer-remark], I named it frontmatter.

.AsciiDoc file [source, Asciidoc]

author: {name: hitsuji no shippo, email: xxx@gmail.com} category: transformer tags: [gatsby, asciidoc]

= doctitle :author: hitsuji no shippo

.GraphQL [source, GraphQL]

{ allAsciidoc { edges { node { frontmatter { author { name email } category tags } } } } }


Asciidoctor attribute skip-front-matter is always true.

== Auto update for attributes

If xref:pageAttributePrefix[pageAttributePrefix] is different from cache, the pageAttributes field is automatically updated.

[horizontal] attributs:: Reload asciidoc using new attributes and update asciidoc fields values +


The fields are not added and deleted. Only update the values of existing fields. If you clear the cache, it’s OK. This issue will take time, so if there is a request, will fix it. (link:{issues-url}/54[#54])

— pageAttributePrefix:: Update pageAttributePrefix field


.Cache does not store default Cache stores input values every time. Default value is not included. Therefore, the update process is run in the following cases, although the result is the same.

.options of last time [source, JavaScript]

{ enablesEmptyAttribute: true, }

.options of this time [source, JavaScript]

{ enablesEmptyAttribute: true, pageAttributePrefix: page-, }


© 2023 Gatsby, Inc.