Generación automática de documentación técnica

dmgtlqavf9vvl30g8hbtnyirxjo







Continuando con el tema del uso de Asciidoc (y otros formatos similares) para organizar procesos de documentación continua, quiero considerar el tema de la generación automática de documentación técnica.







La generación automática de documentación es un término común pero muy vago. Entiendo por este término extracción para presentación en una forma conveniente de información contenida en el código fuente y la configuración del programa documentado (sistema de información).







Esquema general de generación automática de documentación



, ,  —  . .







  • . , . , - , , , , .  —  , JSON/YAML XML;
  • ( Asciidoc, DITA, Docbook, Markdown, reStructuredText).


, (html, docx, odt, pdf ..) ( ) . , ? , . .







:







g mxjdbl4ya0quccx1iizd2ecai







, -. 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"
            }
        ]
    }
]
      
      





, .









,

. , .







, , .







( ) XSLT.  — Mustache.







. , Excel ods .







, , 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 . , . - ( , , ..).







Microsoft Word , .







ehijqkjfk8e64ogx3zo5aomx63u







,



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 :







mjh 6 n36odw71vbmj itjbnis0









, : , , .







, . , 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)
    "&#8203;#&#8203;"
  end
end
      
      





Para deshabilitar completamente la sintaxis de Asciidoc en los valores insertados, simplemente escapéelos.







conclusiones



  • Se han desarrollado tecnologías para la generación automática de documentación y se pueden utilizar eficazmente en proyectos de TI de cualquier complejidad.
  • El lenguaje de marcado Asciidoc está tecnológicamente avanzado para su uso en tareas de generación automática de documentación.


Y un anuncio: el próximo artículo estará dedicado a las cuestiones de garantía de calidad de la documentación en formato Asciidoc.








All Articles