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.
This commit is contained in:
parent
22c1730261
commit
f5e7d62f90
@ -257,6 +257,12 @@ if(FLTK_BUILD_FLTK_OPTIONS)
|
||||
add_subdirectory(fltk-options)
|
||||
endif(FLTK_BUILD_FLTK_OPTIONS)
|
||||
|
||||
#######################################################################
|
||||
# build utilities
|
||||
#######################################################################
|
||||
|
||||
add_subdirectory(util)
|
||||
|
||||
#######################################################################
|
||||
# variables shared by export and install
|
||||
# export.cmake creates configuration files for direct use in a built but uninstalled FLTK
|
||||
|
||||
@ -103,6 +103,7 @@ if(FLTK_BUILD_HTML_DOCS)
|
||||
|
||||
set(GENERATE_HTML YES)
|
||||
set(GENERATE_LATEX NO)
|
||||
set(EXTRA_SECTIONS "HTML_SECTIONS")
|
||||
set(LATEX_HEADER "")
|
||||
set(DOXYFILE "Doxyfile")
|
||||
set(LOGFILE "${CMAKE_CURRENT_BINARY_DIR}/${DOXYFILE}_error.log")
|
||||
@ -152,6 +153,7 @@ if(FLTK_BUILD_PDF_DOCS)
|
||||
|
||||
set(GENERATE_HTML NO)
|
||||
set(GENERATE_LATEX YES)
|
||||
set(EXTRA_SECTIONS "LATEX_SECTIONS")
|
||||
set(LATEX_HEADER "${CMAKE_CURRENT_BINARY_DIR}/fltk-book.tex")
|
||||
set(DOXYFILE "Doxybook")
|
||||
set(LOGFILE "${CMAKE_CURRENT_BINARY_DIR}/${DOXYFILE}_error.log")
|
||||
@ -202,6 +204,7 @@ if(FLTK_BUILD_PDF_DOCS)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/fltk.pdf
|
||||
COMMAND code_snapshot ${CMAKE_CURRENT_SOURCE_DIR}/src/unicode.dox
|
||||
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/make_header
|
||||
${DOXYGEN_EXECUTABLE}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/fltk-title.tex
|
||||
@ -220,6 +223,7 @@ if(FLTK_BUILD_PDF_DOCS)
|
||||
add_custom_target(pdf
|
||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/fltk.pdf
|
||||
)
|
||||
add_dependencies(pdf code_snapshot)
|
||||
|
||||
endif(FLTK_BUILD_PDF_DOCS)
|
||||
|
||||
|
||||
@ -229,7 +229,8 @@ TAB_SIZE = 8
|
||||
# newlines (in the resulting output). You can put ^^ in the value part of an
|
||||
# alias to insert a newline as if a physical newline was in the original file.
|
||||
|
||||
ALIASES =
|
||||
ALIASES = code_international{1}="@if LATEX_SECTIONS^^@image latex \1 width=\\linewidth^^@endif^^@if HTML_SECTIONS^^@code"
|
||||
ALIASES += endcode_international="@endcode^^@endif"
|
||||
|
||||
# This tag can be used to specify a number of word-keyword mappings (TCL only).
|
||||
# A mapping has the form "name=value". For example adding "class=itcl::class"
|
||||
@ -639,7 +640,7 @@ GENERATE_DEPRECATEDLIST= YES
|
||||
# sections, marked by \if <section_label> ... \endif and \cond <section_label>
|
||||
# ... \endcond blocks.
|
||||
|
||||
ENABLED_SECTIONS = @DRIVER_DOCS@
|
||||
ENABLED_SECTIONS = @DRIVER_DOCS@ @EXTRA_SECTIONS@
|
||||
|
||||
# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
|
||||
# initial value of a variable or macro / define can have for it to appear in the
|
||||
@ -920,7 +921,8 @@ EXAMPLE_RECURSIVE = NO
|
||||
# that contain images that are to be included in the documentation (see the
|
||||
# \image command).
|
||||
|
||||
IMAGE_PATH = @CMAKE_CURRENT_SOURCE_DIR@/src
|
||||
IMAGE_PATH = @CMAKE_CURRENT_SOURCE_DIR@/src \
|
||||
@CMAKE_CURRENT_BINARY_DIR@/generated
|
||||
|
||||
# The INPUT_FILTER tag can be used to specify a program that doxygen should
|
||||
# invoke to filter for each input file. Doxygen will invoke the filter program
|
||||
|
||||
@ -20,6 +20,16 @@ are not yet implemented.
|
||||
|
||||
\section unicode_quick_start Quick Start
|
||||
|
||||
International code test for HTML and PDF:
|
||||
|
||||
\code_international{"generated/unicode_about.png"}
|
||||
// This is a test
|
||||
// 日本語テストテキスト
|
||||
// 中文测试文本
|
||||
// Ελληνικό κείμενο δοκιμής
|
||||
\endcode_international
|
||||
|
||||
|
||||
For most applications, you simply need to ensure your text is UTF-8 encoded:
|
||||
|
||||
\code
|
||||
|
||||
@ -53,6 +53,7 @@ public:
|
||||
Code_Editor(int X, int Y, int W, int H, const char *L=nullptr);
|
||||
~Code_Editor();
|
||||
void textsize(Fl_Fontsize s);
|
||||
Fl_Fontsize textsize() const { return Fl_Text_Editor::textsize(); }
|
||||
|
||||
/// access to protected member get_absolute_top_line_number()
|
||||
int top_line() { return get_absolute_top_line_number(); }
|
||||
|
||||
76
util/CMakeLists.txt
Normal file
76
util/CMakeLists.txt
Normal file
@ -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
|
||||
@ -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.
|
||||
|
||||
159
util/code_snapshot.cxx
Normal file
159
util/code_snapshot.cxx
Normal file
@ -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;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user