Hi,

Some time ago, there was a discussion here about how to handle legacy (8-bits)
encodings for old documents with a reasonable amount of changes to the macro
packages, esp. in the LaTeX world. Since then, experiments have been done (the
lua-inputenc package), and I keep thinking that the only way to a sound solution
would be to have a process_output_buffer callback in LuaTeX.

(Intended use: process_input_buffer converts the input encoding to its bytes
representation, internally everything is bytes as it was with pdfTeX,
process_output_buffer outputs bytes as themselves and not their UTF8
representation, so that when the auxiliary file is opened again, it can been
read correctly. This could be done in lua-inputenc or later inputenc itself
without affecting other LaTeX macro packages.)

I can't find in the archives whether it has already been discussed on the list
(at least not with this name), but here are some arguments and 
counter-arguments:
- admittedly, I can't imagine any other use of this callback than for
compatibility with old documents and "old" macro packages, and I know supporting
them is not your priority;
- but adding such a callback costs essentially nothing: the interface keeps
clean (it is symmetric to process_input_buffer) and a possible implementation
doesn't bloat the code at all;
- it keeps in line with LuaTeX philosophy of providing the tools and letting the
macro package authors build whatever they want with it.

In order to help saving your time, I attach a proposed implementation. I ran
quite a few tests with it, and the results look ok.

Please consider including this new callback in LuaTeX.

Thanks,
Manuel.
diff --git a/manual/luatexref-t.tex b/manual/luatexref-t.tex
index b1923da..e3fba27 100644
--- a/manual/luatexref-t.tex
+++ b/manual/luatexref-t.tex
@@ -3536,6 +3536,26 @@ that.
 
 This callback does not replace any internal code.
 
+\subsubsection{\luatex{process_output_buffer}}
+
+This callback allows you to change the contents of the line output
+buffer just before \LUATEX\ actually starts writing it to a file as the
+result of a \tex{write} command. It is only called for output to an
+actual file (that is, excluding the log, the terminal, and \tex{write18}
+calls).
+
+\startfunctioncall
+function(<string> buffer)
+    return <string> adjusted_buffer
+end
+\stopfunctioncall
+
+If you return \type{nil}, \LUATEX\ will pretend like your callback
+never happened. You can gain a small amount of processing time from
+that.
+
+This callback does not replace any internal code.
+
 \subsubsection{\luatex{token_filter}}
 
 This callback allows you to replace the way \LUATEX\ fetches
diff --git a/source/texk/web2c/luatexdir/dvi/dvigen.c b/source/texk/web2c/luatexdir/dvi/dvigen.c
index bf33cf6..d9e3583 100644
--- a/source/texk/web2c/luatexdir/dvi/dvigen.c
+++ b/source/texk/web2c/luatexdir/dvi/dvigen.c
@@ -2126,6 +2126,9 @@ void write_out(halfword p)
     integer d;                  /* number of characters in incomplete current string */
     boolean clobbered;          /* system string is ok? */
     integer ret;                /* return value from |runsystem| */
+    char *s, *ss;               /* line to be written, as a C string */
+    int callback_id;
+    int lua_retval;
     expand_macros_in_tokenlist(p);
     old_setting = selector;
     j = write_stream(p);
@@ -2138,7 +2141,17 @@ void write_out(halfword p)
             selector = log_only;
         tprint_nl("");
     }
-    token_show(def_ref);
+    s = tokenlist_to_cstring(def_ref, false, NULL);
+    if (selector < no_print) { /* selector is a file */
+        /* fix up the output buffer using callbacks */
+        callback_id = callback_defined(process_output_buffer_callback);
+        if (callback_id > 0) {
+            lua_retval = run_callback(callback_id, "S->S", s, &ss);
+            if ((lua_retval == true) && (ss != NULL)) 
+                s = ss;
+        }
+    }
+    tprint(s);
     print_ln();
     flush_list(def_ref);
     if (j == 18) {
diff --git a/source/texk/web2c/luatexdir/lua/lcallbacklib.c b/source/texk/web2c/luatexdir/lua/lcallbacklib.c
index d593cc7..70ce409 100644
--- a/source/texk/web2c/luatexdir/lua/lcallbacklib.c
+++ b/source/texk/web2c/luatexdir/lua/lcallbacklib.c
@@ -50,7 +50,7 @@ static const char *const callbacknames[] = {
     "find_sfd_file", "read_sfd_file",
     "find_pk_file", "read_pk_file",
     "show_error_hook",
-    "process_input_buffer",
+    "process_input_buffer", "process_output_buffer",
     "start_page_number", "stop_page_number",
     "start_run", "stop_run",
     "define_font",
diff --git a/source/texk/web2c/luatexdir/ptexlib.h b/source/texk/web2c/luatexdir/ptexlib.h
index e856266..0f1b040 100644
--- a/source/texk/web2c/luatexdir/ptexlib.h
+++ b/source/texk/web2c/luatexdir/ptexlib.h
@@ -325,7 +325,7 @@ typedef enum {
     find_sfd_file_callback, read_sfd_file_callback,
     find_pk_file_callback, read_pk_file_callback,
     show_error_hook_callback,
-    process_input_buffer_callback,
+    process_input_buffer_callback, process_output_buffer_callback,
     start_page_number_callback, stop_page_number_callback,
     start_run_callback, stop_run_callback,
     define_font_callback,

Reply via email to