
Melanjutkan topik penggunaan Asciidoc (dan format serupa lainnya) untuk mengatur proses dokumentasi berkelanjutan, saya ingin mempertimbangkan topik pembuatan dokumentasi teknis otomatis.
Pembuatan dokumentasi otomatis adalah istilah yang umum tetapi sangat kabur. Saya mengerti dengan ekstraksi istilah ini untuk presentasi dalam bentuk informasi yang nyaman yang terkandung dalam kode sumber dan pengaturan program yang didokumentasikan (sistem informasi).
Skema umum pembuatan dokumentasi otomatis
, , βββ . .
- . , . , - , , , , . βββ , JSON/YAML XML;
- ( Asciidoc, DITA, Docbook, Markdown, reStructuredText).
, (html, docx, odt, pdf ..) ( ) . , ? , . .
:

, -. Asciidoc, (reStructuredText, Markdown), ( kroki, ).
. .
, , ( Javadoc, ReST ..) .
.
(, , ..), .
. βββ. , Junit xml report. , , , βββAllure Framework.
, JSON-, Cucumber, , .
, ,βββ . , .
(, xsd-, OpenAPI, DSL , ).
, , ( Β«flattenΒ»).
( ) , .
βββ
, .
create table geo.Strana ( id int , naimenovaniye varchar(255) , primary key (id) ); create table geo.Gorod ( id int , naimenovaniye varchar(255) , strana_id int , constraint strana_gorod foreign key (strana_id) references geo.Strana(id) );
( PostgreSQL): JSON- .
drop table if exists fk; select x.table_schema as table_schema , x.table_name , y.table_schema as foreign_table_schema , y.table_name as foreign_table_name into temp fk from information_schema.referential_constraints rc join information_schema.key_column_usage x on x.constraint_name = rc.constraint_name join information_schema.key_column_usage y on y.ordinal_position = x.position_in_unique_constraint and y.constraint_name = rc.unique_constraint_name;
select json_agg(json_build_object( 'name', t.table_schema || '.' || t.table_name , 'columns' , (select json_agg(json_build_object ( 'name', column_name ,'type', data_type )) from information_schema.columns as c where c.table_name = t.table_name and c.table_schema = t.table_schema ) , 'fk' , (select json_agg(json_build_object ( 'fk_table' , fk.foreign_table_schema || '.' || fk.foreign_table_name )) from fk where fk.table_name = t.table_name and fk.table_schema = t.table_schema ) )) from information_schema.tables as t where table_schema = 'geo';
JSON-:
[{ "name": "geo.Strana", "columns": [{ "name": "id", "type": "integer" }, { "name": "naimenovaniye", "type": "character varying" } ], "fk": null }, { "name": "geo.Gorod", "columns": [{ "name": "id", "type": "integer" }, { "name": "naimenovaniye", "type": "character varying" }, { "name": "strana_id", "type": "integer" } ], "fk": [{ "fk_table": "geo.Strana" } ] } ]
, .
, , .
, , 2003 XSLT , , Ruby. 18 , , XSLT , .
Liquid JSON XSLT XML. Ruby, (1) AsciidocβββAsciidoctorβββ Ruby (2) Ruby- java javascript, .
JSON-
JSON-.
PlantUML:
{% assign bl = "\n" %} {%- for table in data -%} class {{ table.name }}{{ bl }} {%- for fk in table.fk -%} {{ table.name }} "*" -- "1" {{ fk.fk_table }}{{ bl }} {%- endfor -%} {%- endfor -%}
, . PlantUML class [ ]
. .
:
class geo.Strana class geo.Gorod geo.Gorod "*" -- "1" geo.Strana
Asciidoc:
{% assign bl = "\n" %}{% assign bbl = "\n\n" %} {%- for table in data -%} [[{{ table.name }}]]{{- bl -}} . {{ table.name }}{{- bl -}} [cols="1,3,3", options="header"]{{- bl -}} |==={{- bl -}} |β | | {{ bl }} {%- for column in table.columns -%} |{counter:{{ table.name }}} |{{ column.name }} |{{ column.type }}{{- bl -}} {%- endfor -%} {%- if table.fk -%} 3+a| :{{- bbl -}} {%- for fk in table.fk -%} * <<{{fk.fk_table}}, {{fk.fk_table}}>>{{- bl -}} {%- endfor -%} {%- endif -%} |==={{- bbl -}} {%- endfor -%}
include:
= :lang: ru :figure-caption: :xrefstyle: short :sectnums: == (<<struktura>>). [[struktura]] . [plantuml, struktura, png, fitrect="170x240mm", srcdpi=300, width="50%"] .... skinparam dpi 300 left to right direction include::pu_sql.pu[] .... == include::adoc_sql.adoc[]
Asciidoc Asciidoc . Asciidoc . , . - ( , , ..).

,
XML-.
( xsd ) 3βββhttps://smev3.gosuslugi.ru/portal/inquirytype_one.jsp?id=41108&zone=fed. :
<ns1: =" 5087746429843" =" 5087746429843"> <ns1: ="5087746429843" ="2008-11-18"/> </ns1:> <ns1:> <ns1: ="77" ="770000000002990" ="7" ="6"> <fnst: ="" =""/> <fnst: ="" =" 2-"/> <fnst: ="5087746429843" ="2008-11-18"/> </ns1:> </ns1:>
, , xsd.
Asciidoc :
<stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform" xmlns:ep="uri:asciidoc:doc:automation" extension-element-prefixes="ep"> <output method="text" /><strip-space elements="*"/> <template match="/"><apply-templates/></template> <template match="*[count(@*|*) > 0 and count(ancestor::*) > 0]"> <value-of select="'\n='"/> <for-each select="ancestor::*"><value-of select="'='"/></for-each> <value-of select="' '"/> <value-of select="concat('{',local-name(),'}')"/><text>\n\n</text> <text>|===\n</text> <for-each select="(@*)|(*[./text()])"> <text>|</text><value-of select="concat('{',local-name(),'}')"/> <text>|</text><value-of select="ep:iformat(current())"/> <text>\n</text> </for-each> <text>|===\n</text> <apply-templates/> </template> <template match="text()"/> </stylesheet>
. , . βββ . , Asciidoc |
.
XML- βββ Asciidoc. xsd- :
<?xml version="1.0" encoding="UTF-8"?> <stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <output method="text" /> <strip-space elements="*"/> <template match="*[@name]"> <value-of select="concat(':', @name, ': ')"/> <value-of select="normalize-space(xs:annotation/xs:documentation)"/> <text>\n</text> <apply-templates/> </template> <template match="*[not(@name)]"> <apply-templates/> </template> <template match="text()"></template> </stylesheet>
Asciidoc ( , .. xsd) :
:sectnums: include::adoc_egrul_xsd.adoc[] include::adoc_egrul_xsd2.adoc[] include::adoc_egrul.adoc[]
Microsoft Word :

, : , , .
, . , Asciidoc . , . . . XML JSON , . , , .
, , , , , .
, , βββ , , . <strip-space elements="*"/>
<text>\n</text>
. \n
. , - .
Liquid , bl
.
, .
. , XSLT apply-templates
. (template
) .
Asciidoc Asciidoc. , Open API Β«;
Β». . Β«;;
Β» Asciidoc , , , .
, , . βββ iformat
. (zero space) DD.MM.YYYY.
AsciidocDocAutomation = Class.new do def iformat(node) value = node.to_s re = /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/ vm = value.match(re) value = "#{vm[3]}.#{vm[2]}.#{vm[1]}" if !!(value =~ re) "​#​" end end
Untuk sepenuhnya menonaktifkan sintaks Asciidoc dalam nilai yang disisipkan, cukup keluar dari nilai tersebut.
kesimpulan
- Teknologi untuk pembuatan dokumentasi otomatis telah dikembangkan dan dapat digunakan secara efektif dalam proyek TI dengan kompleksitas apa pun.
- Bahasa markup Asciidoc berteknologi maju untuk digunakan dalam tugas pembuatan dokumentasi secara otomatis.
Dan pengumuman: artikel berikutnya akan dikhususkan untuk masalah jaminan kualitas dokumentasi dalam format Asciidoc.