SGML : conversions
DTD
Un document a la structure suivante
<!DOCTYPE document SYSTEM "document.dtd">
<DOCUMENT>
<head>
<title>Bla bla bla<title>
<author> Vincent Zoonekynd<author>
<date>Avril 2000<date>
</head>
<body>
<abstract>
<p>
Bla bla bla
</p>
</abstract>
<toc>
<!-- ------------------------------------------------------------ -->
<sect>
<stitle>Bla bla bla</stitle>
<p>
Bla bla bla
</p>
</sect>
<sect>
<stitle>Bla bla bla</stitle>
<sect1>
<stitle>Bla bla bla</stitle>
<p>
Bla bla bla
</p>
</sect1>
<sect1>
<stitle>Bla bla bla</stitle>
<p>
Bla bla bla
</p>
</sect1>
</sect>
</body>
</document>
Il y a éventuellement des images, comme en HTML (ici, il devra y
avoir un fichier 1.eps et un autre 1.gif)
<IMG SRC="1">
Les liens sont de deux formes.
<A HREF="...">...</A>
<LINK>
<LINKTEXT>plusieurs</LINKTEXT>
<href>http://www.math.jussieu.fr/~zoonek/Ecrits/</href>
<href>http://www.math.jussieu.fr/~zoonek/LaTeX/</href>
<href>http://www.math.jussieu.fr/~zoonek/Images/</href>
<href>http://www.math.jussieu.fr/~zoonek/Politique/</href>
</LINK>.
Voici enfin le DTD.
<!ENTITY % text "#PCDATA|img|ref|label|a|link|itemize|enum|descrip|verb|perl|tt|em|html|latex">
<!ENTITY % simpletext "#PCDATA|tt|em">
<!ELEMENT document - - (head,body)>
<!ELEMENT head O O (title, author?, date?)>
<!ELEMENT title - O (#PCDATA)>
<!ELEMENT author - O (#PCDATA)>
<!ELEMENT date - O (#PCDATA)>
<!ELEMENT body O O (abstract?,toc?,sect*)>
<!ELEMENT abstract - O (p+)>
<!ELEMENT toc - O EMPTY>
<!ELEMENT sect - O (stitle, (p|sect1)+)>
<!ELEMENT sect1 - O (stitle, (p|sect2)+)>
<!ELEMENT sect2 - O (stitle, p+)>
<!ELEMENT stitle O O (%simpletext)+>
<!ELEMENT p O O (%text)+>
<!ELEMENT tt - - (#PCDATA)>
<!ELEMENT em - - (#PCDATA)>
<!ELEMENT html - O EMPTY>
<!ATTLIST html
src CDATA #REQUIRED>
<!ELEMENT latex - O EMPTY>
<!ATTLIST latex
src CDATA #REQUIRED>
<!ELEMENT img - O EMPTY>
<!ATTLIST img
src CDATA #REQUIRED>
<!ELEMENT a - - (%simpletext)+>
<!ATTLIST a
href CDATA #REQUIRED>
<!ELEMENT link - - (linktext, href+)>
<!ELEMENT href - - (#PCDATA)>
<!ELEMENT linktext - - (%simpletext)+>
<!ATTLIST sect
id ID #IMPLIED>
<!ATTLIST sect1
id ID #IMPLIED>
<!ATTLIST sect2
id ID #IMPLIED>
<!ELEMENT label - O EMPTY>
<!ATTLIST label
id ID #REQUIRED>
<!ELEMENT ref - O EMPTY>
<!ATTLIST ref
id IDREF #REQUIRED>
<!ELEMENT itemize - - (item+)>
<!ELEMENT enum - - (item+)>
<!ELEMENT item - O (p+)>
<!ELEMENT descrip - - (tag,p+)+>
<!ELEMENT tag - - (%simpletext)+>
<!ELEMENT verb - - (#PCDATA)>
<!ATTLIST verb
lang (tex|perl|shell) tex>
<!ENTITY LaTeX "LaTeX">
<!ENTITY latex "LaTeX">
<!ENTITY TeX "TeX">
<!ENTITY tex "TeX">
<!ENTITY lt "<">
<!ENTITY gt ">">
<!ENTITY amp "&">
<!ENTITY dollar "$">
<!ENTITY oe "oe">
<!ENTITY OE "OE">
Modification du fichier SGML
Le script suivant enlève les & et les < à l'intérieur de <VERB>.
#! perl -w
# Transforme des fichiers « presque SGML », avec des < et des &
# dans les <VERB>...</VERB> en un fichier SGML correct.
##
## BUGS :
##
## - Ne jamais mettre de <VERB> à l'intérieur de <VERB>...</VERB>
## - Ne jamais mettre de & ou de < à l'intrieur de <VERB>...</VERB>
## - Les « & », etc. qui apparaissent à l'intérieur restent « & », etc.
##
## Corollaire : On aura des problèmes à utiliser ce genre de
## « bidouille » pour écrire une documentation sur SGML...
##
$all = join('', <>);
sub correct_spaces {
my ($a) = @_;
$a =~ s/\n\s*\n+/RETOURALALIGNE/gsm;
$a =~ s/\n/ /gsm;
$a =~ s/RETOURALALIGNE/\n\n/gsm;
$a;
}
$resultat = "";
while($all =~ m#<VERB(.*?)>(.*?)(</VERB>|</>)#smi){
$arguments = $1;
$milieu = $2;
$avant = $`;
$all = $';
# On remplace les caractères posant problème : & et <
$milieu =~ s/\&/\&\;/g;
$milieu =~ s/\</\<\;/g;
# On enlève tous les \s et \n qui se trouvent à la fin
$milieu =~ s/\s*$//;
# On enlève aussi (presque) tous les espaces qui se trouvent au début
$milieu =~ s/^\s*\n(\s*)/$1/;
$avant = correct_spaces($avant);
$resultat .= "$avant<VERB$arguments>$milieu</VERB>";
# print "(*** RESULTAT\n$resultat\n***)\n";
}
$resultat .= correct_spaces($all);
$resultat =~ s/\&\;amp\;/\&\;/g;
$resultat =~ s/\&\;lt\;/\<\;/g;
$resultat =~ s/\&\;gt\;/\>\;/g;
$resultat =~ s/<VERB>(\s*\n)+/<VERB>/g;
print $resultat;
Conversion vers HTML
À l'aide de sgmlspl.
##
## À FAIRE
##
## <URL URL="..." NAME="..."> (mettre l'URL en note de bas de page)
## Les caractères spéciaux de LaTeX
## La chaîne de caractères « LateX » doit être transformée en {\LaTeX}
## <VERB>
## (n'y a-t-il pas de problème d'espaces superflus ???)
## Et s'il y a des < et des > à l'intérieur ???
## (Il y en a...)
## <TSCREEN> : à enlever... Non...
## <EM>
##
## Dans le même ordre d'idées, prévoir un convertisseur SGML -> SGML.
## qui rajouterait toutes les balises manquantes.
## Ça existe déjà, ça s'appelle sgmlnorm.
##
use SGMLS;
use SGMLS::Output;
use SGMLS::Refs;
##
## Constantes, à modifier
##
# Si on écrit en blanc :
$couleur_fond_latex = "#500000";
$couleur_texte_latex = "#000000";
$couleur_fond_perl = "#505000";
$couleur_texte_perl = "#000000";
$couleur_fond_shell = "#005050";
$couleur_texte_shel = "#000000";
# J'écris maintenant en noir sur fond jaune :
$couleur_fond = "#F5DEB3"; # Jaune clair
$couleur_texte ="#000000";
$couleur_fond_latex = "#FF8080"; # rouge
$couleur_fond_latex = "#F5DEB3"; # le rouge était illisible...
$couleur_texte_latex = "#000000";
$couleur_fond_perl = "#F0F000"; # jaune
$couleur_texte_perl = "#000000";
$couleur_fond_shell = "#A0F0F0"; # bleu pastel
$couleur_fond_shell = "#80C0C0"; # bleu moins pastel
$couleur_texte_shell = "#000000";
$basename = shift;
sgml('start', sub {
system("touch .redo_$basename");
$Refs = new SGMLS::Refs("$basename.refs");
rename ".tmp.toc", ".tmp.toc.old";
});
my $toc="";
sgml('end', sub {
unlink(".redo_$basename") unless $Refs->warn;
open(TOC,">.tmp.toc");
print TOC $toc;
close(TOC);
});
######################################################################
sgml('cdata', sub {
my($text,$event) = @_;
# unless($event->element->name eq 'VERB'){
$text =~ s/\&/\&/g;
$text =~ s/\</\</g;
$text =~ s/\>/\>/g;
# }
output $text;
});
######################################################################
sgml('<DOCUMENT>', "");
sgml('</DOCUMENT>', "</BODY></HTML>\n");
sgml('<TITLE>', sub{ push_output 'string'; });
sgml('</TITLE>', sub {
my $t = pop_output;
output "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n";
output "<HTML><HEAD><TITLE>$t</TITLE>\n";
output "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=iso-8859-1\">\n";
output "</HEAD>";
output "<BODY BGCOLOR=$couleur_fond TEXT=$couleur_texte><HR WIDTH=80\%><CENTER><H1>$t<P>\n";
});
sgml('<AUTHOR>', "<P><EM>");
sgml('</AUTHOR>', "</EM>\n");
sgml('<DATE>', "<P>");
sgml('</DATE>', "</P>\n");
sgml('</HEAD>', '</H1></CENTER><HR WIDTH=80%>'."\n");
sgml('<ABSTRACT>', "<CENTER><H2>Résumé</H2></CENTER>\n");
sgml('</ABSTRACT>', "<P><HR WIDTH=80\%>\n\n");
sgml('<TOC>', sub{
open(TOC, ".tmp.toc.old");
while(<TOC>){output $_;}
close(TOC);
output "<P><HR WIDTH=80\%>\n";
});
#####################
my $current_number="";
my $chapter = 0;
my $section = 0;
my $subsection = 0;
sgml('<SECT>', sub {
my $element = shift;
$chapter++;
$section = $subsection=0;
$current_number="$chapter";
output "<P><HR WIDTH=80\%><P><H1><A NAME=\"$current_number\">$chapter</A> ";
if( $element->attribute('ID') ){
$Refs->put("ref:". $element->attribute('ID')->value, $current_number);
}
$toc .= "<P><P><A HREF=\"\#$current_number\"><STRONG>$current_number</STRONG> ";
});
sgml('<SECT1>', sub {
my $element = shift;
$section++;
$subsection=0;
$current_number="$chapter.$section";
output "<H1><A NAME=\"$current_number\">$chapter.$section</A> ";
if( $element->attribute('ID') ){
$Refs->put("ref:". $element->attribute('ID')->value, $current_number);
}
$toc .= "<BR><A HREF=\"\#$current_number\">$current_number ";
});
sgml('<SECT2>', sub {
my $element = shift;
$subsection++;
$current_number="$chapter.$section.$subsection";
output "<H1><A NAME=\"$current_number\">$chapter.$section.$subsection</A> ";
if( $element->attribute('ID') ){
$Refs->put("ref:". $element->attribute('ID')->value, $current_number);
}
$toc .= "<BR><A HREF=\"\#$current_number\">$current_number ";
});
sgml('<STITLE>', sub{ push_output 'string'; });
sgml('</STITLE>', sub {
my $t = pop_output;
output "$t</H1>";
$toc .= "$t</A>\n";
});
sgml('<P>', "<P>");
sgml('<TT>', "<TT>");
sgml('</TT>', "</TT>");
sgml('<EM>', "<EM>");
sgml('</EM>', "</EM>");
sgml('<EXAMPLE>', "<PRE>\n");
sgml('</EXAMPLE>', "</PRE>\n");
sgml('<A>', sub {
my $element = shift;
my $url = $element->attribute('HREF')->value;
output "<A HREF=\"$url\">";
});
sgml('</A>', sub {
output "</A>";
});
my $link_number = 0;
sgml('<LINK>', sub {
open(LINK, ">$basename.link_$link_number.html") || die "Cannot open link file";
output "<A HREF=\"$basename.link_$link_number.html\">";
});
sgml('<LINKTEXT>', sub { push_output 'string'; });
sgml('</LINKTEXT>', sub {
my $a = pop_output;
output "$a</A>";
print LINK "$a\n";
print LINK "<UL>\n";
});
sgml('<HREF>', sub { push_output 'string'; });
sgml('</HREF>', sub {
my $a = pop_output;
print LINK "<LI><A HREF=\"$a\">$a</A>\n";
});
sgml('</LINK>', sub {
print LINK "</UL>\n";
close LINK;
$link_number++;
});
sgml('<HTML>', sub {
my $element = shift;
my $html = $element->attribute('SRC')->value;
open(H, "$html") || warn "Cannot open $html: $!";
while(<H>){output $_;}
close H;
});
sgml('<IMG>', sub {
my $element = shift;
my $img = $element->attribute('SRC')->value;
unless( $img =~ s/\.eps$/.gif/i ){ $img =~ s/$/.gif/i; }
# output "<CENTER><IMG SRC=\"$img\"></CENTER>\n";
output "<TABLE><TR><TD WIDTH=50></TD><TD><IMG SRC=\"$img\"></TD></TR></TABLE>\n";
});
sgml('<REF>', sub {
my $element = shift;
my $ref = $element->attribute('ID')->value;
my $n = $Refs->get("ref:$ref");
output "<A HREF=\"\#$n\">$n</A>";
});
sgml('<LABEL>', sub {
my $element = shift;
my $ref = $element->attribute('ID')->value;
$Refs->put("ref:$ref", $current_number);
});
sgml('<ITEMIZE>', "<UL>");
sgml('</ITEMIZE>', "</UL>\n");
sgml('<ENUM>', "<UL>");
sgml('</ENUM>', "</UL>\n");
sgml('<ITEM>', "<LI>");
sgml('<DESCRIP>', "<DL>");
sgml('</DESCRIP>', "</DL>\n");
sgml('<TAG>', "<P><DT><STRONG>");
sgml('</TAG>', "</STRONG><DD>");
sgml('<VERB>', sub {
my $element = shift;
my $lang = $element->attribute('LANG')->value;
if( $lang eq "TEX" ){
output "<TABLE><TR><TD WIDTH=50></TD><TD BGCOLOR=$couleur_fond_latex><font color=$couleur_texte_latex><PRE>";
} elsif( $lang eq "PERL" ) {
output "<TABLE><TR><TD WIDTH=50></TD><TD BGCOLOR=$couleur_fond_perl><font color=$couleur_texte_perl><PRE>";
} else {
output "<TABLE><TR><TD WIDTH=50></TD><TD BGCOLOR=$couleur_fond_shell><font color=$couleur_texte_shell><PRE>";
}
});
sgml('</VERB>', "<!PRE></font></TD></TR></TABLE>");
######################################################################
## ???
sgml('&latex;', "\\LaTeX\xspace ");
sgml('&latex;', "\\LaTeX\xspace ");
Correction des fichiers HTML
Toujours à l'aide de sgmlspl.
#! perl -w
use strict;
die "usage: $1 file.html" unless $ARGV[0];
open(HTML,$ARGV[0]) || die "Cannot open $ARGV[0] for reading: $!";
my $tout = join('',<HTML>);
close HTML;
my $new = "";
while( $tout =~ s/^(.*?)SRC\=\"([^"]*)\"//s ){ #"
my $avant = $1;
my $file = $2;
print STDERR "Looking for the size of $file\n";
open(SIZE, "file $file /dev/null|") ||
warn "Cannot run `file $file /dev/null': $!";
# warn "Cannot run `convert -verbose $file /dev/null': $!";
my $tmp = join('',<SIZE>);
close SIZE;
my($width,$height)=(10,10);
if($tmp =~ m/([0-9]+) x ([0-9]+)/){
$width = $1;
$height = $2;
}
print STDERR " width: $width height: $height\n";
$new .= "$avant WIDTH=$width HEIGHT=$height SRC=\"$file\" ";
}
$new .= $tout;
open(HTML, ">$ARGV[0]") || die "Cannot open $ARGV[0] for writing: $!";
print HTML $new;
close HTML;
Conversion vers LaTeX
##
## À FAIRE
##
## <URL URL="..." NAME="..."> (mettre l'URL en note de bas de page)
## Les caractères spéciaux de LaTeX
## La chaîne de caractères « LateX » doit être transformée en {\LaTeX}
## <VERB>
## (n'y a-t-il pas de problème d'espaces superflus ???)
## Et s'il y a des < et des > à l'intérieur ???
## (Il y en a...)
## <TSCREEN> : à enlever... Non... Si...
## <EM>
##
## Dans le même ordre d'idées, prévoir un convertisseur SGML -> SGML.
## qui rajouterait toutes les balises manquantes.
##
use SGMLS;
use SGMLS::Output;
use SGMLS::Refs;
$basename = shift;
sgml('start', sub {
system("touch .redo_$basename");
$Refs = new SGMLS::Refs("$basename.refs");
});
sgml('end', sub {
unlink(".redo_$basename") unless $Refs->warn;
});
######################################################################
sgml('cdata', sub {
my($text,$event) = @_;
unless($event->element->name eq 'VERB'){
$text =~ s/\\/\\textbackslash /g;
$text =~ s/\{/\\\{/g;
$text =~ s/\}/\\\}/g;
$text =~ s/\\textbackslash /\{\\textbackslash\}/g;
$text =~ s/\&/\\\&/g;
$text =~ s/\~/{\\textasciitilde}/g;
$text =~ s/\#/\\\#/g;
$text =~ s/\_/{\\textunderscore}/g;
$text =~ s/\^/{\\textasciicircum}/g;
$text =~ s/\$/{\\textdollar}/g;
$text =~ s/\%/\\\%/g;
$text =~ s/\*/{\\textasterixcentered}/g;
$text =~ s/\</{\\textless}/g;
$text =~ s/\>/{\\textgreater}/g;
}
output $text;
});
######################################################################
sgml('<DOCUMENT>', "\\documentclass[openany]{book}\n\n" .
"\\usepackage[latin1]{inputenc}\n" .
"\\usepackage[T1]{fontenc}\n" .
"\\usepackage{url}\n" .
"\\usepackage{frxspace}\n" .
"\\usepackage[left=1cm,right=1cm,top=1cm,bottom=1cm,nofoot]{geometry}\n" .
"\\usepackage{graphicx}\n" .
"\\usepackage{longtable}\n" .
"\\usepackage{textcomp,wasysym,pifont,marvosym,stmaryrd,yhmath,amsmath,amssymb}\n" .
"\\usepackage{french}\n" .
"\\usepackage{boites,boites_exemples}\n" .
"\\providecommand{\\textasterixcentered}{*}\n".
"\\newenvironment{example}{\\par\\bigskip\\noindent\\textbf{Exemple : }}{\\bigskip}\n".
"\\newenvironment{simpleverb}{\\par\\medskip\\parindent=0pt\\obeylines\\obeyspaces\\ttfamily}{\\medskip}\n".
"\\newenvironment{tscreen}{\\begin{boitecoloriee}}{\\end{boitecoloriee}}\n".
"");
sgml('</DOCUMENT>', "\\end{document}\n");
sgml('<TITLE>', "\\title{");
sgml('</TITLE>', "}\n");
sgml('<AUTHOR>', "\\author{");
sgml('</AUTHOR>', "}\n");
sgml('<DATE>', "\\date{");
sgml('</DATE>', "}\n");
sgml('</HEAD>', "\\begin{document}\n\\maketitle\n\n");
sgml('<ABSTRACT>', "\\begin{abstract}\n");
sgml('</ABSTRACT>', "\\end{abstract}\n\n");
sgml('<TOC>', "\\tableofcontents\n\n");
my $next_label=undef;
sgml('<SECT>', sub {
my $element = shift;
output "\n\\chapter";
if( $element->attribute('ID') ){ $next_label = $element->attribute('ID')->value; }
});
sgml('<SECT1>', sub {
my $element = shift;
output "\n\\section";
if( $element->attribute('ID') ){ $next_label = $element->attribute('ID')->value; }
});
sgml('<SECT2>', sub {
my $element = shift;
output "\n\\subsection";
if( $element->attribute('ID') ){ $next_label = $element->attribute('ID')->value; }
});
sgml('<STITLE>', "{");
sgml('</STITLE>', sub {
if( $next_label ){ output "}\\label{$next_label}\n\n"; }
else { output "}\n\n"; }
$next_label = undef;
});
sgml('</P>', "\n\n");
sgml('<TT>', "\\texttt{");
sgml('</TT>', "}");
sgml('<EM>', "\\emph{");
sgml('</EM>', "}");
sgml('<EXAMPLE>', "\\begin{example}\n");
sgml('</EXAMPLE>', "\\end{example}");
my $url;
sgml('<A>', sub {
my $element = shift;
$url = $element->attribute('HREF')->value;
});
sgml('</A>', sub { output "\\footnote{\\url{$url}}"; });
sgml('<IMG>', sub {
my $element = shift;
my $img = $element->attribute('SRC')->value;
unless( $img =~ s/\.gif$/.eps/i ){ $img =~ s/\$/.eps/i; }
# output "\\begin{center}\\includegraphics{$img}\\end{center}";
output "\\begin{center}\\begin{boiteavecunelignequiondulesurlecote}\\includegraphics{$img}\\end{boiteavecunelignequiondulesurlecote}\\end{center}";
});
sgml('<LATEX>', sub {
my $element = shift;
my $latex = $element->attribute('SRC')->value;
open(L, "$latex") || warn "Cannot open $latex: $!";
while(<L>){output $_;}
close L;
});
sgml('<LINK>', sub {} );
sgml('<LINKTEXT>', sub {} );
sgml('</LINKTEXT>', sub {} );
my $first_link = TRUE;
sgml('<HREF>', sub {
output "\\textsuperscript{,}" unless $first_link;
$first_link = FALSE;
output "\\footnote{\\url{";
});
sgml('</HREF>', sub {
output "}}";
});
sgml('</LINK>', sub {
$first_link = TRUE;
});
sgml('<REF>', sub {
my $element = shift;
my $ref = $element->attribute('ID')->value;
output "\\ref{$ref}";
});
sgml('<LABEL>', sub {
my $element = shift;
my $ref = $element->attribute('ID')->value;
output "\\label{$ref}";
});
sgml('<ITEMIZE>', "\\begin{itemize}");
sgml('</ITEMIZE>', "\\end{itemize}\n");
sgml('<ENUM>', "\\begin{enumerate}");
sgml('</ENUM>', "\\end{enumerate}\n");
sgml('<ITEM>', "\\item ");
sgml('<DESCRIP>', "\\begin{description}");
sgml('</DESCRIP>', "\\end{description}\n");
sgml('<TAG>', "\\item[");
sgml('</TAG>', "]");
#sgml('<VERB>', "\\begin{simpleverb}\n");
#sgml('</VERB>', "\\end{simpleverb}");
sgml('<VERB>', "\\begin{tscreen}\\begin{verbatim}\n");
sgml('</VERB>', "\\end{verbatim}\\end{tscreen}");
#sgml('<HTML>', sub { push_output 'nul' } );
#sgml('</HTML>', sub { pop_output } );
#sgml('<LATEX>', '');
#sgml('</LATEX>', '');
######################################################################
## ???
sgml('&latex;', "\\LaTeX\xspace ");
sgml('&latex;', "\\LaTeX\xspace ");
Vincent Zoonekynd
(zoonek@math.jussieu.fr)
Last modified: Mon Aug 7 13:51:30 CEST 2000