Extensions of useful macros for software documentation

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Extensions of useful macros for software documentation

mariocup
Dear Asciidoctor community,

I am using Asciidoc to write documentation for software and I tried to write some macros to cover the following requirements.

opt::[] to format a string as option e.g. used to describe command line tools
var::[] format a variable as parameter by adding <parameter>
file::[] format a string in the text as file e.g. to mention a header file etc.

optentry: a list environment (role=optentry) which renders the list entry as option.

fcntenry: create a list environment (role=fcnentry) which renders the list entry with rouge syntax highlighting.

I consider this functionality also useful for other users and I would be more than happy if the functionality could be added to the extension lab after review and maintained by the community.

I collected my extensions in a file (can be passed by Asciidoctor option e.g. -r myextensions.rb).

```
RUBY_ENGINE == 'opal' ? (require 'variable-preprocessor/extension') : (require_relative 'variable-preprocessor/extension')
RUBY_ENGINE == 'opal' ? (require 'opt-preprocessor/extension') : (require_relative 'opt-preprocessor/extension')
RUBY_ENGINE == 'opal' ? (require 'file-preprocessor/extension') : (require_relative 'file-preprocessor/extension')
RUBY_ENGINE == 'opal' ? (require 'optentry-treeprocessor/extension') : (require_relative 'optentry-treeprocessor/extension')
RUBY_ENGINE == 'opal' ? (require 'fcnentry-treeprocessor/extension') : (require_relative 'fcnentry-treeprocessor/extension')


Extensions.register do
#  preprocessor  GitMetadataPreprocessor
  preprocessor  VariablePreprocessor
  preprocessor  FilePreprocessor
  preprocessor  OptPreprocessor
  treeprocessor OptEntryTreeProcessor
  treeprocessor FcnEntryTreeProcessor
end
```

The code looks like

# fcnentry

```
require 'asciidoctor/extensions' unless RUBY_ENGINE == 'opal'
require 'asciidoctor-pdf'
require 'asciidoctor-pdf/rouge_ext'

include Asciidoctor

module RawTerm
  def text
    @text
  end

  def text= text
    @text = text
  end
end

class FcnEntryTreeProcessor < Extensions::Treeprocessor
  def process doc
    (doc.find_by context: :dlist, role: 'fcnentry').each do |dlist|
      dlist.items.each do |dlist_entry|
        terms, description = dlist_entry
        term_0 = terms[0]
        term_0.extend RawTerm
        lexer = Rouge::Lexer.find 'c'
        formatter = if doc.backend == "html5"
          Rouge::Formatters::HTML.new(Rouge::Theme.find(doc.attr('rouge-style', 'github')).new)
        else
          Rouge::Formatters::HTMLInline.new(Rouge::Theme.find(doc.attr('rouge-style', 'github')).new)
        end
        newText = formatter.format(lexer.lex(term_0.text))
        term_0.text = newText
      end
    end
  end
end
````

# opentry

```
require 'asciidoctor/extensions' unless RUBY_ENGINE == 'opal'

include Asciidoctor

def convert_to_opt block
    newText = "`" << block.text << "`"
    ListItem.new(block.parent, newText)
  end

class OptEntryTreeProcessor < Extensions::Treeprocessor
  def process doc
    (doc.find_by context: :dlist, role: 'optentry').each do |dlist|
      dlist.items.each.with_index do |dlist_entry, index|
        #puts dlist_entry.inspect, index
        terms, description = dlist_entry
        terms[0] = convert_to_opt terms[0]
      end
    end
  end
end
```

# variable

```
require 'asciidoctor/extensions' unless RUBY_ENGINE == 'opal'

include ::Asciidoctor

class VariablePreprocessor < Extensions::Preprocessor
  def process document, reader
    lines = []
    while reader.has_more_lines?
      lines << reader.read_line
    end
    lines.map do |line|
      while ((startIndex = line.index("var::")))
        if match = /(\w*-*(<\w*\s*\w*>)*)*/.match(line[(startIndex + 5)..-1])[0]
          line.insert(startIndex + 5 + match.length, ">")
          line[startIndex..startIndex+4] = "<"
        end
      end
    end
    Asciidoctor::Reader.new lines
  end
end
```

# opt

```
require 'asciidoctor/extensions' unless RUBY_ENGINE == 'opal'

include ::Asciidoctor

class OptPreprocessor < Extensions::Preprocessor
  def process document, reader
    lines = []
    while reader.has_more_lines?
      lines << reader.read_line
    end
    lines.map do |line|
      while ((startIndex = line.index("opt::")))
        if match = /(\w*-*(<\w*\s*\w*>)*)*/.match(line[(startIndex + 5)..-1])[0]
          line.insert(startIndex + 5 + match.length, "`")
          line[startIndex..startIndex+4] = "`-"
        end
      end
    end
    Asciidoctor::Reader.new lines
  end
end
```

# file

```
require 'asciidoctor/extensions' unless RUBY_ENGINE == 'opal'

include ::Asciidoctor

class FilePreprocessor < Extensions::Preprocessor
  def process document, reader
    lines = []
    while reader.has_more_lines?
      lines << reader.read_line
    end
    lines.map do |line|
      while ((startIndex = line.index("file::")))
        if match = /([[:punct:]]|\w)*\.\w+/.match(line[(startIndex + 6)..-1])[0]
          line.insert(startIndex + 6 + match.length, "`")
          line[startIndex..startIndex+5] = "`"
        end
      end
    end
    Asciidoctor::Reader.new lines
  end
end
```

Any feedback is welcome.