manual/tools/texquote2: reimplement the tool in OCaml
parent
cb38dbdfa1
commit
c8343888fa
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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()
|
Loading…
Reference in New Issue