#!/usr/bin/env ruby # This script is written intended as a living, evolving tooling # to fix oopsies within the docbook documentation. # # This is *not* a formatter. It, instead, handles some known cases # where something bad happened, and fixing it manually is tedious. # # Read the code to see the different cases it handles. # # ALWAYS `make format` after fixing with this! # ALWAYS read the changes, this tool isn't yet proven to be always right. require "rexml/document" include REXML if ARGV.length < 1 then $stderr.puts "Needs a filename." exit 1 end filename = ARGV.shift doc = Document.new(File.open(filename)) $touched = false # Fixing varnames having a sibling element without spacing. # This is to fix an initial `xmlformat` issue where `term` # would mangle as spaces. # # <varlistentry> # <term><varname>types.separatedString</varname><replaceable>sep</replaceable> <---- # </term> # ... # # Generates: types.separatedStringsep # ^^^^ # # <varlistentry xml:id='fun-makeWrapper'> # <term> # <function>makeWrapper</function><replaceable>executable</replaceable><replaceable>wrapperfile</replaceable><replaceable>args</replaceable> <---- # </term> # # Generates: makeWrapperexecutablewrapperfileargs # ^^^^ ^^^^ ^^ ^^ # # <term> # <option>--option</option><replaceable>name</replaceable><replaceable>value</replaceable> <----- # </term> # # Generates: --optionnamevalue # ^^ ^^ doc.elements.each("//varlistentry/term") do |term| ["varname", "function", "option", "replaceable"].each do |prev_name| term.elements.each(prev_name) do |el| if el.next_element and el.next_element.name == "replaceable" and el.next_sibling_node.class == Element then $touched = true term.insert_after(el, Text.new(" ")) end end end end # <cmdsynopsis> # <command>nixos-option</command> # <arg> # <option>-I</option><replaceable>path</replaceable> <------ # </arg> # # Generates: -Ipath # ^^ doc.elements.each("//cmdsynopsis/arg") do |term| ["option", "replaceable"].each do |prev_name| term.elements.each(prev_name) do |el| if el.next_element and el.next_element.name == "replaceable" and el.next_sibling_node.class == Element then $touched = true term.insert_after(el, Text.new(" ")) end end end end # <cmdsynopsis> # <arg> # <group choice='req'> # <arg choice='plain'> # <option>--profile-name</option> # </arg> # # <arg choice='plain'> # <option>-p</option> # </arg> # </group><replaceable>name</replaceable> <---- # </arg> # # Generates: [{--profile-name | -p }name] # ^^^^ doc.elements.each("//cmdsynopsis/arg") do |term| ["group"].each do |prev_name| term.elements.each(prev_name) do |el| if el.next_element and el.next_element.name == "replaceable" and el.next_sibling_node.class == Element then $touched = true term.insert_after(el, Text.new(" ")) end end end end if $touched then doc.context[:attribute_quote] = :quote doc.write(output: File.open(filename, "w")) end