docbook 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (271) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +5 -0
  3. data/CLAUDE.md +19 -0
  4. data/CODE_OF_CONDUCT.md +10 -0
  5. data/README.adoc +335 -0
  6. data/Rakefile +12 -0
  7. data/docs/.lycheeignore +33 -0
  8. data/docs/Gemfile +10 -0
  9. data/docs/INDEX.adoc +67 -0
  10. data/docs/_config.yml +186 -0
  11. data/docs/advanced/element-classes.adoc +185 -0
  12. data/docs/advanced/frontend-customization.adoc +193 -0
  13. data/docs/advanced/index.adoc +14 -0
  14. data/docs/advanced/templates.adoc +123 -0
  15. data/docs/features/element-coverage.adoc +373 -0
  16. data/docs/features/html-output/data-model.adoc +285 -0
  17. data/docs/features/html-output/directory-mode.adoc +180 -0
  18. data/docs/features/html-output/index.adoc +90 -0
  19. data/docs/features/html-output/single-file-mode.adoc +125 -0
  20. data/docs/features/index-generation.adoc +197 -0
  21. data/docs/features/index.adoc +63 -0
  22. data/docs/features/numbering.adoc +183 -0
  23. data/docs/features/toc-generation.adoc +150 -0
  24. data/docs/features/xinclude/fragid-schemes.adoc +287 -0
  25. data/docs/features/xinclude/index.adoc +119 -0
  26. data/docs/features/xinclude/text-includes.adoc +123 -0
  27. data/docs/features/xinclude/xml-includes.adoc +167 -0
  28. data/docs/getting-started/index.adoc +50 -0
  29. data/docs/getting-started/installation.adoc +113 -0
  30. data/docs/getting-started/quick-start.adoc +161 -0
  31. data/docs/guides/converting-article.adoc +188 -0
  32. data/docs/guides/converting-book.adoc +192 -0
  33. data/docs/guides/index.adoc +12 -0
  34. data/docs/guides/roundtrip-testing.adoc +129 -0
  35. data/docs/interfaces/cli/format-command.adoc +109 -0
  36. data/docs/interfaces/cli/index.adoc +73 -0
  37. data/docs/interfaces/cli/roundtrip-command.adoc +125 -0
  38. data/docs/interfaces/cli/to-html-command.adoc +178 -0
  39. data/docs/interfaces/cli/validate-command.adoc +104 -0
  40. data/docs/interfaces/index.adoc +101 -0
  41. data/docs/interfaces/ruby-api/html-output.adoc +186 -0
  42. data/docs/interfaces/ruby-api/index.adoc +111 -0
  43. data/docs/interfaces/ruby-api/parsing.adoc +202 -0
  44. data/docs/interfaces/ruby-api/xinclude.adoc +162 -0
  45. data/docs/interfaces/ruby-api/xref-resolution.adoc +156 -0
  46. data/docs/lychee.toml +42 -0
  47. data/docs/reference/cli-options.adoc +155 -0
  48. data/docs/reference/content-block-types.adoc +243 -0
  49. data/docs/reference/glossary.adoc +119 -0
  50. data/docs/reference/index.adoc +12 -0
  51. data/docs/reference/supported-elements.adoc +749 -0
  52. data/docs/understanding/architecture.adoc +145 -0
  53. data/docs/understanding/content-pipeline.adoc +102 -0
  54. data/docs/understanding/data-models.adoc +156 -0
  55. data/docs/understanding/index.adoc +34 -0
  56. data/exe/docbook +7 -0
  57. data/frontend/dist/app.css +1 -0
  58. data/frontend/dist/app.iife.js +24 -0
  59. data/frontend/package-lock.json +1445 -0
  60. data/frontend/package.json +22 -0
  61. data/frontend/src/App.vue +230 -0
  62. data/frontend/src/app.ts +8 -0
  63. data/frontend/src/components/AppSidebar.vue +116 -0
  64. data/frontend/src/components/AppendixSection.vue +39 -0
  65. data/frontend/src/components/BlockRenderer.vue +358 -0
  66. data/frontend/src/components/ChapterSection.vue +32 -0
  67. data/frontend/src/components/ContentRenderer.vue +13 -0
  68. data/frontend/src/components/EbookContainer.vue +147 -0
  69. data/frontend/src/components/EbookTopBar.vue +116 -0
  70. data/frontend/src/components/PartSection.vue +44 -0
  71. data/frontend/src/components/ReferenceEntry.vue +80 -0
  72. data/frontend/src/components/SearchModal.vue +286 -0
  73. data/frontend/src/components/SectionContent.vue +31 -0
  74. data/frontend/src/components/SettingsPanel.vue +236 -0
  75. data/frontend/src/components/TocTreeItem.vue +135 -0
  76. data/frontend/src/composables/useEbookStore.ts +191 -0
  77. data/frontend/src/composables/useSearch.ts +249 -0
  78. data/frontend/src/env.d.ts +7 -0
  79. data/frontend/src/stores/documentStore.ts +221 -0
  80. data/frontend/src/stores/uiStore.ts +98 -0
  81. data/frontend/src/styles.css +253 -0
  82. data/frontend/tsconfig.json +24 -0
  83. data/frontend/tsconfig.node.json +11 -0
  84. data/frontend/vite.config.ts +30 -0
  85. data/lib/docbook/cli.rb +123 -0
  86. data/lib/docbook/document.rb +67 -0
  87. data/lib/docbook/elements/abbrev.rb +16 -0
  88. data/lib/docbook/elements/acknowledgements.rb +22 -0
  89. data/lib/docbook/elements/address.rb +18 -0
  90. data/lib/docbook/elements/alt.rb +16 -0
  91. data/lib/docbook/elements/annotation.rb +18 -0
  92. data/lib/docbook/elements/appendix.rb +34 -0
  93. data/lib/docbook/elements/article.rb +31 -0
  94. data/lib/docbook/elements/att.rb +15 -0
  95. data/lib/docbook/elements/attribution.rb +20 -0
  96. data/lib/docbook/elements/audioobject.rb +18 -0
  97. data/lib/docbook/elements/author.rb +18 -0
  98. data/lib/docbook/elements/bibliography.rb +24 -0
  99. data/lib/docbook/elements/bibliomixed.rb +40 -0
  100. data/lib/docbook/elements/biblioref.rb +20 -0
  101. data/lib/docbook/elements/blockquote.rb +26 -0
  102. data/lib/docbook/elements/book.rb +36 -0
  103. data/lib/docbook/elements/buildtarget.rb +16 -0
  104. data/lib/docbook/elements/callout.rb +22 -0
  105. data/lib/docbook/elements/calloutlist.rb +22 -0
  106. data/lib/docbook/elements/caution.rb +30 -0
  107. data/lib/docbook/elements/chapter.rb +62 -0
  108. data/lib/docbook/elements/citation.rb +16 -0
  109. data/lib/docbook/elements/citerefentry.rb +26 -0
  110. data/lib/docbook/elements/citetitle.rb +20 -0
  111. data/lib/docbook/elements/classname.rb +16 -0
  112. data/lib/docbook/elements/code.rb +16 -0
  113. data/lib/docbook/elements/colophon.rb +22 -0
  114. data/lib/docbook/elements/computeroutput.rb +18 -0
  115. data/lib/docbook/elements/copyright.rb +17 -0
  116. data/lib/docbook/elements/danger.rb +28 -0
  117. data/lib/docbook/elements/date.rb +16 -0
  118. data/lib/docbook/elements/dedication.rb +22 -0
  119. data/lib/docbook/elements/dir.rb +16 -0
  120. data/lib/docbook/elements/emphasis.rb +18 -0
  121. data/lib/docbook/elements/entry.rb +30 -0
  122. data/lib/docbook/elements/entrytbl.rb +22 -0
  123. data/lib/docbook/elements/equation.rb +26 -0
  124. data/lib/docbook/elements/example.rb +30 -0
  125. data/lib/docbook/elements/fieldsynopsis.rb +21 -0
  126. data/lib/docbook/elements/figure.rb +28 -0
  127. data/lib/docbook/elements/filename.rb +16 -0
  128. data/lib/docbook/elements/firstname.rb +16 -0
  129. data/lib/docbook/elements/firstterm.rb +18 -0
  130. data/lib/docbook/elements/footnote.rb +22 -0
  131. data/lib/docbook/elements/footnoteref.rb +21 -0
  132. data/lib/docbook/elements/foreignphrase.rb +18 -0
  133. data/lib/docbook/elements/formalpara.rb +20 -0
  134. data/lib/docbook/elements/function.rb +16 -0
  135. data/lib/docbook/elements/glossary.rb +24 -0
  136. data/lib/docbook/elements/glossdef.rb +18 -0
  137. data/lib/docbook/elements/glossentry.rb +26 -0
  138. data/lib/docbook/elements/glosssee.rb +18 -0
  139. data/lib/docbook/elements/glossseealso.rb +18 -0
  140. data/lib/docbook/elements/glossterm.rb +18 -0
  141. data/lib/docbook/elements/holder.rb +16 -0
  142. data/lib/docbook/elements/honorific.rb +16 -0
  143. data/lib/docbook/elements/imagedata.rb +29 -0
  144. data/lib/docbook/elements/imageobject.rb +22 -0
  145. data/lib/docbook/elements/important.rb +30 -0
  146. data/lib/docbook/elements/index.rb +26 -0
  147. data/lib/docbook/elements/indexdiv.rb +22 -0
  148. data/lib/docbook/elements/indexentry.rb +22 -0
  149. data/lib/docbook/elements/indexterm.rb +34 -0
  150. data/lib/docbook/elements/info.rb +25 -0
  151. data/lib/docbook/elements/informalexample.rb +24 -0
  152. data/lib/docbook/elements/informalfigure.rb +20 -0
  153. data/lib/docbook/elements/inlinemediaobject.rb +22 -0
  154. data/lib/docbook/elements/itemizedlist.rb +21 -0
  155. data/lib/docbook/elements/legalnotice.rb +22 -0
  156. data/lib/docbook/elements/link.rb +26 -0
  157. data/lib/docbook/elements/listitem.rb +32 -0
  158. data/lib/docbook/elements/literal.rb +16 -0
  159. data/lib/docbook/elements/literallayout.rb +22 -0
  160. data/lib/docbook/elements/mediaobject.rb +26 -0
  161. data/lib/docbook/elements/msg.rb +20 -0
  162. data/lib/docbook/elements/msgexplan.rb +22 -0
  163. data/lib/docbook/elements/msgset.rb +22 -0
  164. data/lib/docbook/elements/note.rb +30 -0
  165. data/lib/docbook/elements/orderedlist.rb +23 -0
  166. data/lib/docbook/elements/orgname.rb +16 -0
  167. data/lib/docbook/elements/para.rb +61 -0
  168. data/lib/docbook/elements/paragraph_like.rb +18 -0
  169. data/lib/docbook/elements/parameter.rb +16 -0
  170. data/lib/docbook/elements/part.rb +38 -0
  171. data/lib/docbook/elements/personname.rb +22 -0
  172. data/lib/docbook/elements/phrase.rb +20 -0
  173. data/lib/docbook/elements/preface.rb +58 -0
  174. data/lib/docbook/elements/primary.rb +16 -0
  175. data/lib/docbook/elements/procedure.rb +24 -0
  176. data/lib/docbook/elements/productname.rb +18 -0
  177. data/lib/docbook/elements/productnumber.rb +16 -0
  178. data/lib/docbook/elements/programlisting.rb +28 -0
  179. data/lib/docbook/elements/property.rb +16 -0
  180. data/lib/docbook/elements/pubdate.rb +16 -0
  181. data/lib/docbook/elements/publishername.rb +16 -0
  182. data/lib/docbook/elements/quotation.rb +24 -0
  183. data/lib/docbook/elements/quote.rb +18 -0
  184. data/lib/docbook/elements/refentry.rb +32 -0
  185. data/lib/docbook/elements/refentrytitle.rb +16 -0
  186. data/lib/docbook/elements/reference.rb +26 -0
  187. data/lib/docbook/elements/refmeta.rb +29 -0
  188. data/lib/docbook/elements/refmiscinfo.rb +16 -0
  189. data/lib/docbook/elements/refname.rb +16 -0
  190. data/lib/docbook/elements/refnamediv.rb +22 -0
  191. data/lib/docbook/elements/refpurpose.rb +16 -0
  192. data/lib/docbook/elements/refsect1.rb +22 -0
  193. data/lib/docbook/elements/refsect2.rb +22 -0
  194. data/lib/docbook/elements/refsect3.rb +22 -0
  195. data/lib/docbook/elements/refsection.rb +32 -0
  196. data/lib/docbook/elements/releaseinfo.rb +16 -0
  197. data/lib/docbook/elements/remark.rb +20 -0
  198. data/lib/docbook/elements/replaceable.rb +16 -0
  199. data/lib/docbook/elements/row.rb +15 -0
  200. data/lib/docbook/elements/screen.rb +28 -0
  201. data/lib/docbook/elements/secondary.rb +16 -0
  202. data/lib/docbook/elements/sect1.rb +26 -0
  203. data/lib/docbook/elements/sect2.rb +24 -0
  204. data/lib/docbook/elements/sect3.rb +24 -0
  205. data/lib/docbook/elements/sect4.rb +24 -0
  206. data/lib/docbook/elements/sect5.rb +22 -0
  207. data/lib/docbook/elements/section.rb +66 -0
  208. data/lib/docbook/elements/see.rb +16 -0
  209. data/lib/docbook/elements/seealso.rb +18 -0
  210. data/lib/docbook/elements/set.rb +26 -0
  211. data/lib/docbook/elements/setindex.rb +24 -0
  212. data/lib/docbook/elements/sidebar.rb +22 -0
  213. data/lib/docbook/elements/simplesect.rb +32 -0
  214. data/lib/docbook/elements/step.rb +26 -0
  215. data/lib/docbook/elements/substeps.rb +18 -0
  216. data/lib/docbook/elements/subtitle.rb +16 -0
  217. data/lib/docbook/elements/surname.rb +16 -0
  218. data/lib/docbook/elements/table.rb +24 -0
  219. data/lib/docbook/elements/tag.rb +20 -0
  220. data/lib/docbook/elements/tbody.rb +15 -0
  221. data/lib/docbook/elements/term.rb +37 -0
  222. data/lib/docbook/elements/tertiary.rb +16 -0
  223. data/lib/docbook/elements/textobject.rb +18 -0
  224. data/lib/docbook/elements/tfoot.rb +15 -0
  225. data/lib/docbook/elements/tgroup.rb +21 -0
  226. data/lib/docbook/elements/thead.rb +15 -0
  227. data/lib/docbook/elements/tip.rb +30 -0
  228. data/lib/docbook/elements/title.rb +16 -0
  229. data/lib/docbook/elements/toc.rb +24 -0
  230. data/lib/docbook/elements/tocdiv.rb +22 -0
  231. data/lib/docbook/elements/tocentry.rb +20 -0
  232. data/lib/docbook/elements/topic.rb +26 -0
  233. data/lib/docbook/elements/type.rb +16 -0
  234. data/lib/docbook/elements/uri.rb +16 -0
  235. data/lib/docbook/elements/userinput.rb +18 -0
  236. data/lib/docbook/elements/variable.rb +16 -0
  237. data/lib/docbook/elements/variablelist.rb +19 -0
  238. data/lib/docbook/elements/varlistentry.rb +17 -0
  239. data/lib/docbook/elements/version.rb +16 -0
  240. data/lib/docbook/elements/videoobject.rb +18 -0
  241. data/lib/docbook/elements/warning.rb +30 -0
  242. data/lib/docbook/elements/xref.rb +18 -0
  243. data/lib/docbook/elements/year.rb +16 -0
  244. data/lib/docbook/elements.rb +204 -0
  245. data/lib/docbook/models/document_metadata.rb +30 -0
  246. data/lib/docbook/models/document_root.rb +33 -0
  247. data/lib/docbook/models/index_entry.rb +28 -0
  248. data/lib/docbook/models/reading_position.rb +22 -0
  249. data/lib/docbook/models/section_number.rb +18 -0
  250. data/lib/docbook/models/section_root.rb +29 -0
  251. data/lib/docbook/models/toc_node.rb +24 -0
  252. data/lib/docbook/models.rb +16 -0
  253. data/lib/docbook/output/data.rb +196 -0
  254. data/lib/docbook/output/html.rb +1450 -0
  255. data/lib/docbook/output/index_generator.rb +281 -0
  256. data/lib/docbook/output.rb +8 -0
  257. data/lib/docbook/services/document_builder.rb +258 -0
  258. data/lib/docbook/services/element_to_hash.rb +287 -0
  259. data/lib/docbook/services/index_generator.rb +134 -0
  260. data/lib/docbook/services/numbering_service.rb +186 -0
  261. data/lib/docbook/services/toc_generator.rb +138 -0
  262. data/lib/docbook/services.rb +14 -0
  263. data/lib/docbook/templates/document.html.liquid +20 -0
  264. data/lib/docbook/templates/partials/_head.liquid +39 -0
  265. data/lib/docbook/templates/partials/_scripts.liquid +10 -0
  266. data/lib/docbook/version.rb +5 -0
  267. data/lib/docbook/xinclude_resolver.rb +217 -0
  268. data/lib/docbook/xref_resolver.rb +78 -0
  269. data/lib/docbook.rb +17 -0
  270. data/sig/docbook.rbs +4 -0
  271. metadata +385 -0
@@ -0,0 +1,161 @@
1
+ ---
2
+ layout: default
3
+ title: Quick Start
4
+ parent: Getting Started
5
+ nav_order: 2
6
+ ---
7
+
8
+ == Quick Start
9
+
10
+ This page walks you through the three most common operations using the `docbook` command-line tool: validating, converting to HTML, and formatting DocBook XML files.
11
+
12
+ === Prerequisites
13
+
14
+ Make sure the gem is installed and the `docbook` command is available. See <<installation>> for details.
15
+
16
+ For these examples, we will use a sample DocBook 5 article file called `article.xml`:
17
+
18
+ [source,xml]
19
+ ----
20
+ <?xml version="1.0" encoding="UTF-8"?>
21
+ <article xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="my-article">
22
+ <info>
23
+ <title>Getting Started with DocBook</title>
24
+ </info>
25
+ <section xml:id="intro">
26
+ <title>Introduction</title>
27
+ <para>This is a sample DocBook article demonstrating the basic features
28
+ of the Metanorma DocBook gem.</para>
29
+ </section>
30
+ <section xml:id="usage">
31
+ <title>Usage</title>
32
+ <para>See the <xref linkend="intro"/> for background information.</para>
33
+ </section>
34
+ </article>
35
+ ----
36
+
37
+ === 1. Validate a DocBook File
38
+
39
+ The `validate` command checks whether an XML file is well-formed:
40
+
41
+ [source,bash]
42
+ ----
43
+ $ docbook validate article.xml
44
+ article.xml: valid
45
+ ----
46
+
47
+ If the file contains errors, the command prints each error to stderr and exits with code 1:
48
+
49
+ [source,bash]
50
+ ----
51
+ $ docbook validate broken.xml
52
+ broken.xml: 6:14: FATAL: Opening and ending tag mismatch: section line 4 and artcle
53
+ broken.xml: 1 file, 1 failures
54
+ $ echo $?
55
+ 1
56
+ ----
57
+
58
+ *TIP:* The `validate` command checks XML well-formedness using Nokogiri. It does not validate against the DocBook schema (DTD or RelaxNG).
59
+
60
+ === 2. Convert to HTML
61
+
62
+ The `to-html` command converts a DocBook XML file to a self-contained HTML document.
63
+
64
+ ==== Single-File Mode (default)
65
+
66
+ [source,bash]
67
+ ----
68
+ $ docbook to-html article.xml -o output.html
69
+ Written to output.html
70
+ ----
71
+
72
+ This produces a single HTML file with all assets (CSS, JavaScript, images) embedded inline. Images are converted to Base64 data URIs, making the file completely self-contained and portable.
73
+
74
+ To write to stdout instead of a file, omit the `--output` option:
75
+
76
+ [source,bash]
77
+ ----
78
+ $ docbook to-html article.xml
79
+ <!DOCTYPE html><html>...
80
+ ----
81
+
82
+ ==== Directory Mode
83
+
84
+ Use `--output-type directory` to generate a multi-file output suitable for web serving:
85
+
86
+ [source,bash]
87
+ ----
88
+ $ docbook to-html article.xml -o my-book --output-type directory
89
+ Written to my-book/index.html and assets/
90
+ ----
91
+
92
+ Directory mode creates the following structure:
93
+
94
+ [source]
95
+ ----
96
+ my-book/
97
+ index.html # HTML shell with Vue.js app
98
+ docbook.data.json # Structured content data (TOC, sections, index)
99
+ assets/
100
+ app.css # Stylesheet
101
+ app.iife.js # Vue.js application bundle
102
+ ----
103
+
104
+ ==== XInclude Resolution
105
+
106
+ By default, XIncludes are resolved before conversion. To disable this:
107
+
108
+ [source,bash]
109
+ ----
110
+ $ docbook to-html book.xml -o output.html --no-xinclude
111
+ ----
112
+
113
+ === 3. Format (Prettify) DocBook XML
114
+
115
+ The `format` command reformats a DocBook XML file with consistent indentation:
116
+
117
+ [source,bash]
118
+ ----
119
+ $ docbook format article.xml -o formatted.xml
120
+ Written to formatted.xml
121
+ ----
122
+
123
+ The output is a properly indented XML document with an XML declaration:
124
+
125
+ [source,xml]
126
+ ----
127
+ <?xml version="1.0" encoding="utf-8"?>
128
+ <article xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="my-article">
129
+ <info>
130
+ <title>Getting Started with DocBook</title>
131
+ </info>
132
+ <section xml:id="intro">
133
+ <title>Introduction</title>
134
+ <para>This is a sample DocBook article demonstrating the basic features
135
+ of the Metanorma DocBook gem.</para>
136
+ </section>
137
+ </article>
138
+ ----
139
+
140
+ To print to stdout, omit the `--output` option:
141
+
142
+ [source,bash]
143
+ ----
144
+ $ docbook format article.xml
145
+ ----
146
+
147
+ To resolve XIncludes before formatting:
148
+
149
+ [source,bash]
150
+ ----
151
+ $ docbook format book.xml --xinclude -o book-flat.xml
152
+ Written to book-flat.xml
153
+ ----
154
+
155
+ === Next Steps
156
+
157
+ Now that you can validate, convert, and format DocBook files, explore the full documentation:
158
+
159
+ * *<<interfaces,Interfaces>>* -- Detailed CLI reference and Ruby API documentation
160
+ * *<<../interfaces/cli/,CLI Reference>>* -- All commands, options, and examples
161
+ * *<<../interfaces/ruby-api/,Ruby API>>* -- Programmatic access to parsing, XInclude resolution, cross-references, and HTML output
@@ -0,0 +1,188 @@
1
+ ---
2
+ layout: default
3
+ title: Converting an Article
4
+ parent: Guides
5
+ nav_order: 2
6
+ ---
7
+
8
+ # Converting an Article
9
+
10
+ Articles are simpler than books -- they have a flat structure with no
11
+ parts, chapters, or appendices. This guide shows how to convert a
12
+ DocBook article to HTML.
13
+
14
+ == Article structure
15
+
16
+ A DocBook article uses `<section>` elements for its hierarchy instead
17
+ of the part/chapter structure of a book. Here is a complete example:
18
+
19
+ [source,xml]
20
+ ----
21
+ <?xml version="1.0" encoding="UTF-8"?>
22
+ <article xmlns="http://docbook.org/ns/docbook" version="5.0"
23
+ xml:id="api-design">
24
+ <info>
25
+ <title>API Design Principles</title>
26
+ <author>
27
+ <personname>
28
+ <firstname>Alex</firstname>
29
+ <surname>Architect</surname>
30
+ </personname>
31
+ </author>
32
+ <pubdate>2025-01-15</pubdate>
33
+ </info>
34
+
35
+ <section xml:id="s-overview">
36
+ <title>Overview</title>
37
+ <para>This article presents key principles for designing
38
+ robust and maintainable APIs.</para>
39
+
40
+ <section xml:id="s-overview-goals">
41
+ <title>Design Goals</title>
42
+ <para>An API should be consistent, discoverable, and
43
+ resilient to change.</para>
44
+ </section>
45
+ </section>
46
+
47
+ <section xml:id="s-patterns">
48
+ <title>Common Patterns</title>
49
+
50
+ <para>REST APIs typically follow these patterns:</para>
51
+
52
+ <itemizedlist>
53
+ <listitem>
54
+ <para>Use nouns for resource endpoints.</para>
55
+ </listitem>
56
+ <listitem>
57
+ <para>Return appropriate HTTP status codes.</para>
58
+ </listitem>
59
+ <listitem>
60
+ <para>Version your API from the start.</para>
61
+ </listitem>
62
+ </itemizedlist>
63
+
64
+ <example>
65
+ <title>Sample endpoint</title>
66
+ <programlisting language="bash">
67
+ curl -X GET https://api.example.com/v1/users \
68
+ -H "Authorization: Bearer TOKEN"
69
+ </programlisting>
70
+ </example>
71
+ </section>
72
+
73
+ <section xml:id="s-error-handling">
74
+ <title>Error Handling</title>
75
+
76
+ <para>Always provide structured error responses:</para>
77
+
78
+ <programlisting language="json">
79
+ {
80
+ "error": {
81
+ "code": "VALIDATION_ERROR",
82
+ "message": "The 'email' field is required."
83
+ }
84
+ }
85
+ </programlisting>
86
+
87
+ <note>
88
+ <title>Important</title>
89
+ <para>Never expose internal stack traces in production
90
+ error responses.</para>
91
+ </note>
92
+
93
+ <warning>
94
+ <para>Returning HTML error pages from a JSON API endpoint
95
+ breaks client parsing.</para>
96
+ </warning>
97
+ </section>
98
+
99
+ <section xml:id="s-figure-example">
100
+ <title>Architecture Diagram</title>
101
+ <figure>
102
+ <title>System Architecture</title>
103
+ <mediaobject>
104
+ <imageobject>
105
+ <imagedata fileref="images/architecture.png"/>
106
+ </imageobject>
107
+ </mediaobject>
108
+ </figure>
109
+ </section>
110
+ </article>
111
+ ----
112
+
113
+ == CLI conversion
114
+
115
+ To convert the article to a single HTML file:
116
+
117
+ ....
118
+ docbook to-html article.xml -o article.html
119
+ ....
120
+
121
+ For directory output:
122
+
123
+ ....
124
+ docbook to-html article.xml -o article-out --output-type directory
125
+ ....
126
+
127
+ Note that XInclude resolution is enabled by default for `to-html`. If
128
+ your article does not use XIncludes, this has no effect.
129
+
130
+ == Ruby API conversion
131
+
132
+ [source,ruby]
133
+ ----
134
+ require "docbook"
135
+
136
+ xml = File.read("article.xml")
137
+
138
+ # Parse the article
139
+ doc = Docbook::Document.from_xml(xml)
140
+
141
+ # Resolve cross-references
142
+ xref = Docbook::XrefResolver.new(doc).resolve!
143
+
144
+ # Generate HTML (single file)
145
+ html = Docbook::Output::Html.new(
146
+ doc,
147
+ xref_resolver: xref,
148
+ output_mode: :single_file,
149
+ base_path: File.dirname(File.expand_path("article.xml"))
150
+ ).to_html
151
+
152
+ File.write("article.html", html)
153
+ ----
154
+
155
+ == What to expect in the output
156
+
157
+ The article conversion produces the following:
158
+
159
+ * **Title** -- The article title from `<info><title>` appears in the
160
+ browser tab and as the document header.
161
+ * **Section tree** -- Each `<section>` becomes a navigable entry in the
162
+ TOC sidebar. Nested sections appear as children.
163
+ * **Numbering** -- Sections receive hierarchical numbers (1, 1.1, 2,
164
+ 2.1, etc.).
165
+ * **Code blocks** -- `<programlisting>` elements are rendered with
166
+ Prism.js syntax highlighting. The `language` attribute determines the
167
+ highlighting language.
168
+ * **Lists** -- `<itemizedlist>` renders as a bulleted list,
169
+ `<orderedlist>` as a numbered list.
170
+ * **Admonitions** -- `<note>`, `<warning>`, `<caution>`, `<important>`,
171
+ and `<tip>` render as styled callout boxes.
172
+ * **Figures** -- `<figure>` with `<mediaobject>` renders the image with
173
+ an optional caption.
174
+ * **Examples** -- `<example>` renders with its title and content.
175
+
176
+ == Inline content
177
+
178
+ Articles support the same inline elements as books. The following
179
+ elements are rendered correctly inside `<para>` and other block
180
+ elements:
181
+
182
+ * `<emphasis>` -- Italic or bold (based on `role` attribute)
183
+ * `<code>` and `<literal>` -- Monospace inline code
184
+ * `<link xlink:href="...">` -- Hyperlinks
185
+ * `<xref linkend="...">` -- Cross-references to other sections
186
+ * `<filename>` -- File names in monospace
187
+ * `<quote>` -- Quoted text
188
+ * `<citetitle>` -- Citation titles
@@ -0,0 +1,192 @@
1
+ ---
2
+ layout: default
3
+ title: Converting a Book
4
+ parent: Guides
5
+ nav_order: 1
6
+ ---
7
+
8
+ # Converting a Book
9
+
10
+ This guide walks through converting a complete DocBook 5 book document
11
+ to HTML using the Metanorma DocBook gem.
12
+
13
+ == Sample book structure
14
+
15
+ A typical DocBook book has the following structure:
16
+
17
+ [source,xml]
18
+ ----
19
+ <?xml version="1.0" encoding="UTF-8"?>
20
+ <book xmlns="http://docbook.org/ns/docbook" version="5.0"
21
+ xml:id="my-book">
22
+ <info>
23
+ <title>My Technical Book</title>
24
+ <author>
25
+ <personname>
26
+ <firstname>Jane</firstname>
27
+ <surname>Developer</surname>
28
+ </personname>
29
+ </author>
30
+ <copyright>
31
+ <year>2025</year>
32
+ <holder>Acme Corp</holder>
33
+ </copyright>
34
+ </info>
35
+
36
+ <preface xml:id="preface">
37
+ <title>Preface</title>
38
+ <para>This book explains how to use the DocBook conversion tool.</para>
39
+ </preface>
40
+
41
+ <part xml:id="part-fundamentals">
42
+ <title>Part I. Fundamentals</title>
43
+ <chapter xml:id="ch-intro">
44
+ <title>Introduction</title>
45
+ <para>Content of the introduction chapter.</para>
46
+ <section xml:id="ch-intro-overview">
47
+ <title>Overview</title>
48
+ <para>Detailed overview content.</para>
49
+ </section>
50
+ </chapter>
51
+ <chapter xml:id="ch-setup">
52
+ <title>Getting Started</title>
53
+ <para>Setup instructions here.</para>
54
+ </chapter>
55
+ </part>
56
+
57
+ <appendix xml:id="appendix-a">
58
+ <title>Appendix A. Additional Resources</title>
59
+ <para>Supplementary material.</para>
60
+ </appendix>
61
+
62
+ <glossary xml:id="glossary">
63
+ <title>Glossary</title>
64
+ <glossentry>
65
+ <glossterm>DocBook</glossterm>
66
+ <glossdef>
67
+ <para>A semantic markup language for technical documentation.</para>
68
+ </glossdef>
69
+ </glossentry>
70
+ </glossary>
71
+
72
+ <bibliography xml:id="bibliography">
73
+ <title>References</title>
74
+ <bibliomixed>
75
+ <abbrev>DocBook5</abbrev>
76
+ <title>DocBook 5: The Definitive Guide</title>
77
+ </bibliomixed>
78
+ </bibliography>
79
+
80
+ <index xml:id="index"/>
81
+ </book>
82
+ ----
83
+
84
+ == Step 1: Validate the input
85
+
86
+ Before conversion, validate that the XML is well-formed:
87
+
88
+ ....
89
+ docbook validate book.xml
90
+ ....
91
+
92
+ If the file is valid, the command prints `book.xml: valid` and exits
93
+ with code 0. If there are errors, they are printed to stderr and the
94
+ command exits with code 1.
95
+
96
+ == Step 2: Check XIncludes (if applicable)
97
+
98
+ If your book uses `<xi:include>` to pull in chapters from separate
99
+ files, verify that all referenced files exist and are well-formed XML.
100
+ XInclude resolution is enabled by default for `to-html`.
101
+
102
+ == Step 3: Convert to single-file HTML
103
+
104
+ For a self-contained HTML file:
105
+
106
+ ....
107
+ docbook to-html book.xml -o output.html
108
+ ....
109
+
110
+ This produces `output.html` with all data, CSS, and JavaScript
111
+ inlined. You can open it directly in any browser.
112
+
113
+ == Step 4: Convert to directory output
114
+
115
+ For a directory-based output with linked assets:
116
+
117
+ ....
118
+ docbook to-html book.xml -o my-book --output-type directory
119
+ ....
120
+
121
+ This creates a `my-book/` directory containing:
122
+
123
+ * `index.html` -- The HTML shell with the Vue SPA mount point
124
+ * `docbook.data.json` -- The full document data as JSON
125
+ * `assets/app.css` -- The compiled stylesheet
126
+ * `assets/app.iife.js` -- The bundled JavaScript
127
+
128
+ == Step 5: Open in browser
129
+
130
+ Open the HTML file or directory in a web browser. You should see:
131
+
132
+ * **TOC sidebar** -- A collapsible tree showing all parts, chapters,
133
+ and sections with their section numbers.
134
+ * **Section numbering** -- Parts labeled with Roman numerals (I, II),
135
+ chapters with Arabic numbers (1, 2), and sections with hierarchical
136
+ dotted numbers (1.1, 1.2.3).
137
+ * **Chapter navigation** -- Click any TOC entry to navigate to that
138
+ section.
139
+ * **Search** -- Use the search function to find sections by title.
140
+ * **Index page** -- If the book contains `<indexterm>` elements, an
141
+ index section with entries grouped by letter.
142
+ * **Settings** -- Theme, font size, reading mode, and other preferences.
143
+
144
+ == Using the Ruby API
145
+
146
+ You can also convert programmatically:
147
+
148
+ [source,ruby]
149
+ ----
150
+ require "docbook"
151
+
152
+ xml = File.read("book.xml")
153
+
154
+ # Parse
155
+ doc = Docbook::Document.from_xml(xml)
156
+
157
+ # Resolve cross-references
158
+ xref = Docbook::XrefResolver.new(doc).resolve!
159
+
160
+ # Generate HTML
161
+ html = Docbook::Output::Html.new(
162
+ doc,
163
+ xref_resolver: xref,
164
+ output_mode: :single_file,
165
+ base_path: File.dirname(File.expand_path("book.xml"))
166
+ ).to_html
167
+
168
+ File.write("output.html", html)
169
+ ----
170
+
171
+ == Troubleshooting
172
+
173
+ Unsupported root element::
174
+ Ensure the XML root element is one of the 37 supported types listed
175
+ in `Document::ROOT_ELEMENT_MAP`. The most common roots are `book`,
176
+ `article`, and `set`.
177
+
178
+ Missing images in output::
179
+ The converter resolves image paths relative to the input file's
180
+ directory. It also searches parent directories and common prefixes
181
+ like `resources/`. If images are still missing, check that the
182
+ `fileref` attribute in `<imagedata>` points to a valid file.
183
+
184
+ XInclude errors::
185
+ XInclude resolution requires that referenced files exist and are
186
+ accessible from the input file's location. Check file paths and
187
+ permissions.
188
+
189
+ Empty output::
190
+ If the output HTML appears empty, the document may not contain any
191
+ recognized block elements. Ensure chapters and sections contain
192
+ `<para>`, `<programlisting>`, or other supported block elements.
@@ -0,0 +1,12 @@
1
+ ---
2
+ layout: default
3
+ title: Guides
4
+ nav_order: 7
5
+ has_children: true
6
+ ---
7
+
8
+ # Guides
9
+
10
+ This section contains task-oriented tutorials that walk you through
11
+ common scenarios step by step. Each guide is self-contained and
12
+ includes complete examples you can run immediately.
@@ -0,0 +1,129 @@
1
+ ---
2
+ layout: default
3
+ title: Round-trip Testing
4
+ parent: Guides
5
+ nav_order: 3
6
+ ---
7
+
8
+ # Round-trip Testing
9
+
10
+ The `docbook roundtrip` command verifies that the element model can
11
+ faithfully parse and re-serialize a DocBook XML document. This is
12
+ essential for ensuring model completeness and serialization fidelity.
13
+
14
+ == How round-trip testing works
15
+
16
+ The round-trip test performs the following sequence:
17
+
18
+ . **Parse** -- The input XML is parsed into element model objects via
19
+ `Document.from_xml`.
20
+ . **Serialize** -- The model objects are serialized back to XML using
21
+ `to_xml` with pretty printing enabled.
22
+ . **Re-parse** -- The serialized XML is parsed again.
23
+ . **Compare** -- If the second parse succeeds without errors, the test
24
+ passes.
25
+
26
+ A successful round-trip confirms that:
27
+
28
+ * All elements and attributes in the input are represented in the model.
29
+ * The XML serialization produces valid DocBook XML.
30
+ * The serialized output can be parsed again without errors.
31
+
32
+ Note that the test does not compare the original and re-serialized XML
33
+ strings character-by-character. Differences in whitespace, attribute
34
+ order, and namespace declarations are acceptable as long as the
35
+ re-parsing succeeds.
36
+
37
+ == Using the CLI
38
+
39
+ Test one or more files:
40
+
41
+ ....
42
+ docbook roundtrip book.xml
43
+ docbook roundtrip chapter1.xml chapter2.xml chapter3.xml
44
+ ....
45
+
46
+ For each file, the command prints either `filename.xml: OK` or
47
+ `filename.xml: FAIL - error message`. At the end, it prints a summary:
48
+
49
+ ....
50
+ 3 files, 0 failures
51
+ ....
52
+
53
+ If any file fails, the command exits with code 1.
54
+
55
+ == Using in CI pipelines
56
+
57
+ Round-trip testing is valuable in continuous integration. Add a step
58
+ to your CI configuration that runs round-trip tests against a corpus
59
+ of DocBook files:
60
+
61
+ [source,yaml]
62
+ ----
63
+ # GitHub Actions example
64
+ - name: Round-trip test
65
+ run: |
66
+ find spec/fixtures -name '*.xml' -print0 | \
67
+ xargs -0 bundle exec docbook roundtrip
68
+ ----
69
+
70
+ This discovers all XML fixture files and tests them in a single
71
+ invocation. The command fails the build if any file does not
72
+ round-trip successfully.
73
+
74
+ == Ruby API
75
+
76
+ You can also run round-trip tests programmatically:
77
+
78
+ [source,ruby]
79
+ ----
80
+ require "docbook"
81
+
82
+ def roundtrip_test(xml_string)
83
+ parsed = Docbook::Document.from_xml(xml_string)
84
+ serialized = parsed.to_xml(declaration: true, encoding: "utf-8")
85
+ reparsed = Docbook::Document.from_xml(serialized)
86
+ true
87
+ rescue => e
88
+ puts "Round-trip failed: #{e.message}"
89
+ false
90
+ end
91
+ ----
92
+
93
+ == Interpreting failures
94
+
95
+ Round-trip failures typically indicate one of the following issues:
96
+
97
+ Unsupported element::
98
+ If the input contains an element that has no corresponding model class,
99
+ `Document.from_xml` raises a "Unsupported root element" error. The
100
+ solution is to add the missing element class.
101
+
102
+ Missing attribute::
103
+ If an element's XML mapping does not declare an attribute that appears
104
+ in the input, the attribute is silently dropped during parsing. The
105
+ re-serialized XML will lack the attribute. This usually manifests as
106
+ a different parse result on the second pass.
107
+
108
+ Broken mixed content::
109
+ If an element declares `mixed_content` but its child element mappings
110
+ are incomplete, some children may be lost during serialization. Check
111
+ that all expected child elements are declared in the element class.
112
+
113
+ Serialization error::
114
+ If the model's `to_xml` produces malformed XML (for example, due to
115
+ incorrect namespace handling), the re-parse step will fail with a
116
+ Nokogiri parse error. The error message usually identifies the line
117
+ and column where the problem occurs.
118
+
119
+ == Testing with XIncludes
120
+
121
+ Round-trip testing operates on the raw XML without resolving XIncludes.
122
+ If you want to test XInclude resolution as well, resolve the includes
123
+ first, then run the round-trip on the resolved document:
124
+
125
+ ....
126
+ # Resolve XIncludes first, then round-trip the resolved XML
127
+ resolved = Docbook::XIncludeResolver.resolve_string(xml_string, base_path: "book.xml")
128
+ Docbook::Document.from_xml(resolved.to_xml)
129
+ ....