Skip to content
Permalink
Browse files

i5 Support diagrams, inheritable pzdcdoc.xml, Gradle config two demos

  • Loading branch information...
Pingvin235 committed Oct 3, 2019
1 parent fab1a03 commit 7d8109b228817254f49b0ae26ef1aca12494efd0
Showing with 124 additions and 46 deletions.
  1. +42 −23 README.adoc
  2. +23 −4 build.gradle
  3. +3 −3 pzdcdoc.xml
  4. +22 −1 src/doc/demo.adoc
  5. +7 −0 src/doc/index.adoc
  6. +6 −0 src/doc/pzdcdoc.xml
  7. +21 −15 src/main/java/org/pzdcdoc/DocGenerator.java
@@ -6,6 +6,19 @@ Java binding of the excellent software documentation framework link:https://asci
Additionally to the information below you may have a look on the link:https://docs.google.com/presentation/d/1MEIMT9SEnepZdLMVFv2Koev3TILRGn_cNgdT25eS-Zg/edit?usp=sharing[Presentation]

== About
PzdcDoc is the complex ready-to-use solution, providing clear way and workflow for organizing software documentation.
On top of AsciiDoctor there are added the following features:
[square]
* Delivered as a single Java artifact in Maven repository for simple integration in existing build processes.
* Building documentation out of many files structured in original way with ToC.
* Preserving structure, preview of documentation is <<src/doc/demo.adoc#, available>> in GitLab and GitHub.
* Internal references checking, no more broken links.
* Produce embedded JS search over EN, RU and DE using link:https://lunrjs.com/[LunrJS].
* <<src/doc/demo#diagrams, Diagrams>> generation.
* Extension for referencing of JavaDoc by class name.
* CSS enhancements.

=== History
Initially this tool was developed for the link:https://bgerp.org[BGERP], project of Open Source ERP/CRM system.
It was successfully used there as one system with GIT stored sources for support of:
[square]
@@ -16,36 +29,42 @@ It was successfully used there as one system with GIT stored sources for support
The single tool has replaced Confluence + MediaWiki + self-written DB structure describing utility in a more convenient way.
Ideally fits for continuous delivery approach, when documentation is considered as essential part of product and written,
stored, handled together with other sources. Documentation is automatically built using GitLab CI and published,
you may see the result link:https://bgerp.ru/doc/3.0/manual/[here].
you may see the result link:https://bgerp.ru/doc/3.0/manual/[here].

=== The key features
[square]
* Delivered as a single Java artifact in Maven repository for simple integration in existing build processes.
* Building documentation out of many files structured in original way with ToC.
* Preserving structure, preview of documentation is <<src/doc/demo.adoc#, available>> in GitLab and GitHub.
* Produce embedded JS search over EN, RU and DE using link:https://lunrjs.com/[LunrJS].
* Internal references checking, no more broken links.
* Extension for referencing of JavaDoc by class name.
* CSS enhancements.
== Demo
Clone the GIT repository, after execute in the directory one of the following tests.
You would need Java version 8 or higher.
Both produce result to `target/doc-out`, these files may be published on HTTP server.

== Logic
=== Simple test with local files
[source]
----
gradlew
----

Default task `buildDemoDocLocal` uses `src/doc` directory as an input and compiles classes from sources.
Good for first start and testing changes.

=== Complex test with checking out GIT
[source]
----
gradlew buildDemoDoc
----

Extracts the project data from GIT and uses Maven artifact of PzdcDoc for running.
That sample suits for integrating to other projects.
You may see the result here: http://pzdcdoc.org/demo

== How does it work
[square]
* As parameter generator takes input and output directories.
* Input directory may be taken directly from project or checked out from version control to outside like `target`.
* Input directory may be copied directly from project or checked out from version control to outside like `target`.
First way is easier, in the second one may be combined doc sources out of many GIT projects.
* In the input directory mast be placed `index.adoc` with table of contents.
* In the input directory may be placed `pzdcdoc.xml` file with different parameters.
AsciiDoctor attributes from the file are included in all of converted `.adoc` files.
In the input directory may be placed:
* `index.adoc` with table of contents. Only one index on the highest level will be used.
* `pzdcdoc.xml` file with AsciiDoctor attributes, these will be implicitly included in each of `.adoc` file starting from the directory, where `pzdcdoc.xml` is placed. This means, that this configuration is inherited and may be overwritten.
* The generator goes through all the files in input dir and converting all with extension `.adoc` them to `.html`.
** Directory starting from `.` are skipped.
** Includes have to be named `.adocf` to avoid converting.
** Resources (files, images) must be placed in `_res` subdirectory near of referencing `.adoc` file, they are automatically copied.
* All the used references between `.adoc` are relative and automatically converted to HTML.

== How to test
Clone the GIT repository, after execute in the directory:
[source]
----
gradlew buildDemoDoc
----
That will build result to `target/doc-out`, these files may be published on HTTP server.
@@ -22,7 +22,9 @@ sourceCompatibility = 1.8
targetCompatibility = 1.8

ext.admin = hasProperty('sonatypeUsername')
ext.docBranch = project.hasProperty('docBranch') ? project.findProperty('docBranch') : 'master'
ext.docSrcDir = "${buildDir}/doc-src"
ext.docOutDir = "${buildDir}/doc-out"

eclipse {
classpath {
@@ -54,6 +56,7 @@ dependencies {
compile group: 'org.jsoup', name: 'jsoup', version: '1.11.3'
compile group: 'org.asciidoctor', name: 'asciidoctorj', version: '2.1.0'
compile group: 'org.asciidoctor', name: 'asciidoctorj-api', version: '2.1.0'
compile group: 'org.asciidoctor', name: 'asciidoctorj-diagram', version: '1.5.18'
compile group: 'com.beust', name: 'jcommander', version: '1.78'
compile group: 'org.jruby', name: 'jruby-complete', version: '9.2.8.0'
compile group: 'org.dom4j', name: 'dom4j', version: '2.1.1'
@@ -74,14 +77,30 @@ tasks.withType(Javadoc) {
options.encoding = 'UTF-8'
}

task checkoutDemoDoc(type: Exec, dependsOn: clean) {
commandLine 'git', 'clone', 'https://github.com/pzdcdoc/pzdcdoc.git', docSrcDir, '--depth', '1', '--branch', 'master'
defaultTasks 'clean', 'buildDemoDocLocal'

task copyDemoDocLocal(type: Copy) {
mustRunAfter 'clean'
from 'src/doc'
into docSrcDir
}

task buildDemoDocLocal(type:JavaExec, dependsOn: ['compileJava', 'copyDemoDocLocal']) {
classpath = sourceSets.main.runtimeClasspath
main = 'org.pzdcdoc.DocGenerator'
args 'NOTUSED', docSrcDir, docOutDir
}

task checkoutDemoDoc(type: Exec, dependsOn: ['clean']) {
commandLine 'git', 'clone', 'https://github.com/pzdcdoc/pzdcdoc.git', docSrcDir, '--depth', '1', '--branch', "${docBranch}"
}

task buildDemoDoc(type:JavaExec, dependsOn: ['checkoutDemoDoc']) {
// Sample of generation out of branch:
// gradlew buildDemoDoc -PdocBranch=i5-diagrams
task buildDemoDoc(type:JavaExec, dependsOn: ['checkoutDemoDoc', 'publishToMavenLocal']) {
classpath = configurations.pzdcdoc
main = 'org.pzdcdoc.DocGenerator'
args 'NOTUSED', docSrcDir, 'target/doc-out'
args 'NOTUSED', docSrcDir, docOutDir
}

task sourceJar(type: Jar) {
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- configuration file, may be placed in the same directory with root index.adoc file -->
<!-- configuration file, may be placed in the same directory with .adoc file -->
<pzdcdoc>
<!-- these attributes applied to each of processed files, may be overvritten inside -->
<!-- these attributes applied to each of processed files, may be extended/overvritten in deeper pzdcdoc.xml files and inside the files themself -->
<attributes>
<doc-path>src/doc</doc-path>

<favicon>https://bgerp.ru/img/favicon.png</favicon>
<pzdc-javadoc>http://www.bgcrm.ru/doc/3.0/javadoc/</pzdc-javadoc>

<!-- sample of labels customization
https://asciidoctor.org/docs/user-manual/#customizing-labels
https://github.com/asciidoctor/asciidoctor/blob/master/lib/asciidoctor/document.rb#L255
@@ -112,7 +112,7 @@ Big images may be restricted by width, recommended 600px for horizontal oriented

image::_res/image.png[width="600px"]

Link to JavaDoc of the class: javadoc:ru.bgerp.tool.asciidoc.DocGenerator[]
Link to JavaDoc of the class: javadoc:ru.bgcrm.dao.user.UserDAO[]

Another document: <<module/index.adoc#, Module>>

@@ -132,6 +132,27 @@ Such link causes a validation error, may be used for marking not finished places
For any selection except of links use bold font:
*variable*, *path*, *parameter*, *interface => menu => item*

[[diagrams]]
== Diagrams
Supported Ditaa and PlantUML diagrams.
[square]
* https://asciidoctor.org/docs/asciidoctor-diagram/
* https://asciidoctor.org/news/2014/02/18/plain-text-diagrams-in-asciidoctor/

=== Ditaa
http://ditaa.sourceforge.net/

Use http://asciiflow.com/ for editing.

[ditaa]
----
+------------------+ +---------------+
| | | |
| Test for Adoc +------>+ Diagrams |
| | | |
+------------------+ +---------------+
----

== Tools
AsciiDoctor may be edited in any text editor, but as more comfortable way I use an Eclipse plugin.

@@ -0,0 +1,7 @@
= Demo Local ToC
:nofooter:

* <<demo.adoc#, Demo AsciiDoctor>>
* Modules
** <<module/index.adoc#, Module>>
* <<changes.adoc#, Last changes>>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<pzdcdoc>
<attributes>
<pzdc-javadoc>http://bgerp.ru/doc/3.0/javadoc/</pzdc-javadoc>
</attributes>
</pzdcdoc>
@@ -54,9 +54,6 @@

// cached ToC from index.adoc for injecting everywhere
private Element toc;
// global attributes from configuration file
private Map<String, Object> attributes;
//
private Search search = new Search();

public DocGenerator(String configDir, String sourceDir, String targetDir) throws Exception {
@@ -66,12 +63,14 @@ public DocGenerator(String configDir, String sourceDir, String targetDir) throws

JavaExtensionRegistry javaExtensionRegistry = asciidoctor.javaExtensionRegistry();
javaExtensionRegistry.inlineMacro(new JavaDocLink());

asciidoctor.requireLibrary("asciidoctor-diagram");

FileUtils.deleteDirectory(new File(targetDir));
}

public void process() throws Exception {
process(sourceDir, targetDir, -1, false);
process(sourceDir, targetDir, -1, false, new HashMap<>());
copyScriptsAndStyles();
}

@@ -82,7 +81,7 @@ public int check() throws Exception {
return errors;
}

public void process(File source, File target, int depth, boolean resource) throws Exception {
public void process(File source, File target, int depth, boolean resource, Map<String, Object> attributes) throws Exception {
final String sourceName = source.getName();

// hidden resources, names started by .
@@ -110,19 +109,19 @@ public void process(File source, File target, int depth, boolean resource) throw
return 1;
return 0;
});

attributes = loadAttributes(source, attributes);

for (File file : files)
process(file, new File(target.getPath() + "/" + file.getName()), depth + 1, resourceDir);
process(file, new File(target.getPath() + "/" + file.getName()), depth + 1, resourceDir, attributes);
} else {
if (sourceName.endsWith(".adoc")) {
log.info("Processing: " + source);

if (containsIndex(sourceName) && attributes == null)
loadAttributes(source);

Attributes attrs = AttributesBuilder.attributes()
.stylesDir(StringUtils.repeat("../", depth) + RES)
.linkCss(true)
.attribute("imagesoutdir", RES)
.sourceHighlighter("coderay")
.icons(Attributes.FONT_ICONS)
.tableOfContents(true)
@@ -131,8 +130,7 @@ public void process(File source, File target, int depth, boolean resource) throw

attrs.setAttribute("last-update-label", "Powered by <a target='_blank' href='http://pzdcdoc.org'>PzdcDoc</a> at: ");

if (attributes != null)
attrs.setAttributes(attributes);
attrs.setAttributes(attributes);

Options options = OptionsBuilder.options()
.toFile(false)
@@ -161,19 +159,20 @@ else if (resource)
}
}

private void loadAttributes(File source) throws DocumentException {
Path configuration = source.toPath().getParent().resolve("pzdcdoc.xml");
private Map<String, Object> loadAttributes(File source, Map<String, Object> attributes) throws DocumentException {
Path configuration = source.toPath().resolve("pzdcdoc.xml");
if (configuration.toFile().exists()) {
log.info("Processing configuration: {}", configuration);
org.dom4j.Document document = new SAXReader().read(configuration.toFile());

attributes = new HashMap<>();
attributes = new HashMap<>(attributes);

for (Node attr : document.selectNodes("//attributes/*"))
attributes.put(attr.getName(), attr.getText());

log.info("Read {} attributes", attributes.size());
}
return attributes;
}

public void copyScriptsAndStyles() throws IOException {
@@ -214,10 +213,18 @@ private String correctHtml(String html, String targetPath, int depth) throws Exc
Document jsoup = Jsoup.parse(html);
Element head = jsoup.selectFirst("head");

// add content to search index
if (search != null) {
final String relativePath = targetDir.toPath().relativize(Paths.get(targetPath)).toString().replace('\\', '/');
search.addArticle(new Search.Article(relativePath, head.select("title").text(), jsoup.text()));
}

// patch diagram images links
for (Element diag : jsoup.select("img[src^=diag]")) {
String src = RES + "/" + diag.attr("src");
log.info("Corrected diagram path to: {}", src);
diag.attr("src", src);
}

// inject JS files
for (String script : SCRIPTS_INJECT)
@@ -254,7 +261,6 @@ private String correctHtml(String html, String targetPath, int depth) throws Exc
}

public static void main(String[] args) throws Exception {
// TODO: Use args4j.
String configDir = args[0], sourceDir = args[1], targetDir = args[2];

DocGenerator gen = new DocGenerator(configDir, sourceDir, targetDir);

0 comments on commit 7d8109b

Please sign in to comment.
You can’t perform that action at this time.