src/c2html.c

Thu, 11 Jul 2024 20:05:26 +0200

author
Mike Becker <universe@uap-core.de>
date
Thu, 11 Jul 2024 20:05:26 +0200
changeset 81
9e483a0e3f52
parent 75
c72b250866ab
permissions
-rw-r--r--

Added tag v3.1 for changeset 0f1c55d2a90a

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 2016 Mike Becker. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   1. Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *
 *   2. Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include "c2html.h"

#include <cx/array_list.h>
#include <cx/printf.h>
#include <string.h>

size_t c2html_format(
        CxList const *lines,
        void *outbuf,
        cx_write_func wfnc,
        c2html_highlighter_func highlighter,
        int showln
) {
    /* total written bytes */
    size_t written = 0;

    /* compute width of line numbering */
    int lnw = 0;
    if (showln) {
        size_t no_lines = cxListSize(lines);
        for (size_t p = 1; p < no_lines; p *= 10) lnw++;
    }

    /* start code formatting */
    written += wfnc("<div class=\"c2html-code\">\n", 1, 26, outbuf);

    /* process lines */
    int lineno = 0;
    c2html_highlighter_data hd = {0};
    cxBufferInit(&hd.primary_buffer, NULL, 256, NULL, CX_BUFFER_AUTO_EXTEND);
    cxBufferInit(&hd.secondary_buffer, NULL, 32, NULL, CX_BUFFER_AUTO_EXTEND);
    CxBuffer out_line;
    cxBufferInit(&out_line, NULL, 128, NULL, CX_BUFFER_AUTO_EXTEND);

    CxIterator in_lines = cxListIterator(lines);
    cx_foreach(char*, in_line, in_lines) {
        /* increase line number and clean line buffer */
        lineno++;
        cxBufferClear(&out_line);

        /* write line number */
        if (showln) {
            cx_bprintf(&out_line, "<a class=\"c2html-lineno\" name=\"l%d\" "
                                  "href=\"#l%d\">%*d </a>",
                       lineno, lineno, lnw, lineno);
        }

        /* process code line */
        highlighter(in_line, &out_line, &hd);

        /* write code line */
        written += wfnc(out_line.space, 1, out_line.size, outbuf);
    }

    /* end code formatting */
    written += wfnc("</div>\n", 1, 7, outbuf);

    /* cleanup and return */
    cxBufferDestroy(&hd.primary_buffer);
    cxBufferDestroy(&hd.secondary_buffer);
    cxBufferDestroy(&out_line);

    return written;
}

size_t c2html_textformat(
        char const *inputbuffer,
        void *outbuf,
        cx_write_func wfnc,
        c2html_highlighter_func highlighter,
        int showln
) {
    /* a rough estimate for the number of lines */
    size_t inputbuflen = strlen(inputbuffer);
    size_t est_cap = 16 + inputbuflen / 40;

    /* create the line pointer array */
    CxList *lines = cxArrayListCreateSimple(CX_STORE_POINTERS, est_cap);
    cxListAdd(lines, inputbuffer);
    for (size_t i = 0; i < inputbuflen; i++) {
        if (inputbuffer[i] == '\n' && i + 1 < inputbuflen) {
            cxListAdd(lines, inputbuffer + i + 1);
        }
    }

    /* invoke the other function */
    size_t n = c2html_format(lines, outbuf, wfnc, highlighter, showln);

    /* cleanup and return */
    cxListDestroy(lines);
    return n;
}

mercurial