Génération automatique de documentation technique

dmgtlqavf9vvl30g8hbtnyirxjo







Poursuivant le sujet de l'utilisation d'Asciidoc (et d'autres formats similaires) pour organiser des processus de documentation en continu, je souhaite aborder le sujet de la génération automatique de documentation technique.







La génération automatique de documentation est un terme courant mais très vague. J'entends par ce terme extraction pour présentation sous une forme pratique des informations contenues dans le code source et les paramètres du programme documenté (système d'information).







Schéma général de génération automatique de documentation



, ,  —  . .







  • . , . , - , , , , .  —  , 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
      
      





Pour désactiver complètement la syntaxe Asciidoc dans les valeurs insérées, il suffit de les échapper.







conclusions



  • Des technologies de gĂ©nĂ©ration automatique de documentation ont Ă©tĂ© dĂ©veloppĂ©es et peuvent ĂŞtre utilisĂ©es efficacement dans des projets informatiques de toute complexitĂ©.
  • Le langage de balisage Asciidoc est technologiquement avancĂ© pour une utilisation dans des tâches de gĂ©nĂ©ration automatique de documentation.


Et une annonce : le prochain article sera consacré aux problématiques d'assurance qualité de la documentation au format Asciidoc.








All Articles