# HG changeset patch
# Node ID c74b8aa36f68
# Parent  71f0a1891d24
diff --git a/.hgignore b/.hgignore
--- a/.hgignore
+++ b/.hgignore
@@ -17,3 +17,5 @@
 ^po\/.*\.pot$
 ^obj-x86_64-linux-gnu\/
 ^debian\/?$
+^subprojects\/.+\/
+
diff --git a/convey.yml b/convey.yml
--- a/convey.yml
+++ b/convey.yml
@@ -85,8 +85,8 @@
   docs-export:
     type: docker/export
     files:
-      - build-docs/gplugin/reference/html:gplugin-docs
-      - build-docs/gplugin-gtk/reference/html:gplugin-gtk-docs
+      - build-docs/gplugin/reference/gplugin:gplugin-docs
+      - build-docs/gplugin-gtk/reference/gplugin-gtk:gplugin-gtk-docs
 
   package-cloud:
     type: docker/run
diff --git a/gplugin-gtk/meson.build b/gplugin-gtk/meson.build
--- a/gplugin-gtk/meson.build
+++ b/gplugin-gtk/meson.build
@@ -141,7 +141,7 @@
 ###############################################################################
 # subdirectories
 ###############################################################################
-if ENABLE_DOC
+if get_option('doc')
 	subdir('reference')
 endif
 
diff --git a/gplugin-gtk/reference/Dockerfile b/gplugin-gtk/reference/Dockerfile
deleted file mode 100644
--- a/gplugin-gtk/reference/Dockerfile
+++ /dev/null
@@ -1,6 +0,0 @@
-FROM rwgrim/goserve
-
-EXPOSE 3000
-
-COPY html html
-
diff --git a/gplugin-gtk/reference/gplugin-gtk-docs.xml b/gplugin-gtk/reference/gplugin-gtk-docs.xml
deleted file mode 100644
--- a/gplugin-gtk/reference/gplugin-gtk-docs.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
-                      "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
-<!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
-<!ENTITY version SYSTEM "version.xml">
-]>
-<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
-  <bookinfo>
-    <title>GPlugin Gtk Reference Manual</title>
-    <abstract>
-      <title>GPluginGtk &version;</title>
-      <para>
-        GPluginGtk is a collection of Gtk widgets to make it easier to
-        integrate GPlugin into applications.
-      </para>
-      <para>
-        The latest version of this documentation can be found on-line at
-        <ulink role="online-location" url="https://docs.pidgin.im/gplugin-gtk/latest">https://docs.pidgin.im/gplugin-gtk/latest/</ulink>.
-      </para>
-    </abstract>
-  </bookinfo>
-
-  <part id="object-hierarchy">
-    <title>Object Hierarchy</title>
-
-    <xi:include href="xml/tree_index.sgml"/>
-  </part>
-
-  <part id="API">
-	  <title>API Reference</title>
-
-    <xi:include href="xml/gplugin-gtk-plugin-info.xml"/>
-    <xi:include href="xml/gplugin-gtk-store.xml"/>
-    <xi:include href="xml/gplugin-gtk-view.xml"/>
-  </part>
-
-  <index id="api-index-full">
-    <title>Index</title>
-    <xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
-  </index>
-  <index id="api-index-deprecated" role="deprecated">
-    <title>Index of deprecated symbols</title>
-    <xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
-  </index>
-
-  <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
-</book>
diff --git a/gplugin-gtk/reference/gplugin-gtk.toml.in b/gplugin-gtk/reference/gplugin-gtk.toml.in
new file mode 100644
--- /dev/null
+++ b/gplugin-gtk/reference/gplugin-gtk.toml.in
@@ -0,0 +1,48 @@
+[library]
+version = "@GPLUGIN_VERSION@"
+browse_url = "https://keep.imfreedom.org/gplugin/gplugin/"
+repository_url = "https://keep.imfreedom.org/gplugin/gplugin/"
+website_url = "https://keep.imfreedom.org/gplugin/gplugin/"
+authors = "GPlugin Developers"
+logo_url = ""
+license = "LGPL-2.1-or-later"
+description = "GPlugin Gtk Library"
+dependencies = [ "GLib-2.0", "GObject-2.0", "GPlugin-1.0", "Gtk-3.0" ]
+devhelp = true
+search_index = true
+
+  [dependencies."GLib-2.0"]
+  name = "GLib"
+  description = "General-purpose, portable utility library."
+  docs_url = "https://docs.gtk.org/glib/"
+
+  [dependencies."GObject-2.0"]
+  name = "GObject"
+  description = "The base type system library"
+  docs_url = "https://docs.gtk.org/gobject/"
+
+  [dependencies."GPlugin-1.0"]
+  name = "GPlugin"
+  description = "Plugin library"
+  docs_url = "https://docs.imfreedom.org/gplugin"
+
+  [dependencies."Gtk-3.0"]
+  name = "Gtk3"
+  description = "Gtk Widget Toolkit"
+  docs_url = "https://docs.gtk.org/gtk3/"
+
+[theme]
+name = "basic"
+show_index_summary = true
+show_class_hierarchy = true
+
+[source-location]
+base_url = "https://keep.imfreedom.org/gplugin/gplugin/file/default/"
+
+[extra]
+# The same order will be used when generating the index
+content_files = [
+]
+content_images = [
+]
+urlmap_file = "urlmap.js"
diff --git a/gplugin-gtk/reference/meson.build b/gplugin-gtk/reference/meson.build
--- a/gplugin-gtk/reference/meson.build
+++ b/gplugin-gtk/reference/meson.build
@@ -1,42 +1,31 @@
-DOC_MODULE = 'gplugin-gtk'
-
-# Header files or dirs to ignore when scanning. Use base file/dir names
-ignore_hfiles = [
-    'gplugin-gtk.h',
-    'gplugin-gtk-resources.h',
-]
-ignore_hfiles += GPLUGIN_GTK_PRIVATE_HEADERS
-
-# Extra options to supply to gtkdoc-scan.
-scan_args = [
-    '--deprecated-guards=GPLUGIN_GTK_DISABLE_DEPRECATED',
-    '--rebuild-types',
-    '--rebuild-sections',
-]
-
-fixxref_args = [
-    '--extra-dir=' + (meson.project_build_root() / 'gplugin/reference/')
-]
+if get_option('doc')
+	gplugin_gtk_toml = configure_file(
+		input : 'gplugin-gtk.toml.in',
+		output : 'gplugin-gtk.toml',
+		configuration : version_conf,
+		install : true,
+		install_dir : docs_dir / 'gplugin-gtk',
+	)
 
-gplugin_gtk_version_xml = configure_file(
-    input : 'version.xml.in',
-    output : 'version.xml',
-    configuration : version_conf)
-
-content_files = [
-]
-
-content_files += gplugin_doc
+	gplugin_gtk_doc = custom_target('gplugin-gtk-doc',
+		input : [ gplugin_gtk_toml, gplugin_gtk_gir[0] ],
+		output : 'gplugin-gtk',
+		command : [
+			gidocgen,
+			'generate',
+			'--quiet',
+			'--fatal-warnings',
+			'--add-include-path=@0@'.format(meson.project_build_root() / 'gplugin'),
+			'--config=@INPUT0@',
+			'--output-dir=@OUTPUT@',
+			'--no-namespace-dir',
+			'--content-dir=@0@'.format(meson.current_source_dir()),
+			'@INPUT1@'
+		],
+		depends : [ gplugin_gir[0] ],
+		build_by_default : true,
+		install : true,
+		install_dir : docs_dir,
+	)
+endif
 
-gplugin_gtk_doc = gnome.gtkdoc(DOC_MODULE,
-    main_xml : DOC_MODULE + '-docs.xml',
-    namespace : 'gplugin_gtk',
-    src_dir : gplugin_gtk_inc,
-    dependencies : gplugin_gtk_dep,
-    ignore_headers : ignore_hfiles,
-    install : true,
-    scan_args : scan_args,
-    gobject_typesfile : DOC_MODULE + '.types',
-    content_files : content_files,
-    fixxref_args : fixxref_args,
-)
diff --git a/gplugin-gtk/reference/urlmap.js b/gplugin-gtk/reference/urlmap.js
new file mode 100644
--- /dev/null
+++ b/gplugin-gtk/reference/urlmap.js
@@ -0,0 +1,11 @@
+// SPDX-FileCopyrightText: 2021 GNOME Foundation
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
+// A map between namespaces and base URLs for their online documentation
+baseURLs = [
+    [ 'GLib', 'https://docs.gtk.org/glib/' ],
+    [ 'GObject', 'https://docs.gtk.org/gobject/' ],
+    [ 'GPlugin', 'https://docs.imfreedom.org/gplugin' ],
+    [ 'GModule', 'https://docs.gtk.org/gmodule/' ],
+    [ 'Gtk3', 'https://docs.gtk.org/gtk3/' ],
+]
diff --git a/gplugin-gtk/reference/version.xml.in b/gplugin-gtk/reference/version.xml.in
deleted file mode 100644
--- a/gplugin-gtk/reference/version.xml.in
+++ /dev/null
@@ -1,1 +0,0 @@
-@GPLUGIN_VERSION@
diff --git a/gplugin/meson.build b/gplugin/meson.build
--- a/gplugin/meson.build
+++ b/gplugin/meson.build
@@ -229,6 +229,6 @@
 subdir('share')
 subdir('tests')
 
-if ENABLE_DOC
+if get_option('doc')
 	subdir('reference')
 endif
diff --git a/gplugin/reference/Dockerfile b/gplugin/reference/Dockerfile
deleted file mode 100644
--- a/gplugin/reference/Dockerfile
+++ /dev/null
@@ -1,6 +0,0 @@
-FROM rwgrim/goserve
-
-EXPOSE 3000
-
-COPY html html
-
diff --git a/gplugin/reference/embedding.xml b/gplugin/reference/embedding.md
rename from gplugin/reference/embedding.xml
rename to gplugin/reference/embedding.md
--- a/gplugin/reference/embedding.xml
+++ b/gplugin/reference/embedding.md
@@ -1,53 +1,47 @@
-<?xml version='1.0' encoding="UTF-8"?>
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
-              "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
-]>
-<chapter id="chapter-embedding">
-  <title>Embedding GPlugin</title>
+Title: Embedding GPlugin
+Slug: embedding
+
+## Embedding GPlugin
+
+You can embed GPlugin into any language that has GObject-Introspection support,
+but in this example we're going to look at embedding GPlugin into a C based
+project.
 
-  <simplesect id="intro">
-    <para>
-      You can embed GPlugin into any language that has GObject-Introspection
-      support, but in this example we're going to look at embedding GPlugin
-      into a C based project.
-    </para>
+GPlugin was designed to be simple to implement and use. Initialization and
+teardown examples can be found below.
+
+### Initialization
+
+During the start up of your application you need to add the following
 
-    <para>
-      GPlugin was designed to be simple to implement and use.  Initialization
-      and teardown examples can be found below.
-    </para>
-  </simplesect>
+```c
+/* Create a variable to hold the default manager instance. */
+GPluginManager *manager = NULL;
+
+/* Initialize the GPlugin library */
+gplugin_init();
 
-  <simplesect id="initialization">
-    <para>
-      During the start up of your application you need to add the following
-      code:
-      <informalexample><programlisting>
-      /* Initialize the GPlugin library */
-      gplugin_init();
+/* Get a pointer to the default GPluginManager instance. */
+manager = gplugin_manager_get_default();
 
-      /* Tell GPlugin to look for plugins in its default paths */
-      gplugin_manager_add_default_paths();
+/* Tell GPlugin to look for plugins in its default paths */
+gplugin_manager_add_default_paths(manager);
 
-      /* Optionally tell GPlugin to look for plugins in application specific
-       * paths.  This will add `$PREFIX/lib/application`.
-       */
-      gplugin_manager_add_app_paths(PREFIX, "application");
+/* Optionally tell GPlugin to look for plugins in application specific
+ * paths.  This will add `$PREFIX/lib/application`.
+ */
+gplugin_manager_add_app_paths(manager, PREFIX, "application");
 
-      /* Once you're ready to find/load plugins call g_plugin_manager_refresh.
-       */
-      gplugin_manager_refresh();
-      </programlisting></informalexample>
-    </para>
-  </simplesect>
+/* Once you're ready to find/load plugins call g_plugin_manager_refresh. */
+gplugin_manager_refresh(manager);
+```
+
+### Shutdown
 
-  <simplesect id="shutdown">
-    <para>
-      When your application is shutting down you need to uninitialize GPlugin
-      by calling
-      <informalexample><programlisting>
-      gplugin_uninit();
-      </programlisting></informalexample>
-    </para>
-  </simplesect>
-</chapter>
+When your application is shutting down you need to uninitialize GPlugin by
+calling
+
+```c
+gplugin_uninit();
+```
+
diff --git a/gplugin/reference/genie.xml b/gplugin/reference/genie.md
rename from gplugin/reference/genie.xml
rename to gplugin/reference/genie.md
--- a/gplugin/reference/genie.xml
+++ b/gplugin/reference/genie.md
@@ -1,70 +1,54 @@
-<?xml version='1.0' encoding="UTF-8"?>
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
-              "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
-]>
-<chapter id="chapter-genie">
-	<title>Genie Plugins</title>
+Title: Genie Plugin Example
+Slug: genie
+
+## Genie Plugins
 
-	<warning>
-		<para>
-			You <emphasis role="strong">MUST</emphasis> have the Vala bindings
-			installed on your system for this to work.  They are built by the
-			default GPlugin build.
-		</para>
-	</warning>
+> You **MUST** have the Vala bindings installed on your system for this to
+> work. They are built by the default GPlugin build.
+
+### Example Genie Plugin
 
-	<simplesect>
-		<title>Example Genie Plugin</title>
+Like all plugins in GPlugin, Genie plugins must also implement the
+`gplugin_query`, `gplugin_load`, and `gplugin_unload` functions.
 
-		<para>
-			Like all plugins in GPlugin, Genie plugins must also implement
-			the <code>gplugin_query</code>, <code>gplugin_load</code>, and
-			<code>gplugin_unload</code> functions.
-		</para>
+Due to the way `GPlugin.PluginInfo` info works, you must subclass it and set
+your values in the new constructor.
 
-		<para>
-			Due to the way <code>GPlugin.PluginInfo</code> info works, you must
-			subclass it and set your values in the new constructor.
-		</para>
+The following is a basic Genie plugin.
 
-		<para>
-			The following is a basic Genie plugin.
-		</para>
+```genie
+uses GPlugin
+
+class BasicPluginInfo : GPlugin.PluginInfo
+	construct()
+		authors : array of string = {"author1"}
 
-		<informalexample><programlisting>
-		uses GPlugin
-
-		class BasicPluginInfo : GPlugin.PluginInfo
-			construct()
-				authors : array of string = {"author1"}
+		Object(
+			id: "gplugin/genie-basic-plugin",
+			abi_version: 0x01020304,
+			name: "basic plugin",
+			authors: authors,
+			category: "test",
+			version: "version",
+			license_id: "license",
+			summary: "summary",
+			website: "website",
+			description: "description"
+		)
 
-				Object(
-					id: "gplugin/genie-basic-plugin",
-					abi_version: 0x01020304,
-					name: "basic plugin",
-					authors: authors,
-					category: "test",
-					version: "version",
-					license_id: "license",
-					summary: "summary",
-					website: "website",
-					description: "description"
-				)
+def gplugin_query(out error : Error) : GPlugin.PluginInfo
+	error = null
+
+	return new BasicPluginInfo()
+
+def gplugin_load(plugin : GPlugin.Plugin, out error : Error) : bool
+	error = null
 
-		def gplugin_query(out error : Error) : GPlugin.PluginInfo
-			error = null
-
-			return new BasicPluginInfo()
-
-		def gplugin_load(plugin : GPlugin.Plugin, out error : Error) : bool
-			error = null
+	return true
 
-			return true
-
-		def gplugin_unload(plugin : GPlugin.Plugin, out error : Error) : bool
-			error = null
+def gplugin_unload(plugin : GPlugin.Plugin, out error : Error) : bool
+	error = null
 
-			return true
-		</programlisting></informalexample>
-	</simplesect>
-</chapter>
+	return true
+```
+
diff --git a/gplugin/reference/gplugin-docs.xml b/gplugin/reference/gplugin-docs.xml
deleted file mode 100644
--- a/gplugin/reference/gplugin-docs.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" 
-               "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
-
-<!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
-<!ENTITY version SYSTEM "version.xml">
-]>
-<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
-  <bookinfo>
-    <title>GPlugin Reference Manual</title>
-    <abstract>
-      <title>GPlugin &version;</title>
-      <para>
-        GPlugin is a GObject based library that implements a reusable plugin
-        system that supports loading plugins in other languages via loaders.
-        GPlugin also implements dependencies among the plugins.
-      </para>
-      <para>
-        The latest version of this documentation can be found on-line at
-        <ulink role="online-location" url="https://docs.pidgin.im/gplugin/latest">https://docs.pidgin.im/gplugin/latest/</ulink>.
-      </para>
-    </abstract>
-  </bookinfo>
-
-  <part id="tutorials">
-    <title>Tutorials</title>
-
-    <xi:include href="embedding.xml"/>
-    <xi:include href="genie.xml"/>
-    <xi:include href="lua.xml"/>
-    <xi:include href="native-plugins.xml"/>
-    <xi:include href="perl5.xml"/>
-    <xi:include href="python3.xml"/>
-    <xi:include href="vala.xml"/>
-  </part>
-
-  <part id="object-hierarchy">
-    <title>Object Hierarchy</title>
-
-    <xi:include href="xml/tree_index.sgml"/>
-  </part>
-
-  <part id="API">
-    <title>API Reference</title>
-
-    <xi:include href="xml/gplugin-core.xml"/>
-    <xi:include href="xml/gplugin-loader.xml"/>
-    <xi:include href="xml/gplugin-manager.xml"/>
-    <xi:include href="xml/gplugin-options.xml"/>
-    <xi:include href="xml/gplugin-plugin-info.xml"/>
-    <xi:include href="xml/gplugin-plugin.xml"/>
-    <xi:include href="xml/gplugin-version.xml"/>
-  </part>
-
-  <part id="Native API">
-    <title>Native API Reference</title>
-
-    <xi:include href="xml/gplugin-native-loader.xml"/>
-    <xi:include href="xml/gplugin-native-plugin.xml"/>
-  </part>
-
-  <index id="api-index-full">
-    <title>Index</title>
-    <xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
-  </index>
-  <index id="api-index-deprecated" role="deprecated">
-    <title>Index of deprecated symbols</title>
-    <xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
-  </index>
-  <index id="api-0.31.0">
-    <title>Index of new symbols in 0.31.0</title>
-    <xi:include href="xml/api-index-0.31.0.xml"><xi:fallback /></xi:include>
-  </index>
-  <index id="api-0.32.0">
-    <title>Index of new symbols in 0.32.0</title>
-    <xi:include href="xml/api-index-0.32.0.xml"><xi:fallback /></xi:include>
-  </index>
-  <index id="api-0.33.0">
-    <title>Index of new symbols in 0.33.0</title>
-    <xi:include href="xml/api-index-0.33.0.xml"><xi:fallback /></xi:include>
-  </index>
-  <index id="api-0.34.0">
-    <title>Index of new symbols in 0.34.0</title>
-    <xi:include href="xml/api-index-0.34.0.xml"><xi:fallback /></xi:include>
-  </index>
-  <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
-</book>
diff --git a/gplugin/reference/gplugin.toml.in b/gplugin/reference/gplugin.toml.in
new file mode 100644
--- /dev/null
+++ b/gplugin/reference/gplugin.toml.in
@@ -0,0 +1,50 @@
+[library]
+version = "@GPLUGIN_VERSION@"
+browse_url = "https://keep.imfreedom.org/gplugin/gplugin/"
+repository_url = "https://keep.imfreedom.org/gplugin/gplugin/"
+website_url = "https://keep.imfreedom.org/gplugin/gplugin/"
+authors = "GPlugin Developers"
+logo_url = ""
+license = "LGPL-2.1-or-later"
+description = "GPlugin Plugin Library"
+dependencies = [ "GLib-2.0", "GObject-2.0", "GModule-2.0" ]
+devhelp = true
+search_index = true
+
+  [dependencies."GLib-2.0"]
+  name = "GLib"
+  description = "General-purpose, portable utility library."
+  docs_url = "https://docs.gtk.org/glib/"
+
+  [dependencies."GObject-2.0"]
+  name = "GObject"
+  description = "The base type system library"
+  docs_url = "https://docs.gtk.org/gobject/"
+
+  [dependencies."GModule-2.0"]
+  name = "GModule"
+  description = "Portable API for dynamically loading modules"
+  docs_url = "https://docs.gtk.org/gmodule/"
+
+[theme]
+name = "basic"
+show_index_summary = true
+show_class_hierarchy = true
+
+[source-location]
+base_url = "https://keep.imfreedom.org/gplugin/gplugin/file/default/"
+
+[extra]
+# The same order will be used when generating the index
+content_files = [
+  "embedding.md",
+  "genie.md",
+  "lua.md",
+  "native-plugins.md",
+  "perl5.md",
+  "python3.md",
+  "vala.md",
+]
+content_images = [
+]
+urlmap_file = "urlmap.js"
diff --git a/gplugin/reference/lua.xml b/gplugin/reference/lua.md
rename from gplugin/reference/lua.xml
rename to gplugin/reference/lua.md
--- a/gplugin/reference/lua.xml
+++ b/gplugin/reference/lua.md
@@ -1,57 +1,43 @@
-<?xml version='1.0' encoding="UTF-8"?>
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
-              "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
-]>
-<chapter id="chapter-lua">
-	<title>Lua Plugins</title>
+Title: Lua Plugins
+Slug: lua
+
+## Lua Plugins
+
+> You **MUST** have the Lua loader plugin installed and working as well as the
+> gobject-introspection package for GPlugin instance to use Lua plugins.
 
-	<warning>
-		<para>
-			You <emphasis role="strong">MUST</emphasis> have the Lua loader
-			plugin installed and working as well as the gobject-introspection
-			package for GPlugin installed to use Lua plugins.
-		</para>
-	</warning>
+### Example Lua Plugin
+
+Like all plugins in GPlugin, Lua plugins must also implement the
+`gplugin_query`, `gplugin_load`, and `gplugin_unload` functions.
 
-	<simplesect>
-		<title>Example Lua Plugin</title>
+The following is a basic Lua plugin.
 
-		<para>
-			Like all plugins in GPlugin, Lua plugins must also implement
-			the <code>gplugin_query</code>, <code>gplugin_load</code>, and
-			<code>gplugin_unload</code> functions.
-		</para>
-
-		<para>
-			The following is a basic Lua plugin.
-		</para>
+```lua
+local lgi = require "lgi"
+local GPlugin = lgi.GPlugin
 
-		<informalexample><programlisting>
-		local lgi = require "lgi"
-		local GPlugin = lgi.GPlugin
+function gplugin_query()
+    return GPlugin.PluginInfo {
+        id = "gplugin-lua/basic-plugin",
+        abi_version = 0x01020304,
+        name = "basic plugin",
+        category = "test",
+        version = "0.0.10",
+        license_id = "license-id",
+        summary = "basic lua plugin",
+        description = "description of the basic lua plugin",
+        authors = { "Gary Kramlich &lt;grim@reaperworld.com&gt;" },
+        website = "https://keep.imfreedom.org/gplugin/gplugin/"
+    }
+end
 
-		function gplugin_query()
-		    return GPlugin.PluginInfo {
-		        id = "gplugin-lua/basic-plugin",
-		        abi_version = 0x01020304,
-		        name = "basic plugin",
-		        category = "test",
-		        version = "0.0.10",
-		        license_id = "license-id",
-		        summary = "basic lua plugin",
-		        description = "description of the basic lua plugin",
-		        authors = { "Gary Kramlich &lt;grim@reaperworld.com&gt;" },
-		        website = "https://keep.imfreedom.org/gplugin/gplugin/"
-		    }
-		end
+function gplugin_load(plugin)
+    return true
+end
 
-		function gplugin_load(plugin)
-		    return true
-		end
+function gplugin_unload(plugin)
+    return true
+end
+```
 
-		function gplugin_unload(plugin)
-		    return true
-		end
-		</programlisting></informalexample>
-	</simplesect>
-</chapter>
diff --git a/gplugin/reference/meson.build b/gplugin/reference/meson.build
--- a/gplugin/reference/meson.build
+++ b/gplugin/reference/meson.build
@@ -1,46 +1,40 @@
-DOC_MODULE = 'gplugin'
-
-# Header files or dirs to ignore when scanning. Use base file/dir names
-ignore_hfiles = [
-    'dynamic-test.h',
-    'gplugin-enums.h',
-    'gplugin-loader-tests.h',
-    'gplugin-native.h',
-    'gplugin-private.h',
-    'gplugin.h',
-]
-ignore_hfiles += GPLUGIN_PRIVATE_HEADERS
-
-# Extra options to supply to gtkdoc-scan.
-scan_args = [
-    '--deprecated-guards=GPLUGIN_DISABLE_DEPRECATED',
-    '--rebuild-types',
-    '--rebuild-sections',
+gplugin_doc_content_files = [
+	'embedding.md',
+	'genie.md',
+	'lua.md',
+	'native-plugins.md',
+	'perl5.md',
+	'python3.md',
+	'vala.md',
 ]
 
-gplugin_version_xml = configure_file(
-    input : 'version.xml.in',
-    output : 'version.xml',
-    configuration : version_conf)
+if get_option('doc')
+	gplugin_toml = configure_file(
+		input : 'gplugin.toml.in',
+		output : 'gplugin.toml',
+		configuration : version_conf,
+		install : true,
+		install_dir : docs_dir / 'gplugin',
+	)
 
-content_files = [
-    'embedding.xml',
-    'genie.xml',
-    'lua.xml',
-    'native-plugins.xml',
-    'perl5.xml',
-    'python3.xml',
-    'vala.xml',
-]
+	gplugin_doc = custom_target('gplugin-doc',
+		input : [ gplugin_toml, gplugin_gir[0] ],
+		output : 'gplugin',
+		command : [
+			gidocgen,
+			'generate',
+			'--quiet',
+			'--fatal-warnings',
+			'--config=@INPUT0@',
+			'--output-dir=@OUTPUT@',
+			'--no-namespace-dir',
+			'--content-dir=@0@'.format(meson.current_source_dir()),
+			'@INPUT1@'
+		],
+		depend_files : [ gplugin_doc_content_files ],
+		build_by_default : true,
+		install : true,
+		install_dir : docs_dir,
+	)
+endif
 
-gplugin_doc = gnome.gtkdoc(DOC_MODULE,
-    main_xml : DOC_MODULE + '-docs.xml',
-    namespace : 'gplugin',
-    src_dir : gplugin_inc,
-    dependencies : gplugin_dep,
-    ignore_headers : ignore_hfiles,
-    install : true,
-    scan_args : scan_args,
-    gobject_typesfile : DOC_MODULE + '.types',
-    content_files : content_files,
-)
diff --git a/gplugin/reference/native-plugins.xml b/gplugin/reference/native-plugins.md
rename from gplugin/reference/native-plugins.xml
rename to gplugin/reference/native-plugins.md
--- a/gplugin/reference/native-plugins.xml
+++ b/gplugin/reference/native-plugins.md
@@ -1,94 +1,79 @@
-<?xml version='1.0' encoding="UTF-8"?>
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
-              "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
-]>
-<chapter id="chapter-native-plugins">
-  <title>Writing Native Plugins</title>
+Title: Native Plugins
+Slug: native
+
+## Native Plugins
 
-  <simplesect id="intro">
-    <para>
-      Writing Native plugins is pretty simple, but since it's C/C++ it's a bit
-      more complicated.
-    </para>
+Writing Native plugins is pretty simple, but since it's C/C++ it's a bit more
+complicated.
 
-    <para>
-      There are currently no C++ bindings and no intention to write them, but
-      the C API is still usable from C++.
-    </para>
-  </simplesect>
+There are currently no C++ bindings and no intention to write them, but the C
+API is still usable from C++.
+
+```c
+#include <gplugin.h>
+#include <gplugin-native.h>
 
-  <simplesect id="example">
-    <para>
-      <informalexample><programlisting>
-      #include &lt;gplugin.h&gt;
-      #include &lt;gplugin-native.h&gt;
-
-      /* This function is called by the native plugin loader to get information
-       * about the plugin. It returns a #GPluginPluginInfo instance that
-       * describes the plugin. If anything goes wrong during this function,
-       * @error should be set via g_set_error() and %NULL should be returned.
-       * It must match the signature of #GPluginNativePluginQueryFunc, and it
-       * will be passed to #GPLUGIN_NATIVE_PLUGIN_DECLARE which will export it
-       * properly.
-       */
-      static GPluginPluginInfo *
-      gplugin_native_basic_plugin_query(GError **error) {
-          /* Authors is a list of authors who worked on the plugin.  Generally
-           * these are in the "Name Surname &lt;user@domain.com&gt;" format.
-           */
-          const gchar * const authors[] = {
-              "Author O &lt;author@example.com&gt;",
-              NULL
-          };
+/* This function is called by the native plugin loader to get information about
+ * the plugin. It returns a #GPluginPluginInfo instance that describes the
+ * plugin. If anything goes wrong during this function, @error should be set
+ * via g_set_error() and %NULL should be returned. It must match the
+ * signature of GPluginNativePluginQueryFunc, and it will be passed to
+ * GPLUGIN_NATIVE_PLUGIN_DECLARE which will export it properly.
+ */
+static GPluginPluginInfo *
+gplugin_native_basic_plugin_query(GError **error) {
+	/* Authors is a list of authors who worked on the plugin.  Generally
+	 * these are in the "Name Surname <user@domain.com>" format.
+	 */
+	const gchar * const authors[] = {
+		"Author O <author@example.com>",
+		NULL
+	};
 
-          /* gplugin_plugin_info_new only requires that the id be set, and the
-           * rest are here for demonstration purposes.
-           */
-          return gplugin_plugin_info_new(
-              "gplugin/native-basic-plugin",
-              GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
-              "name", "name",
-              "version", "version",
-              "summary", "summary",
-              "description", "description",
-              "authors", authors,
-              "website", "website",
-              NULL);
-      }
+	/* gplugin_plugin_info_new only requires that the id be set, and the
+	 * rest are here for demonstration purposes.
+	 */
+	return gplugin_plugin_info_new(
+		"gplugin/native-basic-plugin",
+		GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
+		"name", "name",
+		"version", "version",
+		"summary", "summary",
+		"description", "description",
+		"authors", authors,
+		"website", "website",
+		NULL);
+}
 
-      /* This function is called by the native plugin loader when the plugin
-       * should be loaded. It should do any setup that the plugin requires and
-       * return %TRUE if everything was successfull. If not, it should set
-       * @error with g_set_error() and return %FALSE. This function needs to
-       * match the signature of #GPluginNativePluginLoadFunc, and it will be
-       * passed to #GPLUGIN_NATIVE_PLUGIN_DECLARE which will export it
-       * properly.
-       */
-      static gboolean
-      gplugin_native_basic_plugin_load(GPluginPlugin *plugin, GError **error) {
-          return TRUE;
-      }
+/* This function is called by the native plugin loader when the plugin should
+ * be loaded. It should do any setup that the plugin requires and return %TRUE
+ * if everything was successful. If not, it should set @error with
+ * g_set_error() and return %FALSE. This function needs to match the
+ * signature of GPluginNativePluginLoadFunc, and it will be passed to
+ * GPLUGIN_NATIVE_PLUGIN_DECLARE which will export it properly.
+ */
+static gboolean
+gplugin_native_basic_plugin_load(GPluginPlugin *plugin, GError **error) {
+	return TRUE;
+}
 
-      /* This function is called by the native plugin loader when the plugin
-       * should be unloaded. It should do any clean up that the plugin requires
-       * and return %TRUE if everything was successfull. If not, it should set
-       * @error with g_set_error() and return %FALSE. This function needs to
-       * match the signature of #GPluginNativePluginUnloadFunc, and it will be
-       * passed to #GPLUGIN_NATIVE_PLUGIN_DECLARE which will export it
-       * properly.
-       */
-      static gboolean
-      gplugin_native_basic_plugin_unload(GPluginPlugin *plugin, GError *error) {
-          return TRUE;
-      }
+/* This function is called by the native plugin loader when the plugin should
+ * be unloaded. It should do any clean up that the plugin requires and return
+ * %TRUE if everything was successful. If not, it should set @error with
+ * g_set_error() and return %FALSE. This function needs to match the signature
+ * of GPluginNativePluginUnloadFunc, and it will be passed to
+ * GPLUGIN_NATIVE_PLUGIN_DECLARE which will export it properly.
+ */
+static gboolean
+gplugin_native_basic_plugin_unload(GPluginPlugin *plugin, GError *error) {
+	return TRUE;
+}
 
-      /* This macro does the heavy lifting of making sure to export all of the
-       * symbols correctly as well as add some future proofing for features
-       * like statically plugins. It is highly recommended to use this macro
-       * instead of manually exporting the symbols yourself.
-       */
-      GPLUGIN_NATIVE_PLUGIN_DECLARE(gplugin_native_basic_plugin)
-      </programlisting></informalexample>
-    </para>
-  </simplesect>
-</chapter>
+/* This macro does the heavy lifting of making sure to export all of the
+ * symbols correctly as well as add some future proofing for features like
+ * statically linking plugins. It is highly recommended to use this macro
+ * instead of manually exporting the symbols yourself.
+ */
+GPLUGIN_NATIVE_PLUGIN_DECLARE(gplugin_native_basic_plugin)
+```
+
diff --git a/gplugin/reference/perl5.xml b/gplugin/reference/perl5.md
rename from gplugin/reference/perl5.xml
rename to gplugin/reference/perl5.md
--- a/gplugin/reference/perl5.xml
+++ b/gplugin/reference/perl5.md
@@ -1,60 +1,46 @@
-<?xml version='1.0' encoding="UTF-8"?>
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
-              "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
-]>
-<chapter id="chapter-perl5">
-	<title>Perl5 Plugins</title>
+Title: Perl5 Plugins
+Slug: perl5
+
+## Perl5 Plugins
+
+> You **MUST** have the Perl5 loader plugin installed and working as well as
+> the gobject-introspection package for GPlugin installed to use Perl5 plugins.
+
+### Example Perl5 Plugin
 
-	<warning>
-		<para>
-			You <emphasis role="strong">MUST</emphasis> have the Perl5 loader
-			plugin installed and working as well as the gobject-introspection
-			package for GPlugin installed to use Perl5 plugins.
-		</para>
-	</warning>
+Like all plugins in GPlugin, Perl5 plugins must also implement the
+`gplugin_query`, `gplugin_load`, and `glugin_unload` functions.
+
+The following is a basic Perl5 plugin.
 
-	<simplesect>
-		<title>Example Perl5 Plugin</title>
+```perl
+use strict;
 
-		<para>
-			Like all plugins in GPlugin, Perl5 plugins must also implement
-			the <code>gplugin_query</code>, <code>gplugin_load</code>, and
-			<code>gplugin_unload</code> functions.
-		</para>
+use Glib::Object::Introspection;
 
-		<para>
-			The following is a basic Perl5 plugin.
-		</para>
+Glib::Object::Introspection->setup(basename => "GPlugin", version => "1.0", package=> "GPlugin");
 
-		<informalexample><programlisting>
-		use strict;
-
-		use Glib::Object::Introspection;
-
-		Glib::Object::Introspection->setup(basename => "GPlugin", version => "1.0", package=> "GPlugin");
+sub gplugin_query {
+	return GPlugin::PluginInfo->new(
+		id => "gplugin/perl5-basic-plugin",
+		abi_version => 0x01020304,
+		name => "basic plugin",
+		authors => ("author1"),
+		category => "test",
+		version => "version",
+		license_id => "license",
+		summary => "summary",
+		website => "website",
+		description => "description",
+	);
+}
 
-		sub gplugin_query {
-			return GPlugin::PluginInfo->new(
-				id => "gplugin/perl5-basic-plugin",
-				abi_version => 0x01020304,
-				name => "basic plugin",
-				authors => ("author1"),
-				category => "test",
-				version => "version",
-				license_id => "license",
-				summary => "summary",
-				website => "website",
-				description => "description",
-			);
-		}
+sub gplugin_load {
+	return 0;
+}
 
-		sub gplugin_load {
-			return 0;
-		}
+sub gplugin_unload {
+	return 0;
+}
+```
 
-		sub gplugin_unload {
-			return 0;
-		}
-		</programlisting></informalexample>
-	</simplesect>
-</chapter>
diff --git a/gplugin/reference/python3.xml b/gplugin/reference/python3.md
rename from gplugin/reference/python3.xml
rename to gplugin/reference/python3.md
--- a/gplugin/reference/python3.xml
+++ b/gplugin/reference/python3.md
@@ -1,56 +1,43 @@
-<?xml version='1.0' encoding="UTF-8"?>
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
-              "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
-]>
-<chapter id="chapter-python">
-	<title>Python Plugins</title>
+Title: Python3 Plugins
+Slut: python3
+
+## Python3 Plugins
+
+> You **MUST** have the Python3 loader plugin installed and working as well as
+> the gobject-introspection package for GPlugin installed to use Python3
+> plugins.
+
+### Example Python Plugin
 
-	<warning>
-		<para>
-			You <emphasis role="strong">MUST</emphasis> have the Python loader
-			plugin installed and working as well as the gobject-introspection
-			package for GPlugin installed to use Python plugins.
-		</para>
-	</warning>
+Like all plugins in GPlugin, Python plugins must also implement the
+`gplugin_query`, `gplugin_load`, and `gplugin_unload` functions.
+
+The following is a basic Python plugin.
 
-	<simplesect>
-		<title>Example Python Plugin</title>
+```python
+import gi
 
-		<para>
-			Like all plugins in GPlugin, Python plugins must also implement
-			the <code>gplugin_query</code>, <code>gplugin_load</code>, and
-			<code>gplugin_unload</code> functions.
-		</para>
-
-		<para>
-			The following is a basic Python plugin.
-		</para>
+gi.require_version("GPlugin", "0.0")
+from gi.repository import GPlugin
 
-		<informalexample><programlisting>
-		import gi
-
-		gi.require_version("GPlugin", "0.0")
-		from gi.repository import GPlugin
+def gplugin_plugin_query():
+    return GPlugin.PluginInfo(
+        id="gplugin-python/basic-plugin",
+        abi_version=0x01020304,
+        name="basic plugin",
+        authors=["author1"],
+        category="test",
+        version="version",
+        license_id="license",
+        summary="summary",
+        website="website",
+        description="description",
+    )
 
-		def gplugin_plugin_query():
-		    return GPlugin.PluginInfo(
-		        id="gplugin-python/basic-plugin",
-		        abi_version=0x01020304,
-		        name="basic plugin",
-		        authors=["author1"],
-		        category="test",
-		        version="version",
-		        license_id="license",
-		        summary="summary",
-		        website="website",
-		        description="description",
-		    )
+def gplugin_plugin_load(plugin):
+    return True
 
-		def gplugin_plugin_load(plugin):
-		    return True
+def gplugin_plugin_unload(plugin):
+    return True
+```
 
-		def gplugin_plugin_unload(plugin):
-		    return True
-		</programlisting></informalexample>
-	</simplesect>
-</chapter>
diff --git a/gplugin/reference/urlmap.js b/gplugin/reference/urlmap.js
new file mode 100644
--- /dev/null
+++ b/gplugin/reference/urlmap.js
@@ -0,0 +1,9 @@
+// SPDX-FileCopyrightText: 2021 GNOME Foundation
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
+// A map between namespaces and base URLs for their online documentation
+baseURLs = [
+    [ 'GLib', 'https://docs.gtk.org/glib/' ],
+    [ 'GObject', 'https://docs.gtk.org/gobject/' ],
+    [ 'GModule', 'https://docs.gtk.org/gmodule/' ],
+]
diff --git a/gplugin/reference/vala.xml b/gplugin/reference/vala.md
rename from gplugin/reference/vala.xml
rename to gplugin/reference/vala.md
--- a/gplugin/reference/vala.xml
+++ b/gplugin/reference/vala.md
@@ -1,75 +1,59 @@
-<?xml version='1.0' encoding="UTF-8"?>
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
-              "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
-]>
-<chapter id="chapter-vala">
-	<title>Vala Plugins</title>
+Title: Vala Plugin Example
+Slug: vala
+
+## Vala Plugins
 
-	<warning>
-		<para>
-			You <emphasis role="strong">MUST</emphasis> have the Vala bindings
-			installed on your system for this to work.  They are built by
-			default.
-		</para>
-	</warning>
+> You **MUST** have the Vala bindings installed on your system for this to
+> work. They are built by the default GPlugin build.
 
-	<simplesect>
-		<title>Example Vala Plugin</title>
+### Example Vala Plugin
 
-		<para>
-			Like all plugins in GPlugin, Vala plugins must also implement
-			the <code>gplugin_query</code>, <code>gplugin_load</code>, and
-			<code>gplugin_unload</code> functions.
-		</para>
+Like all plugins in GPlugin, Vala plugins must also implement the
+`gplugin_query`, `gplugin_load`, and `gplugin_unload` functions.
+
+Due to the way `GPlugin.PluginInfo` info works, you must subclass it and set
+your values in the new constructor.
 
-		<para>
-			Due to the way <code>GPlugin.PluginInfo</code> info works, you must
-			subclass it and set your values in the new constructor.
-		</para>
+The following is a basic Vala plugin.
 
-		<para>
-			The following is a basic Vala plugin.
-		</para>
+```vala
+using GPlugin;
 
-		<informalexample><programlisting>
-		using GPlugin;
+public class BasicPluginInfo : GPlugin.PluginInfo {
+	public BasicPluginInfo() {
+		string[] authors = {"author1"};
 
-		public class BasicPluginInfo : GPlugin.PluginInfo {
-			public BasicPluginInfo() {
-				string[] authors = {"author1"};
-
-				Object(
-					id: "gplugin/vala-basic-plugin",
-					abi_version: 0x01020304,
-					name: "basic plugin",
-					authors: authors,
-					category: "test",
-					version: "version",
-					license_id: "license",
-					summary: "summary",
-					website: "website",
-					description: "description"
-				);
-			}
-		}
+		Object(
+			id: "gplugin/vala-basic-plugin",
+			abi_version: 0x01020304,
+			name: "basic plugin",
+			authors: authors,
+			category: "test",
+			version: "version",
+			license_id: "license",
+			summary: "summary",
+			website: "website",
+			description: "description"
+		);
+	}
+}
 
-		public GPlugin.PluginInfo gplugin_query(out Error error) {
-			error = null;
+public GPlugin.PluginInfo gplugin_query(out Error error) {
+	error = null;
 
-			return new BasicPluginInfo();
-		}
+	return new BasicPluginInfo();
+}
 
-		public bool gplugin_load(GPlugin.Plugin plugin, out Error error) {
-			error = null;
+public bool gplugin_load(GPlugin.Plugin plugin, out Error error) {
+	error = null;
 
-			return true;
-		}
-
-		public bool gplugin_unload(GPlugin.Plugin plugin, out Error error) {
-			error = null;
+	return true;
+}
 
-			return true;
-		}
-		</programlisting></informalexample>
-	</simplesect>
-</chapter>
+public bool gplugin_unload(GPlugin.Plugin plugin, out Error error) {
+	error = null;
+
+	return true;
+}
+```
+
diff --git a/gplugin/reference/version.xml.in b/gplugin/reference/version.xml.in
deleted file mode 100644
--- a/gplugin/reference/version.xml.in
+++ /dev/null
@@ -1,1 +0,0 @@
-@GPLUGIN_VERSION@
diff --git a/meson.build b/meson.build
--- a/meson.build
+++ b/meson.build
@@ -78,7 +78,18 @@
 ###############################################################################
 # gtk-doc
 ###############################################################################
-ENABLE_DOC = get_option('doc')
+if get_option('doc') and not get_option('introspection')
+	error('Documentation requires GObject Introspection.')
+endif
+
+gidocgen_dep = dependency(
+	'gi-docgen', version: '>= 2021.1',
+	fallback: ['gi-docgen', 'dummy_dep'],
+	required: get_option('doc')
+)
+
+gidocgen = find_program('gi-docgen', required : get_option('doc'))
+docs_dir = get_option('prefix') / get_option('datadir') / 'doc'
 
 ###############################################################################
 # Subdirectories
@@ -97,7 +108,7 @@
 subdir('tcc')
 subdir('vala')
 
-if ENABLE_DOC
+if get_option('doc')
 	doc_targets = [gplugin_doc]
 	if get_option('gtk3')
 		doc_targets += gplugin_gtk_doc
@@ -114,7 +125,7 @@
 	install_dir : get_option('datadir') / 'doc' / 'gplugin')
 
 summary({
-	'gtk-doc' : get_option('doc'),
+	'api reference' : get_option('doc'),
 	'gtk3 widgets' : get_option('gtk3'),
 	'man pages' : get_option('help2man'),
 }, bool_yn : true, section : 'Miscellaneous')
diff --git a/subprojects/gi-docgen.wrap b/subprojects/gi-docgen.wrap
new file mode 100644
--- /dev/null
+++ b/subprojects/gi-docgen.wrap
@@ -0,0 +1,6 @@
+[wrap-git]
+directory=gi-docgen
+url=https://gitlab.gnome.org/GNOME/gi-docgen.git
+push-url=ssh://git@gitlab.gnome.org:GNOME/gi-docgen.git
+revision=main
+depth=1
