manual/tools/texquote2: reimplement the tool in OCaml

master
Sébastien Hinderer 2018-06-26 06:58:23 +02:00
parent cb38dbdfa1
commit c8343888fa
8 changed files with 145 additions and 177 deletions

View File

@ -12,7 +12,7 @@ OCAMLDOC = $(if $(wildcard $(SRC)/ocamldoc/ocamldoc.opt),\
# Copy and unprefix the standard library when needed
include $(SRC)/ocamldoc/Makefile.unprefix
TEXQUOTE = ../tools/texquote2
TEXQUOTE = $(SRC)/byterun/ocamlrun ../tools/texquote2
FILES = allfiles.tex biblio.tex foreword.tex version.tex warnings-help.etex

View File

@ -7,7 +7,7 @@ TOOLS = ../../tools
CAMLLATEX = $(SET_LD_PATH) \
$(OCAMLRUN) $(TOOLS)/caml-tex2 \
-caml "TERM=norepeat $(OCAML)" -n 80 -v false
TEXQUOTE = $(TOOLS)/texquote2
TEXQUOTE = $(OCAMLRUN) $(TOOLS)/texquote2
TRANSF = $(SET_LD_PATH) $(OCAMLRUN) $(TOOLS)/transf

View File

@ -15,7 +15,7 @@ OCAMLDOC = $(if $(wildcard $(CSLDIR)/ocamldoc/ocamldoc.opt),\
include $(SRC)/ocamldoc/Makefile.unprefix
TEXQUOTE = ../../tools/texquote2
TEXQUOTE = $(SRC)/byterun/ocamlrun ../../tools/texquote2
CORE_INTF = Pervasives.tex

View File

@ -7,7 +7,7 @@ TOOLS = ../../tools
CAMLLATEX = $(SET_LD_PATH) \
$(OCAMLRUN) $(TOOLS)/caml-tex2 \
-caml "TERM=norepeat $(OCAML)" -n 80 -v false
TEXQUOTE = $(TOOLS)/texquote2
TEXQUOTE = $(OCAMLRUN) $(TOOLS)/texquote2
TRANSF = $(SET_LD_PATH) $(OCAMLRUN) $(TOOLS)/transf

View File

@ -7,7 +7,7 @@ TOOLS = ../../tools
CAMLLATEX = $(SET_LD_PATH) \
$(OCAMLRUN) $(TOOLS)/caml-tex2 \
-caml "TERM=norepeat $(OCAML)" -n 80 -v false
TEXQUOTE = $(TOOLS)/texquote2
TEXQUOTE = $(OCAMLRUN) $(TOOLS)/texquote2
TRANSF = $(SET_LD_PATH) $(OCAMLRUN) $(TOOLS)/transf

View File

@ -2,8 +2,6 @@ TOPDIR=../..
COMPFLAGS=-I $(OTOPDIR)/otherlibs/str -I $(OTOPDIR)/otherlibs/unix
include $(TOPDIR)/Makefile.tools
OC_CFLAGS=-g -O
all: texquote2 transf caml-tex2
@ -17,6 +15,9 @@ caml-tex2: caml_tex2.ml
$(OCAMLC) $(TOPDIR)/compilerlibs/ocamlcommon.cma -I $(TOPDIR)/parsing \
-o $@ str.cma unix.cma $<
texquote2: texquote2.ml
$(OCAMLC) -o $@ $<
%.cmo: %.ml
$(OCAMLC) -c $<
@ -27,9 +28,6 @@ caml-tex2: caml_tex2.ml
%.ml: %.mll
$(OCAMLLEX) $<
%: %.c
$(CC) $(OC_CFLAGS) -o $@ $<
.PHONY: clean
clean:

View File

@ -1,167 +0,0 @@
#include <stdio.h>
#include <ctype.h>
char * transl[256];
#define LINE_LENGTH 1024
char line[LINE_LENGTH];
int isprefix(s, pref)
char * s;
char * pref;
{
while (1) {
if (*pref == 0) return 1;
if (*s == 0) return 0;
if (*s != *pref) return 0;
s++;
pref++;
}
}
int main(argc, argv)
int argc;
char * argv [];
{
unsigned char * p;
int c;
int inquote;
int inverb;
int inverbatim_like;
int incaml;
int inverbatim = 0;
char *verbatim_end_in = "";
char *verbatim_end_out = "";
for (c = 0; c < 256; c++) transl[c] = NULL;
#ifdef TIE_BLANKS
transl[' '] = "~";
transl['\n'] = "~";
#else
transl[' '] = "\\ ";
transl['\n'] = "\\ ";
#endif
transl['{'] = "{\\char123}";
transl['}'] = "{\\char125}";
transl['^'] = "{\\char94}";
transl['_'] = "{\\char95}";
transl['\\'] = "{\\char92}";
transl['~'] = "{\\char126}";
transl['$'] = "\\$";
transl['&'] = "{\\char38}";
transl['#'] = "\\#";
transl['%'] = "\\%";
transl['\''] = "{\\textquotesingle}";
transl['`'] = "{\\textasciigrave}";
inverbatim_like = 0;
incaml = 0;
inquote = 0;
inverbatim = 0;
puts ("% THIS FILE IS GENERATED.\n");
while(fgets(line, LINE_LENGTH, stdin) != NULL) {
if (inverbatim_like) {
fputs(line, stdout);
if (isprefix(line, "\\end{caml_")
|| isprefix(line, "\\end{rawhtml}")) inverbatim_like = 0;
continue;
}
if (incaml) {
fputs(line, stdout);
if (isprefix(line, "\\endcamlexample")) incaml = 0;
continue;
}
if (inverbatim){
if (isprefix (line, verbatim_end_in)){
fputs (verbatim_end_out, stdout);
inverbatim = 0;
}else{
for (p = (unsigned char *) line; *p != 0; p++){
c = *p;
if (c == ' ' || c == '\n' || transl[c] == NULL){
putchar (c);
}else{
fputs (transl[c], stdout);
}
}
}
continue;
}
if (isprefix(line, "\\begin{caml_")
|| isprefix(line, "\\begin{rawhtml}")) {
fputs(line, stdout);
inverbatim_like = 1;
continue;
}
if (isprefix(line, "\\camlexample")) {
fputs(line, stdout);
incaml = 1;
continue;
}
if (isprefix (line, "\\begin{verbatim}")){
fputs ("\\begin{machineenv}", stdout);
inverbatim = 1;
verbatim_end_in = "\\end{verbatim}";
verbatim_end_out = "\\end{machineenv}";
continue;
}
if (isprefix (line, "\\begin{ocamldoccode}")){
fputs ("\\begin{ocamldoccode}", stdout);
inverbatim = 1;
verbatim_end_in = "\\end{ocamldoccode}";
verbatim_end_out = "\\end{ocamldoccode}";
continue;
}
inverb = 0;
for (p = (unsigned char *) line; *p != 0; p++) {
c = *p;
if (inverb) {
if (c == inverb){
inverb = 0;
}else if (c == '\'' || c == '`'){
fprintf (stderr, "Warning: %c found in \\verb\n", c);
}
putchar(c);
continue;
}
switch(c) {
case '"':
if (inquote) {
fputs("}}", stdout);
inquote = 0;
} else {
fputs("{\\machine{", stdout);
inquote = 1;
}
break;
case '\\':
if (inquote) {
if (p[1] == '"' || p[1] == '\\') {
c = p[1];
p++;
}
if (transl[c] != NULL)
fputs(transl[c], stdout);
else
putchar(c);
} else if (isprefix(p, "\\verb") && p[5] != 0 && !isalpha(p[5])) {
inverb = p[5];
p = p + 5;
fputs("\\verb", stdout);
putchar(inverb);
} else {
putchar('\\');
}
break;
default:
if (inquote && transl[c] != NULL)
fputs(transl[c], stdout);
else
putchar(c);
}
}
}
return 0;
}

137
manual/tools/texquote2.ml Normal file
View File

@ -0,0 +1,137 @@
type environment =
| Normal
| Caml
| Verbatim of string * string
| Verbatim_like
let in_quotes = ref false
let is_alpha c =
('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')
let is_prefix prefix str =
let length_prefix = String.length prefix in
let length_str = String.length str in
if length_prefix > length_str
then false
else (String.sub str 0 length_prefix) = prefix
let escape = function
| ' ' | '\n' -> "\\ "
| '{' -> "{\\char123}"
| '}' -> "{\\char125}"
| '^' -> "{\\char94}"
| '_' -> "{\\char95}"
| '\\' -> "{\\char92}"
| '~' -> "{\\char126}"
| '$' -> "\\$"
| '&' -> "{\\char38}"
| '#' -> "\\#"
| '%' -> "\\%"
| '\'' -> "{\\textquotesingle}"
| '`' -> "{\\textasciigrave}"
| _ -> ""
let process_normal_line line =
let (verb_mark : char option ref) = ref None in
let l = String.length line in
let i = ref 0 in
while !i<l do
match !verb_mark with
| None ->
(match line.[!i] with
| '"' ->
let r = if !in_quotes then "}}" else "{\\machine{" in
print_string r;
in_quotes := not !in_quotes;
incr i;
| '\\' ->
if !in_quotes
then begin
if (!i < l-1) && (line.[!i+1] = '"' || line.[!i+1] = '\\')
then incr i;
let t = escape line.[!i] in
if t<>"" then print_string t else print_char line.[!i];
incr i;
end else if is_prefix "\\verb" (String.sub line !i (l - !i))
&& not (is_alpha line.[!i+5])
then begin
i := !i+5;
verb_mark := Some line.[!i];
print_string "\\verb";
print_char line.[!i];
incr i;
end else (print_char '\\'; incr i)
| _ ->
if !in_quotes && (escape line.[!i] <> "")
then print_string (escape line.[!i])
else print_char line.[!i];
incr i;
)
| Some mark ->
if line.[!i] = mark
then verb_mark := None
else if line.[!i] = '\'' || line.[!i] = '`'
then Printf.eprintf "Warning: %c found in \\verb\n" line.[!i];
print_char line.[!i];
incr i;
done
let process_line line = function
| Normal ->
if is_prefix "\\begin{caml_" line || is_prefix "\\begin{rawhtml}" line
then (print_string line; Verbatim_like)
else if is_prefix "\\camlexample" line
then (print_endline line; Caml)
else if is_prefix "\\begin{verbatim}" line
then begin
print_string "\\begin{machineenv}";
(Verbatim ("\\end{verbatim}", "\\end{machineenv}"))
end else if is_prefix "\\begin{ocamldoccode}" line
then begin
print_string "\\begin{ocamldoccode}";
(Verbatim ("\\end{ocamldoccode}", "\\end{ocamldoccode}"))
end else begin
process_normal_line line;
if !in_quotes
then print_string (escape '\n')
else print_newline();
Normal
end
| Caml ->
print_endline line;
if is_prefix "\\endcamlexample" line then Normal else Caml
| Verbatim (verbatim_end_in, verbatim_end_out) as env ->
if is_prefix verbatim_end_in line
then begin
print_string verbatim_end_out;
Normal
end else begin
for i=0 to (String.length line) - 1 do
let c = line.[i] in
let t = escape c in
if c=' ' || c='\n' || t=""
then print_char c
else print_string t
done;
print_newline();
env
end
| Verbatim_like ->
print_endline line;
if is_prefix "\\end{caml_" line || is_prefix "\\end{rawhtml}" line
then Normal
else Verbatim_like
let rec process_input env = match input_line stdin with
| exception End_of_file -> ()
| line ->
let env = process_line line env in
process_input env
let main() =
print_endline "% THIS FILE IS GENERATED.";
print_newline();
process_input Normal
let _ = main()