LCOV - code coverage report
Current view: top level - io/source/format - io_md_writer.c (source / functions) Hit Total Coverage
Test: crystal-facet-uml_v1.58.2_covts Lines: 89 89 100.0 %
Date: 2024-05-12 08:28:01 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /* File: io_md_writer.c; Copyright and License: see below */
       2             : 
       3             : #include "format/io_md_writer.h"
       4             : #include "utf8stringbuf/utf8stringview.h"
       5             : #include "u8/u8_trace.h"
       6             : #include "u8/u8_log.h"
       7             : #include <stdio.h>
       8             : #include <stdbool.h>
       9             : #include <assert.h>
      10             : 
      11             : /* Note, this is no full markdown syntax support - but it helps keeping markdown in shape */
      12             : static const char IO_MD_WRITER_LINEBREAK = '\n';
      13             : static const char IO_MD_WRITER_LINK_AS_ID[] = "#id";
      14             : static const char IO_MD_WRITER_LINK_AS_NAME[] = "#name";
      15             : 
      16           3 : void io_md_writer_init ( io_md_writer_t *this_,
      17             :                          data_database_reader_t *db_reader,
      18             :                          const char * tag_linebreak,
      19             :                          const char * tag_xref_start,
      20             :                          const char * tag_xref_middle,
      21             :                          const char * tag_xref_end,
      22             :                          io_xml_writer_t *sink )
      23             : {
      24           3 :     U8_TRACE_BEGIN();
      25           3 :     assert( NULL != db_reader );
      26           3 :     assert( NULL != tag_linebreak );
      27           3 :     assert( NULL != tag_xref_start );
      28           3 :     assert( NULL != tag_xref_middle );
      29           3 :     assert( NULL != tag_xref_end );
      30           3 :     assert( NULL != sink );
      31             : 
      32           3 :     (*this_).db_reader = db_reader;
      33           3 :     (*this_).tag_linebreak = tag_linebreak;
      34           3 :     (*this_).tag_xref_start = tag_xref_start;
      35           3 :     (*this_).tag_xref_middle = tag_xref_middle;
      36           3 :     (*this_).tag_xref_end = tag_xref_end;
      37           3 :     (*this_).sink = sink;
      38             : 
      39           3 :     U8_TRACE_END();
      40           3 : }
      41             : 
      42           3 : void io_md_writer_destroy( io_md_writer_t *this_ )
      43             : {
      44           3 :     U8_TRACE_BEGIN();
      45             : 
      46           3 :     (*this_).sink = NULL;
      47           3 :     (*this_).db_reader = NULL;
      48             : 
      49           3 :     U8_TRACE_END();
      50           3 : }
      51             : 
      52           4 : u8_error_t io_md_writer_transform ( io_md_writer_t *this_, const char *text )
      53             : {
      54           4 :     U8_TRACE_BEGIN();
      55           4 :     assert ( NULL != text );
      56           4 :     assert ( NULL != (*this_).db_reader );
      57           4 :     assert ( NULL != (*this_).sink );
      58             : 
      59           4 :     unsigned int text_start_byte = 0;
      60           4 :     const unsigned int text_byte_length = utf8string_get_length( text );
      61           4 :     u8_error_t write_err = U8_ERROR_NONE;
      62             : 
      63         148 :     for ( unsigned int text_current_byte = 0; text_current_byte < text_byte_length; text_current_byte ++ )
      64             :     {
      65         144 :         const char current = text[text_current_byte];  /* note: only in case current<=0x7f this is a valid code point */
      66         144 :         const char peeknext = text[text_current_byte+1];  /* note: only in case current<=0x7f this is a valid code point, 0 at string end */
      67         144 :         if ( current == IO_MD_WRITER_LINEBREAK )
      68             :         {
      69          12 :             if (( peeknext == IO_MD_WRITER_LINEBREAK )
      70           9 :                 || ( peeknext == '+' )  /* list */
      71           9 :                 || ( peeknext == '*' )  /* list */
      72           9 :                 || ( peeknext == '-' )  /* list or heading */
      73           8 :                 || ( peeknext == '=' )  /* heading */
      74           8 :                 || ( peeknext == '#' )  /* heading */
      75           8 :                 || ( peeknext == '0' )  /* ordered list */
      76           8 :                 || ( peeknext == '1' )  /* ordered list */
      77           8 :                 || ( peeknext == '2' )  /* ordered list */
      78           8 :                 || ( peeknext == '3' )  /* ordered list */
      79           8 :                 || ( peeknext == '4' )  /* ordered list */
      80           7 :                 || ( peeknext == '5' )  /* ordered list */
      81           6 :                 || ( peeknext == '6' )  /* ordered list */
      82           6 :                 || ( peeknext == '7' )  /* ordered list */
      83           6 :                 || ( peeknext == '8' )  /* ordered list */
      84           6 :                 || ( peeknext == '9' )  /* ordered list */
      85           6 :                 || ( peeknext == '>' )  /* citation */
      86             :                 /*|| ( peeknext == ' ' )*/  /* list continuation */
      87           5 :                 || ( peeknext == '|' ))  /* table */
      88             : 
      89             :             {
      90           7 :                 const utf8stringview_t str_view = UTF8STRINGVIEW( &(text[text_start_byte]), text_current_byte-text_start_byte );
      91           7 :                 write_err |= io_xml_writer_write_xml_enc_view( (*this_).sink, &str_view );
      92           7 :                 write_err |= io_xml_writer_write_plain ( (*this_).sink, (*this_).tag_linebreak );
      93           7 :                 text_start_byte = text_current_byte+1;
      94             :             }
      95             :         }
      96         132 :         else if ( current == DATA_TABLE_ALPHANUM_DIAGRAM /* = 'D' */)
      97             :         {
      98             :             /* try to parse an id */
      99             :             data_id_t probe_id;
     100             :             size_t length;
     101          12 :             data_id_init_by_string_region ( &probe_id, text, text_current_byte, &length );
     102          12 :             if ( data_id_is_valid( &probe_id ) )
     103             :             {
     104           5 :                 const bool show_id = utf8string_equals_region_str( text, text_current_byte+length, IO_MD_WRITER_LINK_AS_ID );
     105           5 :                 const bool show_name
     106             :                     = show_id
     107             :                     ? false
     108           5 :                     : utf8string_equals_region_str( text, text_current_byte+length, IO_MD_WRITER_LINK_AS_NAME );
     109             : 
     110           5 :                 if ( show_id || show_name )
     111           3 :                 {
     112             :                     u8_error_t d_err;
     113           3 :                     d_err = data_database_reader_get_diagram_by_id ( (*this_).db_reader, data_id_get_row_id( &probe_id ), &((*this_).temp_diagram) );
     114           3 :                     if ( d_err == U8_ERROR_NONE )
     115             :                     {
     116             :                         /* write previously parsed characters */
     117           2 :                         const utf8stringview_t str_view = UTF8STRINGVIEW( &(text[text_start_byte]), text_current_byte-text_start_byte );
     118           2 :                         write_err |= io_xml_writer_write_xml_enc_view( (*this_).sink, &str_view );
     119           2 :                         char probe_id_str_buf[DATA_ID_MAX_UTF8STRING_SIZE] = "";
     120           2 :                         utf8stringbuf_t probe_id_str = UTF8STRINGBUF( probe_id_str_buf );
     121           2 :                         write_err |= data_id_to_utf8stringbuf ( &probe_id, probe_id_str );
     122           2 :                         write_err |= io_xml_writer_write_plain ( (*this_).sink, (*this_).tag_xref_start );
     123           2 :                         write_err |= io_xml_writer_write_xml_enc( (*this_).sink, utf8stringbuf_get_string( probe_id_str ) );
     124           2 :                         write_err |= io_xml_writer_write_plain ( (*this_).sink, (*this_).tag_xref_middle );
     125           2 :                         text_start_byte = text_current_byte;
     126           2 :                         if ( show_id )
     127             :                         {
     128           1 :                             write_err |= io_xml_writer_write_xml_enc( (*this_).sink, utf8stringbuf_get_string( probe_id_str ) );
     129           1 :                             text_current_byte += length + sizeof(IO_MD_WRITER_LINK_AS_ID)-1 - 1;
     130             :                         }
     131             :                         else /* show_name */
     132             :                         {
     133           1 :                             write_err |= io_xml_writer_write_xml_enc( (*this_).sink, data_diagram_get_name_const( &((*this_).temp_diagram) ) );
     134           1 :                             text_current_byte += length + sizeof(IO_MD_WRITER_LINK_AS_NAME)-1 - 1;
     135             :                         }
     136           2 :                         write_err |= io_xml_writer_write_plain ( (*this_).sink, (*this_).tag_xref_end );
     137           2 :                         text_start_byte = text_current_byte+1;
     138             : 
     139             :                         /* destroy the diagram */
     140           2 :                         data_diagram_destroy( &((*this_).temp_diagram) );
     141             :                     }
     142             :                     else
     143             :                     {
     144           1 :                         U8_TRACE_INFO_INT("id found but diagram does not exist: D", data_id_get_row_id( &probe_id ) );
     145             :                     }
     146             :                 }
     147             :                 else
     148             :                 {
     149           2 :                     U8_TRACE_INFO_INT("id found but #id or #name fragment missing: D", data_id_get_row_id( &probe_id ) );
     150             :                 }
     151             :             }
     152             :         }
     153             : 
     154         144 :         if ( text_current_byte+1 == text_byte_length )
     155             :         {
     156           4 :             write_err |= io_xml_writer_write_xml_enc( (*this_).sink, &(text[text_start_byte]) );
     157             :         }
     158             :     }
     159             : 
     160           4 :     U8_TRACE_END_ERR( write_err );
     161           4 :     return write_err;
     162             : }
     163             : 
     164             : 
     165             : /*
     166             : Copyright 2019-2024 Andreas Warnke
     167             : 
     168             : Licensed under the Apache License, Version 2.0 (the "License");
     169             : you may not use this file except in compliance with the License.
     170             : You may obtain a copy of the License at
     171             : 
     172             :     http://www.apache.org/licenses/LICENSE-2.0
     173             : 
     174             : Unless required by applicable law or agreed to in writing, software
     175             : distributed under the License is distributed on an "AS IS" BASIS,
     176             : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     177             : See the License for the specific language governing permissions and
     178             : limitations under the License.
     179             : */

Generated by: LCOV version 1.16