diff options
| author | Matthias Melcher <github@matthiasm.com> | 2025-12-28 21:37:23 +0100 |
|---|---|---|
| committer | Matthias Melcher <github@matthiasm.com> | 2025-12-28 21:37:30 +0100 |
| commit | f5e7d62f90f5eb88afad45d56017c42835149d0c (patch) | |
| tree | d1fae5330c7c107776626466e17aabc3844e6f84 /util | |
| parent | 22c17302616acad9e4eb735d897948dee28942ae (diff) | |
Generate code block documentation using FLTK (#1353)
The Doxygen-to-pdf toolchain can not easily generate
pdf's with Japanese and Chinese characters. This patch
generates code blocks by rendering them in FLTK.
Diffstat (limited to 'util')
| -rw-r--r-- | util/CMakeLists.txt | 76 | ||||
| -rw-r--r-- | util/README.txt | 13 | ||||
| -rw-r--r-- | util/code_snapshot.cxx | 159 |
3 files changed, 248 insertions, 0 deletions
diff --git a/util/CMakeLists.txt b/util/CMakeLists.txt new file mode 100644 index 000000000..a89413a19 --- /dev/null +++ b/util/CMakeLists.txt @@ -0,0 +1,76 @@ +# +# CMakeLists.txt to build utilities for the FLTK project using CMake (www.cmake.org) +# +# Copyright 1998-2025 by Bill Spitzak and others. +# +# This library is free software. Distribution and use rights are outlined in +# the file "COPYING" which should have been included with this file. If this +# file is missing or damaged, see the license at: +# +# https://www.fltk.org/COPYING.php +# +# Please see the following page on how to report bugs and issues: +# +# https://www.fltk.org/bugs.php +# + +# Build utilities for FLTK development + +# Note: utilities are only built internally during the build process +# and not installed. They are tools used to generate source files or +# assist in building documentation. + +####################################################################### +# cmap - colormap generation program +####################################################################### + +# This program produces the contents of "fl_cmap.h" +# It's used during the build process to generate src/fl_cmap.h + +add_executable(cmap cmap.cxx) + +# cmap doesn't need to link against FLTK libraries - it's a standalone tool +target_link_libraries(cmap PRIVATE m) + +# Set properties +set_target_properties(cmap PROPERTIES + OUTPUT_NAME cmap + EXCLUDE_FROM_ALL TRUE +) + +####################################################################### +# PDF documentation tool to generate a png image from a +# Doxygen `@code` segment with international characters +####################################################################### + +if(FLTK_BUILD_PDF_DOCS) + + # PDF documentation helper tool + add_executable(code_snapshot + code_snapshot.cxx + ../fluid/Widgets/Code_Viewer.cxx + ../fluid/Widgets/Code_Editor.cxx + ../fluid/Widgets/Style_Parser.cxx + ) + + target_link_libraries(code_snapshot PRIVATE fltk::images) + + set_target_properties(code_snapshot PROPERTIES + OUTPUT_NAME code_snapshot + EXCLUDE_FROM_ALL FALSE + ) + + target_include_directories(code_snapshot PRIVATE + ../fluid + ) + + message(STATUS "PDF code snapshot tools will be built (FLTK_BUILD_PDF_DOCS=ON)") + +endif(FLTK_BUILD_PDF_DOCS) + +####################################################################### +# Install rules (if any tools need to be installed) +####################################################################### + +# Currently no utilities are installed as they are build-time tools only +# If you need to install any utilities, add install() commands here diff --git a/util/README.txt b/util/README.txt index bfafb80fd..c71f6b147 100644 --- a/util/README.txt +++ b/util/README.txt @@ -4,3 +4,16 @@ Utility programs used to build the FLTK library. Contents: cmap.cxx generate src/fl_cmap.h + code_snapshot.cxx PDF documentation tool to generate a png image from a + Doxygen `@code` segment with international characters + +Build System: + + The util directory includes CMake support. Utilities are built + automatically during the build process when needed. Some utilities + are only built when specific features are enabled: + + - the PDF documentation helper is only built when FLTK_BUILD_PDF_DOCS=ON + + To add a new utility, edit util/CMakeLists.txt and follow the existing + patterns for conditional building and target configuration. diff --git a/util/code_snapshot.cxx b/util/code_snapshot.cxx new file mode 100644 index 000000000..a8a2f2cae --- /dev/null +++ b/util/code_snapshot.cxx @@ -0,0 +1,159 @@ +// +// PDF documentation tool to generate a png image from a Doxygen `@code` +// segment with international characters for the Fast Light Tool Kit (FLTK). +// +// Copyright 2025 by Bill Spitzak and others. +// +// This library is free software. Distribution and use rights are outlined in +// the file "COPYING" which should have been included with this file. If this +// file is missing or damaged, see the license at: +// +// https://www.fltk.org/COPYING.php +// +// Please see the following page on how to report bugs and issues: +// +// https://www.fltk.org/bugs.php +// + +// +// Our documentation for the FLTK unicode contains international characters +// to illustrate use of non ASCII characters in the GUI. To generate PDF +// output, Doxygen uses LaTeX which can not easily handle UTF-8 characters in +// beyond Western encoding. This tool generates PNG images from code segments +// containing international characters so that they can be included in the +// PDF documentation instead of the code segments with UTF-8 characters. +// + +#include <stdio.h> + +#include <FL/Fl_Window.H> +#include <FL/Fl_Group.H> +#include <FL/filename.H> +#include <FL/fl_draw.H> +#include <FL/Fl_Image_Surface.H> +#include <FL/Fl_PNG_Image.H> + +#include "../fluid/widgets/Code_Editor.h" +#include "../fluid/widgets/Code_Viewer.h" +#include "../fluid/widgets/Style_Parser.h" + +Fl_Window* window = nullptr; +Fl_Group* group = nullptr; +fld::widget::Code_Viewer* code_viewer = nullptr; + +void create_window() { + window = new Fl_Window(1024, 100); + group = new Fl_Group(0, 0, 1024, 100); + group->color(0xf7f7ff00); + group->box(FL_FLAT_BOX); + + code_viewer = new fld::widget::Code_Viewer(5, 5, 1014, 94); + code_viewer->box(FL_FLAT_BOX); + code_viewer->color(0xf7f7ff00); + code_viewer->textsize(30); + + window->resizable(group); + group->resizable(code_viewer); +} + +void save_snapshot(const char* code, const char* filename) +{ +// fprintf(stderr, "\\code\n%s\n\\endcode\n", code); + + code_viewer->buffer()->text(code); + int n_lines = 1; + for (const char* s=code; *s; ++s) if (*s == '\n') n_lines++; + // 300 dpi for 7 inches = 2000 pixels + window->size(2100, 6 + 34*n_lines ); + + // Generate the Image Surface + Fl_Image_Surface *srfc = new Fl_Image_Surface(window->w(), window->h()); + + // Draw the window and its content + Fl_Image_Surface::push_current(srfc); + srfc->draw(group, 0, 0); + fl_rect(0, 0, window->w(), window->h(), 0xccccff00); + Fl_Image_Surface::pop_current(); + +// fprintf(stderr, " Saving to \"%s\".\n", filename); + + // Write the generated image + Fl_RGB_Image *img = srfc->image(); + fl_write_png(filename, img); + + // Clean up + delete img; + delete srfc; +} + +/** + Main entry point for the PDF documentation helper tool. + + The app scans the input file for the `\\code_international{"filename"}` + directive, reads the following code segment until + `\\endcode_international`, and generates a PNG image file with the given + filename containing the code segment rendered with FLTK's + code rendering capabilities. + + \param argc Argument count + \param argv a list of input files with documentation in Doxygen format + \return Exit code (0 for success, non-zero for failure) +*/ +int main(int argc, char *argv[]) +{ + int ret = 0; + char line[1024]; + char cwd[FL_PATH_MAX]; + +// fl_getcwd(cwd, FL_PATH_MAX-1); +// fprintf(stderr, "code_snapshot:\n"); +// fprintf(stderr, "Working directory is \"%s\".\n", cwd); + + create_window(); + + for (int i = 1; i < argc; i++) { + FILE* f = fl_fopen(argv[i], "rb"); + if (!f) { + fl_getcwd(cwd, FL_PATH_MAX-1); + fprintf(stderr, "code_snapshot:\nCan't open file \"%s\".\n", argv[i]); + fprintf(stderr, "Working directory is \"%s\".\n", cwd); + ret = -1; + break; + } + +// fprintf(stderr, "Reading \"%s\".\n", argv[i]); + + std::string code; + std::string filename; + bool in_code_block = false; + for (;;) { + fgets(line, 1023, f); + if (feof(f)) break; + if (in_code_block) { + if (strstr(line, "\\endcode_international")) { + if (!code.empty()) { + code.resize( code.size()-1 ); + save_snapshot(code.c_str(), filename.c_str()); + } + in_code_block = false; + } else { + code += line; + } + } else { + if (strstr(line, "\\code_international")) { + const char* fn_start = strstr(line, "{\""); + const char* fn_end = strstr(line, "\"}"); + if (fn_start && fn_end && (fn_end > fn_start)) { + filename = std::string(fn_start+2, fn_end-fn_start-2); + in_code_block = true; + } + } + } + } + fclose(f); + } + + delete window; + + return ret; +} |
