summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbrecht Schlosser <albrechts.fltk@online.de>2025-12-29 20:02:06 +0100
committerAlbrecht Schlosser <albrechts.fltk@online.de>2025-12-29 20:02:06 +0100
commita057e13fb4331b17442028a0c7ed90a53241f0a2 (patch)
tree08a24d411ea35c604193d017674f2026cc584061
parent83fab8cb0ffd6ee7a38ec6e4dd768b1b3f9eb896 (diff)
Improve code snapshot generation for PDF docs (#1353)
CMake: execute `code_snapshot` separately for each file we want to scan so we can create timestamps and generate PNG images only if the source file (e.g. unicode.dox) was modified. documentation/src/unicode.dox: remove output folder `generated`, use only the filename. CMake sets the current working directory as needed. util/code_snapshot.cxx: format and improve comments, reset code buffer so we can generate multiple images per input file.
-rw-r--r--documentation/CMakeLists.txt40
-rw-r--r--documentation/src/unicode.dox6
-rw-r--r--util/code_snapshot.cxx44
3 files changed, 66 insertions, 24 deletions
diff --git a/documentation/CMakeLists.txt b/documentation/CMakeLists.txt
index 6c8524ffe..ada291af2 100644
--- a/documentation/CMakeLists.txt
+++ b/documentation/CMakeLists.txt
@@ -202,11 +202,42 @@ if(FLTK_BUILD_PDF_DOCS)
@ONLY
)
- # generate fltk.pdf
+ # Generate code snapshots (images with international characters).
+ # Note: File names (even from different folders) must be unique !
+
+ set(image_output_dir "${CMAKE_CURRENT_BINARY_DIR}/generated")
+ set(_deps)
+ set(image_input_sources
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/unicode.dox
+ # ${CMAKE_CURRENT_SOURCE_DIR}/src/cmp.dox
+ # ${FLTK_SOURCE_DIR}/src/Fl.cxx # example source file
+ )
+
+ # Generate one custom command and one timestamp per input file
+ # so dependencies can be used to generate the images only if
+ # the source file was changes.
+ # Variable `_deps` is used to make the final PDF generation
+ # depend on all input files.
+
+ foreach(_infile ${image_input_sources})
+ get_filename_component(_name "${_infile}" NAME)
+ set(_timestamp ${image_output_dir}/${_name}.timestamp)
+ list(APPEND _deps ${_timestamp})
+ # create custom command
+ add_custom_command(
+ OUTPUT ${_timestamp}
+ COMMAND touch ${_timestamp}
+ COMMAND code_snapshot ${_infile}
+ DEPENDS ${_infile}
+ WORKING_DIRECTORY ${image_output_dir}
+ COMMENT "Generating code snapshots (PNG) from '${_infile}'"
+ )
+ endforeach()
+
+ # Now generate the PDF file (fltk.pdf)
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
@@ -214,8 +245,11 @@ if(FLTK_BUILD_PDF_DOCS)
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYFILE}
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/make_pdf
COMMAND cp -f latex/refman.pdf fltk.pdf
- DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${DOXYFILE}
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in
+ ${CMAKE_CURRENT_BINARY_DIR}/${DOXYFILE}.in
+ ${CMAKE_CURRENT_BINARY_DIR}/${DOXYFILE}
${CMAKE_CURRENT_BINARY_DIR}/fltk-title.tex
+ ${_deps} # source files processed to generate PNG's
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Generating PDF documentation" VERBATIM
)
diff --git a/documentation/src/unicode.dox b/documentation/src/unicode.dox
index b640e170e..c11308ca3 100644
--- a/documentation/src/unicode.dox
+++ b/documentation/src/unicode.dox
@@ -22,7 +22,7 @@ are not yet implemented.
International code test for HTML and PDF:
-\code_international{"generated/unicode_about.png"}
+\code_international{"unicode_about.png"}
// This is a test
// 日本語テストテキスト
// 中文测试文本
@@ -70,11 +70,11 @@ doesn't break legacy ASCII code.
Functions to check and analyze UTF-8 text:
fl_utf8test() - Check if a string contains valid UTF-8
-\code
+\code_international{"unicode_hello.png"}
const char* text = "Hello 世界";
int result = fl_utf8test(text, strlen(text));
// Returns: 0=invalid, 1=ASCII, 2=2-byte chars, 3=3-byte chars, 4=4-byte chars
-\endcode
+\endcode_international
fl_utf8len() - Get the length in bytes of a UTF-8 octet
\code
diff --git a/util/code_snapshot.cxx b/util/code_snapshot.cxx
index 6613d5b51..907c6ae37 100644
--- a/util/code_snapshot.cxx
+++ b/util/code_snapshot.cxx
@@ -18,11 +18,20 @@
//
// 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
+// output, Doxygen uses LaTeX which can not easily handle UTF-8 characters
// 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.
//
+// Notes:
+// - This program is work in progress...
+// - The PDF generation process (CMake) calls it once for each source file
+// that needs image generation. The loop over all commandline arguments is
+// currently not necessary but kept for potential extensions.
+// - The program exits silently if no commandline is given.
+// - If the terminating "\endcode_international" line is missing or misspelled,
+// the program reads the "code" until the end of the file is reached and
+// terminates w/o error message. This could be improved...
#include <FL/Fl_Window.H>
#include <FL/Fl_Group.H>
@@ -54,7 +63,7 @@ void create_window() {
code_viewer->box(FL_FLAT_BOX);
code_viewer->color(0xf7f7ff00);
code_viewer->textsize(30);
- //code_viewer->cursor_style(CARET_CURSOR);
+ // code_viewer->cursor_style(CARET_CURSOR);
window->resizable(group);
group->resizable(code_viewer);
@@ -69,14 +78,13 @@ void create_window() {
line_height = std::max(line_height, fl_height(FL_COURIER_BOLD_ITALIC, code_viewer->textsize()));
}
-void save_snapshot(const char* code, const char* filename)
-{
-// fprintf(stderr, "\\code\n%s\n\\endcode\n", code);
+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
+ // 300 dpi for 7 inches = 2100 pixels
window->size(2100, (line_height * n_lines) + 18 );
// Generate the Image Surface
@@ -88,7 +96,7 @@ void save_snapshot(const char* code, const char* filename)
fl_rect(0, 0, window->w(), window->h(), 0xccccff00);
Fl_Image_Surface::pop_current();
-// fprintf(stderr, " Saving to \"%s\".\n", filename);
+ // fprintf(stderr, " Saving to \"%s\".\n", filename);
// Write the generated image
Fl_RGB_Image *img = srfc->image();
@@ -102,25 +110,24 @@ void save_snapshot(const char* code, const char* filename)
/**
Main entry point for the PDF documentation helper tool.
- The app scans the input file for the `\\code_international{"filename"}`
+ 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
+ `\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
+ \param[in] argc Argument count
+ \param[in] 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 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);
+ // fl_getcwd(cwd, FL_PATH_MAX-1);
+ // fprintf(stderr, "code_snapshot:\n");
+ // fprintf(stderr, "Working directory is \"%s\".\n", cwd);
create_window();
@@ -134,7 +141,7 @@ int main(int argc, char *argv[])
break;
}
-// fprintf(stderr, "Reading \"%s\".\n", argv[i]);
+ // fprintf(stderr, "Reading \"%s\".\n", argv[i]);
std::string code;
std::string filename;
@@ -145,10 +152,11 @@ int main(int argc, char *argv[])
if (in_code_block) {
if (strstr(line, "\\endcode_international")) {
if (!code.empty()) {
- code.resize( code.size()-1 );
+ code.resize(code.size() - 1);
save_snapshot(code.c_str(), filename.c_str());
}
in_code_block = false;
+ code = "";
} else {
code += line;
}