Repository: tesseract-ocr/tesseract
File: src/api/altorenderer.cpp (C++)

Code before:
 * Alto Text Renderer interface implementation
 **********************************************************************/
    TessAltoRenderer::TessAltoRenderer(const char *outputbase)
            : TessResultRenderer(outputbase, "xml") {
    }

    /**
    * Append the ALTO XML for the beginning of the document
    */
    bool TessAltoRenderer::BeginDocumentHandler() {
        AppendString(
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
                "<alto xmlns=\"http://www.loc.gov/standards/alto/ns-v3#\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.loc.gov/standards/alto/ns-v3# http://www.loc.gov/alto/v3/alto-3-0.xsd\">\n"
                "\t<Description>\n"
                "\t\t<MeasurementUnit>pixel</MeasurementUnit>\n"
                "\t\t<sourceImageInformation>\n"
                "\t\t\t<fileName>");

        AppendString(title());

        AppendString("\t\t\t</fileName>\n"
                     "\t\t</sourceImageInformation>\n"
                     "\t\t<OCRProcessing ID=\"OCR_0\">\n"
                     "\t\t\t<ocrProcessingStep>\n"
                     "\t\t\t\t<processingSoftware>\n"
                     "\t\t\t\t\t<softwareName>tesseract 4.0.0</softwareName>\n"
                     "\t\t\t\t</processingSoftware>\n"
                     "\t\t\t</ocrProcessingStep>\n"
                     "\t\t</OCRProcessing>\n"
                     "\t</Description>\n"
                     "\t<Layout>\n");

        return true;
    }

    /**
    * Append the ALTO XML for the end of the document
    */
    bool TessAltoRenderer::EndDocumentHandler() {
        AppendString("\t</Layout>\n</alto>\n");

        return true;
    }

    /**
    * Append the ALTO XML for the layout of the image
    */
    bool TessAltoRenderer::AddImageHandler(TessBaseAPI *api) {
        const std::unique_ptr<const char[]> hocr(api->GetAltoText(imagenum()));
        if (hocr == nullptr) return false;


Review comment (suggestion):
The version should be taken from `TessBaseAPI::Version()` here.

Code after:
    ///
    static void AddBoxToAlto(const ResultIterator *it, PageIteratorLevel level,
                             STRING *alto_str) {
        int left, top, right, bottom;
        it->BoundingBox(level, &left, &top, &right, &bottom);

        int hpos = left;
        int vpos = top;
        int height = bottom - top;
        int width = right - left;

        *alto_str += " HPOS=\"";
        alto_str->add_str_int("", hpos);
        *alto_str += "\"";
        *alto_str += " VPOS=\"";
        alto_str->add_str_int("", vpos);
        *alto_str += "\"";
        *alto_str += " WIDTH=\"";
        alto_str->add_str_int("", width);
        *alto_str += "\"";
        *alto_str += " HEIGHT=\"";
        alto_str->add_str_int("", height);
        *alto_str += "\"";

        if (level == RIL_WORD) {
            int wc = it->Confidence(RIL_WORD);
            *alto_str += " WC=\"0.";
            alto_str->add_str_int("", wc);
            *alto_str += "\"";
        }
        if (level != RIL_WORD) {

            *alto_str += ">";
        }
    }

    ///
    /// Add a unique ID to an ALTO element
    ///
    static void AddIdToAlto(STRING *alto_str, const std::string base, int num1) {
        const size_t BUFSIZE = 64;
        char id_buffer[BUFSIZE];
        snprintf(id_buffer, BUFSIZE - 1, "%s_%d", base.c_str(), num1);
        id_buffer[BUFSIZE - 1] = '\0';
        *alto_str += " ID=\"";
        *alto_str += id_buffer;
        *alto_str += "\"";
    }

    ///
    /// Append the ALTO XML for the beginning of the document