{"id":18889718,"url":"https://github.com/middleman/middleman-asciidoc","last_synced_at":"2026-04-09T10:41:29.485Z","repository":{"id":15521128,"uuid":"18255510","full_name":"middleman/middleman-asciidoc","owner":"middleman","description":":beginner: AsciiDoc support for Middleman 4. (In Middleman 3, AsciiDoc support is provided by a core extension).","archived":false,"fork":false,"pushed_at":"2023-10-31T08:52:28.000Z","size":258,"stargazers_count":26,"open_issues_count":6,"forks_count":12,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-03-28T11:38:25.319Z","etag":null,"topics":["asciidoc","asciidoctor","middleman-extension","ruby"],"latest_commit_sha":null,"homepage":"https://middlemanapp.com","language":"Gherkin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/middleman.png","metadata":{"files":{"readme":"README.adoc","changelog":"CHANGELOG.adoc","contributing":"CONTRIBUTING.adoc","funding":null,"license":"LICENSE.adoc","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-03-30T02:10:04.000Z","updated_at":"2025-03-21T21:04:52.000Z","dependencies_parsed_at":"2024-11-08T07:50:42.644Z","dependency_job_id":"93dbf1aa-11fa-4149-8beb-e6bee631b3ed","html_url":"https://github.com/middleman/middleman-asciidoc","commit_stats":{"total_commits":245,"total_committers":6,"mean_commits":"40.833333333333336","dds":0.04081632653061229,"last_synced_commit":"30d41349daeb88521b5338a722f054ed33ed449b"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/middleman%2Fmiddleman-asciidoc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/middleman%2Fmiddleman-asciidoc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/middleman%2Fmiddleman-asciidoc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/middleman%2Fmiddleman-asciidoc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/middleman","download_url":"https://codeload.github.com/middleman/middleman-asciidoc/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248978305,"owners_count":21192757,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asciidoc","asciidoctor","middleman-extension","ruby"],"created_at":"2024-11-08T07:50:29.971Z","updated_at":"2026-04-09T10:41:24.428Z","avatar_url":"https://github.com/middleman.png","language":"Gherkin","funding_links":[],"categories":[],"sub_categories":[],"readme":"= AsciiDoc Extension for Middleman (powered by Asciidoctor)\nDan Allen \u003chttps://github.com/mojavelinux[@mojavelinux]\u003e\n// Settings:\n:idprefix:\n:idseparator: -\n:hide-uri-scheme:\nifndef::env-github[:icons: font]\nifdef::env-github,env-browser[]\n:toc: preamble\n:toclevels: 1\nendif::[]\nifdef::env-github[]\n:status:\n:outfilesuffix: .adoc\n:!toc-title:\n:important-caption: :exclamation:\n:note-caption: :paperclip:\n:tip-caption: :bulb:\n:warning-caption: :warning:\nendif::[]\n// URIs:\n:uri-repo: https://github.com/middleman/middleman-asciidoc\n:uri-issues: https://github.com/middleman/middleman-asciidoc/issues\n:uri-middleman: https://middlemanapp.com\n:uri-middleman-forum: https://forum.middlemanapp.com\n:uri-asciidoc: http://asciidoc.org\n:uri-asciidoctor: http://asciidoctor.org\n:uri-asciidoctor-diagram: {uri-asciidoctor}/docs/asciidoctor-diagram\n:uri-asciidoctor-discuss: http://discuss.asciidoctor.org\n:uri-gem: https://rubygems.org/gems/middleman-asciidoc\n:uri-tilt: https://github.com/rtomayko/tilt\n:uri-yaml: https://en.wikipedia.org/wiki/YAML\n:uri-help-pr: https://help.github.com/articles/using-pull-requests\n:img-gem: https://img.shields.io/gem/v/middleman-asciidoc.svg?label=gem\n:uri-ci-github: {uri-repo}/actions\n:img-ci-github: https://github.com/asciidoctor/asciidoctor/workflows/CI/badge.svg\n\nifdef::status[]\nimage:{img-gem}[Gem Version,link={uri-gem}]\nimage:{img-ci-github}[Build Status (GitHub Actions),link={uri-ci-github}]\nendif::[]\n\nMiddleman AsciiDoc (gem: *middleman-asciidoc*) is an extension for the {uri-middleman}[Middleman] static site generator that adds support for the {uri-asciidoc}[AsciiDoc] lightweight markup language.\nSpecifically, this extension converts AsciiDoc files in your site source to HTML pages.\nThis conversion is performed using {uri-asciidoctor}[Asciidoctor] by default.\n\nIMPORTANT: This extension is designed for Middleman \u003e= 4.0.0.\nIt's tested using the lastest Middleman 4 release running on C Ruby \u003e= 2.3 and JRuby \u003e= 9.1.\nPrior to Middleman 4, AsciiDoc support was bundled with Middleman core.\n\n== Installation\n\nIf you're just getting started, first install the *middleman* gem.\n\n $ gem install middleman\n\nThen, generate a new project:\n\n $ middleman init MY_PROJECT\n\nThe project will be created in the MY_PROJECT directory.\n\nIf you're working with an existing project, you can skip the previous steps.\n\nNext, add the gem for this extension to your project's [.path]_Gemfile_.\n\n[source,ruby]\n----\ngem 'middleman-asciidoc'\n----\n\nFinally, run Bundler to install the dependencies using the `bundle` command:\n\n $ bundle\n\nYou're now ready to activate this extension and begin putting it to work.\n\n== Activation and Configuration\n\nTo activate the AsciiDoc extension, add the following line to the [.path]_config.rb_ file for your site:\n\n[source,ruby]\n----\nactivate :asciidoc\n----\n\nYou can also pass options to the extension.\nOne way is to pass a Hash of options as the second argument of `activate`.\nIn this case, the option keys must be expressed as symbols.\n\nHere's an example of how to set the `attributes` option for this extension, which assigns attributes to the underlying Asciidoctor processor:\n\n[source,ruby]\n----\nactivate :asciidoc, attributes: ['source-highlighter=coderay']\n----\n\nAlternately, you can assign options directly to the extension object when using the block form of `activate`.\nIn this case, the options are properties of the extension object.\n\nHere's how to assign the `attributes` option for this extension using the block form of `activate`:\n\n[source,ruby]\n----\nactivate :asciidoc do |asciidoc|\n  asciidoc.attributes = ['source-highlighter=coderay']\nend\n----\n\nThe following option keys can be used to configure this extension.\nWith the exception of `layout`, these option keys map directly to options in the Asciidoctor API.\n\nattributes (type: Hash or String Array, default: {})::\nCustom AsciiDoc attributes to pass to the processor.\nThe following built-in attributes are automatically appended to this collection.\n(You can remove one of these attributes by passing a custom attribute with the corresponding name prefixed with `-`).\n\n* env=site\n* env-site\n* site-gen=middleman\n* site-gen-middleman\n* builder=middleman\n* builder-middleman\n* middleman-version=(value of `Middleman::VERSION` constant)\n* site-root=(app.root.to_s)\n* site-source=(app.source_dir.to_s)\n* site-destination=(app.root.to_s + / + app.config[:build_dir])\n* site-environment=(app.environment.to_s)\n* relfilesuffix=(path to index file, as configured, if directory indexes are enabled)\n* relfilesuffix=../ if directory indexes are enabled\n* imagesdir=(http_prefix + app.config[:images_dir])@\n ** skipped if `-imagesdir` (soft unset) or `!imagesdir` (hard unset) is defined as a custom attribute\n ** can be overridden by page, hence the trailing @\n* imagesoutdir=(imagesdir relative to site destination)\n\npromoted_attributes (type: String Array, default: [])::\nList of attribute names in the document header to convert to page data (aka front matter).\nRefer to the \u003c\u003cAdding Custom Page Data\u003e\u003e section for details.\n\npromoted_attributes_convert_dashes (type: Boolean, default: false)::\nWhether to replace dashes in attribute names to underscores when promoting them to page data.\nRefer to the \u003c\u003cAdding Custom Page Data\u003e\u003e section for details.\n\nbackend (type: Symbol, default: :html5)::\nThe moniker for a converter, which determines the output format to generate.\n\nbase_dir (type: String, default: :docdir)::\nThe base directory to use for the current AsciiDoc document.\nIf not specified, defaults to the document directory (i.e., `:docdir`).\nTo set the base directory to the source directory, use the keyword `:source` or the expression `app.source_dir`.\nTo leave the base directory undefined, use the value `nil`.\n\nlayout (type: String or Symbol, default: nil)::\nThe name of the default layout for AsciiDoc-based pages (pages processed by this extension, not including blog articles if a blog layout is specified).\n\nsafe (type: Symbol, default: :safe)::\nThe safe mode level under which to run the AsciiDoc processor.\n\ntemplate_dirs (type: String or String Array, default: nil)::\nOne or more directory paths (relative to the site root) where Asciidoctor converter templates should be discovered.\nAsciidoctor templates can be used to customize the HTML generated for each node in the Asciidoctor document tree.\n\ntemplate_engine (type: String or Symbol, default: nil)::\nThe template engine filter to apply when scanning for Asciidoctor converter templates.\nFor example, to only discover Slim templates, set this to `:slim`.\n\ntemplate_engine_options (type: Hash, default: nil)::\nAdditional options to pass to the template engine when invoking the Asciidoctor converter templates.\nOptions must be indexed by the template engine name (e.g., `:slim`).\n\nTIP: The full set of options can be seen on your preview server's config page at the path [.path]_/__middleman/config/_.\n\nThe following implicit attributes are passed to the AsciiDoc processor prior to the page being converted, making them available to both the AsciiDoc source and extensions:\n\n* outfile - the absolute path of the output (HTML) file\n* outdir - the absolute path of the directory containing the output file\n\nIn addition to the `outdir` attribute, the `:to_dir` option is also passed to the AsciiDoc processor, and subsequently available on the parsed document object.\nThis option may be useful for certain integrations, such as Asciidoctor Diagram.\n\n=== Configuring Specific Pages\n\nYou can pass extra attributes and other options to the AsciiDoc processor for a given page (or set of pages) using the `:renderer_options` option of the `page` directive (where the \"`renderer`\" is the AsciiDoc processor):\n\n[source,ruby]\n----\npage 'manual', renderer_options: {\n  attributes: { 'sectanchors' =\u003e '' }\n}\n----\n\nNOTE: The first argument to the `page` directive is the page ID.\nThe page ID is computed by starting with the path of the source file relative to the source directory, then removing the template extension (i.e., the AsciiDoc extension), then removing the `.html` extension, if present.\nFor example, the page ID for both [.path]_home.adoc_ and [.path]_home.html.adoc_ is `home`.\n\nWARNING: Attributes passed to the page directive must be specified as a Hash and receive no additional processing.\n\nYou can add extra attributes to a page more concisely using the `:attributes` option on the page directive:\n\n[source,ruby]\n----\npage 'manual', attributes: { 'sectanchors' =\u003e '' }\n----\n\nThe `:attributes` option on the page directive takes precedence over the `:attributes` option in `:renderer_options`.\n\n=== Defining Additional Site Attributes\n\nMiddleman doesn't have a predefined schema for site-related data, such as the title, url, and author.\nHowever, since this information is needed for most sites, authors end up defining one themselves.\nThis section describes how to make this site-related information available to your AsciiDoc documents as attributes.\n\nTo maintain consistently with integrations for other site generators, we'll use `site-` as the prefix for site-related attributes.\nFor example, the site title will be named `site-title`.\n\nFirst, we assume you've created a data file named [.path]_site.yml_ in the data directory.\nFor example:\n\n.data/site.yml\n[source,yml]\n----\ntitle: Site Title\nurl: http://example.com\ndescription: An awesome site.\nauthor: Joe Cool\n----\n\nThe information in this file is available via the variable path `app.data.site`.\nThe next step is to convert this information into AsciiDoc attributes.\n\nInside the activate block for the AsciiDoc extension, convert this data into attributes to pass to AsciiDoc, then assign the result to the `attributes` property of the extension.\n\n[source,ruby]\n----\nactivate :asciidoc do |asciidoc|\n  attributes = {}\n  allowed_value_types = [String, Numeric, TrueClass, FalseClass, Date, Time]\n  app.data.site.inject(attributes) do |accum, (k, v)|\n    accum[%(site-#{k})] = v if allowed_value_types.detect {|type| type === v }\n    accum\n  end\n  asciidoc.attributes = attributes\nend\n----\n\nYou can now access these attributes from any AsciiDoc document in the site.\nFor example, to reference the site title, you'd use:\n\n[source,asciidoc]\n----\n{site-title}\n----\n\nIf you want to support nested properties (e.g., `site.blog.title`), you can refactor the code above into a function you can call recursively.\nThe convention is to flatten these paths into attribute names using the hyphen character (e.g., `site-blog-title`).\n\n=== Customizing the Output File Extension\n\nBy default, the extension of an output file created from an AsciiDoc document is `.html`.\nIf you want to customize this extension, for example to change it to `.jsp`, there are two ways to do so.\n\nFirst, you can give the AsciiDoc source document a double file extension, such as `.jsp.adoc`.\nIn this case, the second file extension (`.adoc`) tells Middleman the file is an AsciiDoc file and the first file extension (`.jsp`) tells Middleman which extension to use for the output file.\n\nIf you're working with existing AsciiDoc documents, you may not want to change the file extension from `.adoc`.\nIn this case, you must set the `outfilesuffix` AsciiDoc attribute, either globally:\n\n[source,ruby]\n----\nactivate :asciidoc, attributes: ['outfilesuffix=.jsp']\n----\n\nor per page you want to customize:\n\n[source,ruby]\n----\npage 'manual', attributes: { 'outfilesuffix' =\u003e  '.jsp' }\n----\n\nNote that setting the outfilesuffix has no effect on a file with a double file extension.\nWhen the file has a double file extension, the first extension is always used as the extension for the output file.\n\n== Creating Pages\n\nEach AsciiDoc file in the source directory (except for files that begin with `+_+` or which are located in a directory that begins with `+_+`) becomes a page in the site.\nAsciiDoc files can have the file extension `.adoc` or `.html.adoc`.\nThese extensions are stripped and replaced with the value of the `outfilesuffix` attribute, which defaults to `.html`.\n\nNOTE: For details about how the file extension is substituted, see the discussion in {uri-issues}/7[issue #7].\n\nTo add a page composed in AsciiDoc, simply add an AsciiDoc file that has one of the aforementioned AsciiDoc file extensions to the project source directory.\n\n.sample.adoc\n[source,asciidoc]\n....\n= Sample Page\n:page-layout: page\n:uri-asciidoctor: http://asciidoctor.org\n\nThis is a sample page composed in AsciiDoc.\nThe Middleman AsciiDoc extension converts it to HTML using {uri-asciidoctor}[Asciidoctor].\n\n[source,ruby]\n----\nputs \"Hello, World!\"\n----\n....\n\n=== Adding Custom Page Data\n\nAsciiDoc attributes defined in the document header whose names begin with `page-` are promoted to page data (aka front matter).\nThe part of the name after the `page-` prefix is used as the entry's key (e.g., page-layout becomes layout).\nYou can also set the `:promoted_attributes` option to provide a list of attributes that are always promoted without the `page-` prefix.\nIf the `:promoted_attributes_convert_dashes` option is set to true, dashes in the attribute names are replaced with underscores (e.g., page-a-very-long-name becomes a_very_long_name).\nThe value is parsed as {uri-yaml}[YAML] data (that which can be expressed in a single line).\n\nIn addition to these explicit page attributes and the `:promoted_attributes` option, the following AsciiDoc attributes are also promoted to page data:\n\n* doctitle (i.e., the document title) (becomes title)\n* author (becomes author.name)\n* email (becomes author.email or author.url)\n ** if value matches the pattern `url[@username]`, author.username is also set\n* authors (converted to an Array of Author objects)\n* revdate (becomes date; value is converted to a Time object)\n* keywords (value is kept as a String)\n* description\n\nTIP: You can continue to specify page data using the front matter header.\nKeep in mind that the AsciiDoc `page-` attributes override matching entries in the front matter header.\n\nNOTE: If you specify a time zone in the value of the `revdate` attribute, that time zone is honored.\nOtherwise, the date specified is assumed to have the time zone set for the application.\nYou can define the application time zone in [.path]_config.rb_ using `set :time_zone` (a setting shared with the blog extension).\nIf you don't specify a time zone in the page's date or for the application, dates are assumed to be UTC.\n\n=== Specifying a Layout\n\nThe most important of these page attributes is `page-layout`, which determines the layout that is applied to the page.\nMiddleman will look for the first file that matches this root name under the source directory and use it as the layout.\nFor example, if `page-layout` has the value `page`, Middleman might resolve a layout named [.path]_page.erb_.\nYou can set the extension of the layout file using the `page-layout-engine` attribute.\n\nIf a layout is not specified, or the value of the `page-layout` attribute is empty, the default layout for the site is used.\n\nYou can set a default layout for all pages in [.path]_config.rb_ using:\n\n[source,ruby]\n----\nset :layout, :name_of_layout\n----\n\nAlternately, you can set a default layout just for AsciiDoc-based pages (pages processed by this extension) in [.path]_config.rb_ using:\n\n[source,ruby]\n----\nactivate :asciidoc, layout: :name_of_layout\n----\n\nFinally, you can set the layout for a specific page or group of pages using the `page` directive.\nThis is an alternate way to define front matter for a page.\n\n[source,ruby]\n----\npage 'home', layout: :name_of_layout\n----\n\nTIP: When you define the layout in [.path]_config.rb_, you can specify the value either as a String or a Symbol.\n\nIf you don't set the layout in [.path]_config.rb_, the default layout is considered unset.\n(The one exception to this rule is the layout for blog articles, which is controlled by the configuration for the blog extension).\n\nAsciiDoc-based pages are configured to use the automatic layout by default (i.e., the `page-layout` attribute is set to blank).\nIf you unset the `page-layout` attribute, the AsciiDoc processor will handle generating a standalone document (`header_footer: true`).\nIn this case, the page will appear like an HTML file that is generated by the AsciiDoc processor directly.\n\nHere are the different ways to specify a layout:\n\n* `:page-layout:`, `:page-layout: _auto_layout`, or _not specified_ -- use the automatic layout (default: layout)\n* `:page-layout: custom` -- use the page layout named \"`custom`\" (e.g., [.path]_custom.erb_)\n* `:!page-layout:` or `:page-layout: false` -- generate a standalone HTML document\n* `:page-layout: ~` or `:page-layout: null` -- generate a page without a layout (don't wrap content in a layout)\n\n.Layout for blog posts\nWARNING: If you're using the Middleman Blog extension to write blog posts, the `layout` property on the blog configuration overrides the default layout, but you can still override that setting using the `page-layout` attribute in each post.\n\n==== Accessing the AsciiDoc Configuration From a Layout\n\nYou can access the global configuration for the AsciiDoc extension from a layout template using the variable path `app.config.asciidoc` (Hash).\n\nFor example, let's say you want to reference the location stored in the `imagesoutdir` attribute.\nYou can do so in an ERB template using:\n\n----\n\u003c%= app.config.asciidoc[:attributes]['imagesoutdir'] %\u003e\n----\n\nOther processor options, such as `:safe`, are available from the `app.config.asciidoc` variable path.\n\nIf you want to access the options passed to the AsciiDoc processor for the current page, use the variable path `current_page.options[:renderer_options]` (Hash) instead.\n\nFor example, let's say you want to access the resolved base directory for the current page.\nYou can do so in an ERB template using:\n\n----\n\u003c%= current_page.options[:renderer_options][:base_dir] %\u003e\n----\n\nOther processor options, such as `:attributes`, are available from the `current_page.options[:renderer_options]` variable path.\n\n==== Accessing the AsciiDoc Document From a Layout\n\nYou can access the document model for the current AsciiDoc-based page from the page layout as follows:\n\n----\n\u003c%= current_page.data.document %\u003e\n----\n\nThis object is an instance of `Asciidoctor::Document`.\nIt can be used, for instance, to output a table of contents for the current page:\n\n----\n\u003c% if (doc = current_page.data.document) %\u003e\n\u003c%= doc.converter.convert doc, 'outline', toclevels: 3 %\u003e\n\u003c% end %\u003e\n----\n\nFor more information about this API, refer to the http://www.rubydoc.info/gems/asciidoctor/Asciidoctor/Document[API documentation].\n\n=== Ignoring a Page\n\nIn addition to the normal ignore filter in Middleman, you can also control whether a page is ignored from AsciiDoc.\nTo mark a page as ignored from AsciiDoc, set the `page-ignored` attribute in the AsciiDoc document header to any value other than `false`, as follows:\n\n[source,asciidoc]\n----\n= Ignored Page\n:page-ignored:\n----\n\nOnce this page attribute is detected, no further processing is performed on the document by this extension.\n\n=== Marking an Article as a Draft\n\nIf you're using the Middleman Blog extension, you can mark an article as a draft so it does not get published.\nTo do so, assign the value `false` the page attribute named `page-published` in the AsciiDoc document header, as follows:\n\n[source,asciidoc]\n----\n= Draft Article\n:page-published: false\n----\n\nThis effectively sets the `published` key in the page data to `false`.\nRecall that the AsciiDoc extension converts the value of page attributes as a YAML value, which means the string literal \"`false`\" becomes the boolean value `false`.\nMiddleman then knows not to publish this article.\n\nAnother option is to set the date of the article way into the future.\n\n[source,asciidoc]\n----\n= Future Post\nAuthor Name\n3001-01-01\n----\n\nBy default, the blog extension does not publish articles with a future date.\n\n=== Linking Between Pages\n\nYou can link from one page to another using an {uri-asciidoctor}/docs/user-manual/#inter-document-cross-references[inter-document xref].\nLet's say you have the following two pages in the source directory:\n\n* about.adoc\n* team.adoc\n\nYou can link from the about page to the team page using the following:\n\n[source,asciidoc]\n----\nMeet our \u003c\u003cteam.adoc#,team\u003e\u003e.\n----\n\nThe `.adoc#` suffix indicates the xref targets another page.\nThe target is the path from the current page to the other page (a source-to-source reference).\nThis reference is then converted to the following HTML:\n\n[source,html]\n----\nMeet our \u003ca href=\"team.html\"\u003eteam\u003c/a\u003e.\n----\n\nOf course, we're assuming there that the input maps 1-to-1 to the output.\nThat assumption breaks down as soon as you enable directory indexes.\n\nWhen directory indexes are enabled, each page is moved into its own folder and renamed to index.html.\nSo how does the xref work in that case?\n\nThis extension provides built-in support for directory indexes.\nWhen the directory indexes extension is enabled, this extension automatically defines the `relfileprefix` and `relfilesuffix` attributes on the AsciiDoc document.\nThe `relfilesuffix` attribute honors both the `:trailing_slash` and `:strip_index_file` options in Middleman.\nHere's the result of the xref macro when directory indexes are enabled.\n\n[source,html]\n----\nMeet our \u003ca href=\"../team/\"\u003eteam\u003c/a\u003e.\n----\n\n.Using the interdoc xref macro with directory indexes on Asciidoctor \u003c 1.5.7\n****\nIf you're using Asciidoctor \u003c 1.5.7, you have to make one additional change to your pages to get the `relfilesuffix` to influence the output of the interdoc xref macro.\n\nBelow the document header (but *not in* the document header), you must assign the `outfilesuffix` attribute to the value of the `relfilesuffix` attribute.\nHere's an example:\n\n[source,asciidoc]\n----\n= About Us\n\n// ^ the previous blank line is required!\n\\ifdef::relfilesuffix[:outfilesuffix: {relfilesuffix}]\n\n...\n\nMeet our \u003c\u003cteam.adoc#,team\u003e\u003e.\n----\n\nWith the help of the `outfilesuffix` assignment, Asciidoctor \u003c 1.5.7 will automatically produce the correct link to the other page when using directory indexes.\n****\n\nOptionally, you can construct the link manually using:\n\n[source,asciidoc]\n----\nMeet our link:{relfileprefix}team{relfilesuffix}[team].\n----\n\nI think you'll agree that using the xref macro is simpler.\n\n=== Controlling the Destination Path\n\nBy default, Middleman does not support controlling the destination path from the page data, often called a permalink.\nHowever, with the addition of a simple extension, it's possible to enable this feature.\n\nStart by adding the following Ruby code to the file [.path]_lib/permalink.rb_.\n\n.lib/permalink.rb\n[source,ruby]\n----\nclass Permalink \u003c Middleman::Extension\n  # Run after front matter extension (priority: 20), after the AsciiDoc extension (priority: 30),\n  # and before other third-party extensions (priority: 50).\n  self.resource_list_manipulator_priority = 35\n\n  def manipulate_resource_list resources\n    resources.each do |resource|\n      if !resource.ignored? \u0026\u0026 (resource.respond_to? :data) \u0026\u0026 (permalink = resource.data.permalink)\n        permalink = permalink.slice 1, permalink.length if permalink.start_with? '/'\n        resource.destination_path = %(#{permalink}#{resource.ext})\n      end\n    end\n  end\nend\n\nMiddleman::Extensions.register :permalink, Permalink\n----\n\nNext, require and activate this extension in the [.path]_config.rb_ file for your site:\n\n[source,ruby]\n----\nrequire_relative 'lib/permalink'\nactivate :permalink\n----\n\nYou can now customize the destination path for any AsciiDoc-based page by adding the following attribute entry to the document header:\n\n[source,asciidoc]\n----\n:page-permalink: custom-destination-path\n----\n\nCustomize the destination path to your liking.\nThe leading forward slash (`/`) is optional.\n\n== Building Your Site\n\nYou can now build your site using:\n\n $ middleman build\n\nor preview it using:\n\n $ middleman serve\n\nIf you're using Bundler, use the following commands instead:\n\n $ bundle exec middleman build\n $ bundle exec middleman serve\n\n== Customizing the HTML\n\nYou can use templates to customize the HTML Asciidoctor generates for the pages in your site.\nEach template file corresponds to a node in the AsciiDoc document tree (aka AST).\nTemplate files can be composed in any templating language supported by {uri-tilt}[Tilt].\n\nFollow the steps below to configure Asciidoctor to use custom templates when converting AsciiDoc documents to HTML.\n\n=== Step {counter:step}: Add Required Gems\n\nYou'll first need to add the *thread_safe* gem to your [.path]_Gemfile_.\nIf you plan to use a template language other than ERB (.erb) or InterpolatedString (.str), you'll also need to add the dependency for the template language.\nWe've decided to use Slim for this example, so we need to also add the *slim* gem.\n\n[source,ruby]\n----\ngem 'slim', '~\u003e 3.0.9'\ngem 'thread_safe', '~\u003e 0.3.6'\n----\n\n=== Step {counter:step}: Install New Gems\n\nNow run the `bundle` command to install the new gems.\n\n $ bundle\n\n=== Step {counter:step}: Create a Templates Folder\n\nNext, create a new folder in your site named [.path]_asciidoc_templates_ to store your templates for AsciiDoc.\n\n $ mkdir asciidoc_templates\n\nWe don't put this folder under the [.path]_source_ directory since we don't need Middleman monitoring it.\n//We prefix the folder name with an underscore so it doesn't get included in the sitemap (i.e., Middleman won't look for pages in this folder).\n\n=== Step {counter:step}: Configure Asciidoctor to Load Templates\n\nIn your site's [.path]_config.rb_ file, configure Asciidoctor to load the templates by setting the `:template_dirs` option (and optionally the `:template_engine` option) when activating the extension:\n\n[source,ruby]\n----\nactivate :asciidoc, template_dirs: 'asciidoc_templates', template_engine: :slim\n----\n\n=== Step {counter:step}: Compose a Template\n\nThe final step is to compose a template.\nWe'll be customizing the unordered list node.\nAdd a file named [.path]_ulist.html.slim_ to the [.path]_asciidoc_templates_ directory.\nPopulate the file with the following contents:\n\n.asciidoc_templates/ulist.html.slim\n[source,slim]\n----\n- if title?\n  figure.list.unordered id=id\n    figcaption=title\n    ul class=[style, role]\n      - items.each do |_item|\n        li\n          span.primary=_item.text\n          - if _item.blocks?\n            =_item.content\n- else\n  ul id=id class=[style, role]\n    - items.each do |_item|\n      li\n        span.primary=_item.text\n        - if _item.blocks?\n          =_item.content\n----\n\nThe next time you build your site, Asciidoctor will use your custom template to generate HTML for all unordered lists converted from AsciiDoc.\n\n== Using Asciidoctor Diagram\n\nYou can use {uri-asciidoctor-diagram}[Asciidoctor Diagram] (gem: *asciidoctor-diagram*) to generate diagrams from plain text defined in specially marked literal blocks.\nFollow the steps below to enable Asciidoctor Diagram in your Middleman site.\n\n=== Step {counter:diagram-step}: Add the Asciidoctor Diagram Gem\n\nYou'll first need to add the *asciidoctor-diagram* gem to your [.path]_Gemfile_.\n\n[source,ruby]\n----\ngem 'asciidoctor-diagram'\n----\n\nIf you plan to make diagrams that rely on external commands, such as graphviz (dot), you may need to install additional external applications.\nConsult the {uri-asciidoctor-diagram}#specifying-diagram-generator-paths[Asciidoctor Diagram docs] for further instructions.\n\n=== Step {counter:diagram-step}: Install New Gems\n\nNow run the `bundle` command to install the gem.\n\n $ bundle\n\n=== Step {counter:diagram-step}: Switch Asciidoctor to Unsafe Mode\n\nThis step is very important.\nYou must change Asciidoctor to unsafe mode.\nDon't worry, it's not that unsafe.\nIt just means that Asciidoctor Diagram will be able to write the generated image to a parent directory of the source file.\n\n[source,ruby]\n----\nactivate :asciidoc, safe: :unsafe\n----\n\n=== Step {counter:diagram-step}: Skip Build Clean\n\nTo prevent Middleman from removing the generated images when you run the `build` command, you need to add the following function to [.path]_config.rb_.\n\n[source,ruby]\n----\nset :skip_build_clean, proc {|f| f.start_with? 'build/images/' }\n----\n\nThis step is necessary since the generated images don't get registered with the sitemap.\nAs a result, Middleman inconveniently wants to remove them for you.\n\n=== Step {counter:diagram-step}: Start Making Diagrams\n\nAt this point, you're all set to start making diagrams!\nJust create an AsciiDoc page in the source folder and populate it with the following contents:\n\n[source,html]\n----\n= Diagrams FTW!\n\nHere's a document symbol generated by ditaa.\n\n[ditaa,document,png]\n....\n+----+\n|{d} |\n|    |\n+----+\n....\n----\n\nThe next time you generate the site, Asciidoctor Diagram replaces the literal block that has the style `ditaa` with a generated diagram.\nThe diagram image ends up in the images folder under the build folder (build/images/document.png).\nThe corresponding `\u003cimg\u003e` element in the HTML refers to this image using a root-relative path (/images/document.png).\nAsciidoctor Diagram caches information about the image under the [.path]_.asciidoctor/diagram_ folder relative to the project root (MM_ROOT).\nThis folder is safe to delete.\n\n=== Limitations\n\nThere are limitations with using Asciidoctor Diagram with Middleman.\nSince Asciidoctor Diagram generates the images during AsciiDoc conversion, Middleman doesn't know about these resources (since they don't get registered in Middleman's sitemap).\nAs a result, there are two things you must be aware of:\n\n* Diagrams won't be shown when using the preview server (server)\n* Middleman will try to purge the generated images when building the site (build)\n\nTo prevent Middleman from purging the diagrams, you need to add the \"`skip build clean`\" function mentioned above.\n\n== Community\n\nThe official community forum for Middleman can be found at {uri-middleman-forum}.\nFor questions related to this extension or general questions about AsciiDoc, please post to the Asciidoctor discussion list at {uri-asciidoctor-discuss}.\n\n== Bug Reports\n\nGithub Issues are used for managing bug reports and feature requests.\nIf you run into issues, please search the issues and submit new problems in the project's {uri-issues}[issue tracker].\n\nThe best way to get quick responses to your issues and swift fixes to your bugs is to submit detailed bug reports, include test cases and respond to developer questions in a timely manner.\nEven better, if you know Ruby, you can submit {uri-help-pr}[pull requests] containing Cucumber Features which describe how your feature should work or exploit the bug you are submitting.\n\n== How to Run Tests\n\nThe tests are based on Cucumber.\nHere's how to clone the project and run the tests.\n\n. Clone the repository:\n+\n[subs=attributes+]\n $ git clone {uri-repo} \u0026\u0026\n   cd \"`basename $_`\"\n\n. Install Bundler (if not already installed):\n\n $ gem install bundler\n\n. Run Bundler (from the project root) to install the gem dependencies:\n\n $ bundle\n\n. Run test cases (based on Cucumber) using Rake:\n\n $ bundle exec rake cucumber\n\n== Copyright\n\nCopyright (C) 2014-2018 Dan Allen and the Asciidoctor Project.\nFree use of this software is granted under the terms of the MIT License.\nFor the full text of the license, see the \u003c\u003cLICENSE.adoc#,LICENSE\u003e\u003e file.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmiddleman%2Fmiddleman-asciidoc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmiddleman%2Fmiddleman-asciidoc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmiddleman%2Fmiddleman-asciidoc/lists"}