Prolog "literate"

Admin User, erstellt 04. Jan. 2024
         
/**
* Modern Albufeira Prolog Interpreter
*
* Warranty & Liability
* To the extent permitted by applicable law and unless explicitly
* otherwise agreed upon, XLOG Technologies AG makes no warranties
* regarding the provided information. XLOG Technologies AG assumes
* no liability that any problems might be solved with the information
* provided by XLOG Technologies AG.
*
* Rights & License
* All industrial property rights regarding the information - copyright
* and patent rights in particular - are the sole property of XLOG
* Technologies AG. If the company was not the originator of some
* excerpts, XLOG Technologies AG has at least obtained the right to
* reproduce, change and translate the information.
*
* Reproduction is restricted to the whole unaltered document. Reproduction
* of the information is only allowed for non-commercial uses. Selling,
* giving away or letting of the execution of the library is prohibited.
* The library can be distributed as part of your applications and libraries
* for execution provided this comment remains unchanged.
*
* Restrictions
* Only to be distributed with programs that add significant and primary
* functionality to the library. Not to be distributed with additional
* software intended to replace any components of the library.
*
* Trademarks
* Jekejeke is a registered trademark of XLOG Technologies AG.
*/
:- ['../cross/helper.p'].
:- ensure_loaded(library(util/format)).
:- ensure_loaded(library(util/charsio)).
% :- ensure_loaded(library(util/format)).
% :- ensure_loaded(library(util/charsio)).
/*************************************************************/
/* Webify Batch */
/*************************************************************/
/**
* webify_libs(D):
* The predicate succeeds in adding libs to the directory D.
* The webifyer silently overwrites existing libs in the directory D.
*/
% webify_libs(+Atom)
webify_libs(OutDir) :-
libs_file(OutDir, 'notebook.css'),
libs_file(OutDir, 'engine.mjs').
% libs_file(+Atom, +Atom)
libs_file(OutDir, Name) :-
atom_concat(OutDir, Name, OutName),
atom_concat('transpiler/press/', Name, InName),
copy_text(InName, OutName).
/**
* webify_page(A, B):
* webify_page(A, B, O):
* The predicate succeeds in a HTML page B for the Prolog text A.
* The webifyer silently overwrites an already existing HTML page B.
* The ternary predicate allows specifying webify options.
*/
% webify_page(+Path, +Path)
webify_page(InName, OutName) :-
webify_page(InName, OutName, []).
% webify_page(+Path, +Path, +List)
webify_page(InName, OutName, Opts) :-
decode_notebook_opts(Opts, 0, Flags),
copy_text('transpiler/press/header.html', OutName),
setup_once_cleanup(
open(OutName, append, OutStream),
page_file(InName, OutStream, Flags),
close(OutStream)),
copy_text('transpiler/press/footer.html', OutName, [append(true)]).
% page_file(+Path, +Stream, +Integer)
page_file(InName, OutStream, Flags) :-
setup_once_cleanup(
open(InName, read, InStream),
page_stream(InStream, OutStream, Flags),
close(InStream)).
% page_stream(+Stream, +Stream, +Integer)
page_stream(InStream, OutStream, Flags) :-
get_atom(InStream, 0'\n, Line),
page_line(Line, InStream, OutStream, Flags, 0),
(Flags /\ 1 =:= 0 ->
notebook_link(List, []);
notebook_link_async(List, [])),
atom_split(Block, '', List),
write(OutStream, Block).
% page_line(+Atom, +Stream, +Stream, +Integer, +Integer)
page_line('', _, _, _, _) :- !.
page_line(Line, InStream, OutStream, Flags, Stage) :-
sub_atom(Line, 0, _, _, '/**'), !,
notebook_text(Line, InStream, Line2, List, []),
atom_split(Block, '', List),
write(OutStream, Block),
page_line(Line2, InStream, OutStream, Flags, Stage).
page_line(Line, InStream, OutStream, Flags, Stage) :-
notebook_code(Line, InStream, Stage, Line2, List, []),
atom_split(Block, '', List),
write(OutStream, Block),
Stage2 is Stage+1,
page_line(Line2, InStream, OutStream, Flags, Stage2).
/*************************************************************/
/* Link Cells */
/*************************************************************/
% notebook_link(-List, +List)
notebook_link -->
['<script type="module">\n'],
[' import {setup_engine, link_cells\n'],
[' } from "./engine.mjs";\n'],
[' setup_engine();\n'],
[' link_cells();\n'],
['</script>\n'].
% notebook_link_async(-List, +List)
notebook_link_async -->
['<script type="module">\n'],
[' import {setup_engine, link_cells_async\n'],
[' } from "./engine.mjs";\n'],
[' setup_engine();\n'],
[' link_cells_async();\n'],
['</script>\n'].
/*************************************************************/
/* Text Cell */
/*************************************************************/
% notebook_text(+Atom, +Stream, -Atom, -List, +List)
notebook_text('', _, '') -->
throw(error(syntax_error(unbalanced_text),_)).
notebook_text(Line, InStream, Line3) -->
{sub_atom(Line, 0, _, _, ' */')}, !,
{strip_block(Line, Line2)},
[Line2],
{get_atom(InStream, 0'\n, Line3)}.
notebook_text(Line, InStream, Line4) -->
{strip_block(Line, Line2)},
[Line2],
{get_atom(InStream, 0'\n, Line3)},
notebook_text(Line3, InStream, Line4).
% strip_block(+Atom, -Atom)
strip_block(X, Y) :-
sub_atom(X, 3, _, 0, Y), !.
strip_block(_, '').
/*************************************************************/
/* Code Cell */
/*************************************************************/
% notebook_code(+Atom, +Stream, +Integer, -Atom, -List, +List)
notebook_code(Line, InStream, Stage, Line2) -->
{atom_integer(Atom, 10, Stage)},
['<table style="width: 100%">\n'],
[' <tr>\n'],
[' <td class="input" style="width: 100%"\n'],
[' contenteditable="true" id="text', Atom, '" spellcheck="false"\n'],
[' >'], notebook_value(Line, InStream, Line2), ['</td>\n'],
[' <td rowspan="2" valign="top">\n'],
[' <button class="run" id="launch', Atom, '"\n'],
[' >⏵</button>\n'],
[' </td>\n'],
[' </tr>\n'],
[' <tr>\n'],
[' <td class="result" id="demo', Atom, '"></td>\n'],
[' </tr>\n'],
['</table>\n'].
% notebook_value(+Atom, +Stream, -Atom, -List, +List)
notebook_value('', _, '') --> !.
notebook_value(Line, _, Line) -->
{sub_atom(Line, 0, _, _, '/**')}, !.
notebook_value(Line, InStream, Line4) -->
{xml_escape(Line, Line2)},
[Line2],
{get_atom(InStream, 0'\n, Line3)},
notebook_value(Line3, InStream, Line4).
/***************************************************************/
/* Notebook Options */
/***************************************************************/
/**
* decode_notebook_opts(L, F, G):
* The predicate succeeds in G with the options L starting with defaults F.
*/
% decode_notebook_opts(+List, +Integer, -Integer)
decode_notebook_opts(V, _, _) :- var(V),
throw(error(instantiation_error,_)).
decode_notebook_opts([X|L], I, O) :- !,
decode_notebook_opt(X, I, H),
decode_notebook_opts(L, H, O).
decode_notebook_opts([], H, H) :- !.
decode_notebook_opts(L, _, _) :-
throw(error(type_error(list,L),_)).
% decode_notebook_opt(+Option, +Integer, -Integer)
decode_notebook_opt(V, _, _) :- var(V),
throw(error(instantiation_error,_)).
decode_notebook_opt(async_mode(B), F, G) :- !,
decode_notebook_boolean(B, 1, F, G).
decode_notebook_opt(O, _, _) :-
throw(error(type_error(webify_option,O),_)).
% decode_notebook_boolean(+Boolean, +Integer, +Integer, -Integer)
decode_notebook_boolean(V, _, _, _) :- var(V),
throw(error(instantiation_error,_)).
decode_notebook_boolean(true, M, F, G) :- !,
G is F \/ M.
decode_notebook_boolean(false, M, F, G) :- !,
G is F /\ \ M.
decode_notebook_boolean(B, _, _, _) :-
throw(error(type_error(boolean,B),_)).