package latex;
import java.util.List;
import pregroup.PhraseString;
import pregroup.TypeLink;
import pregroup.TypeReduction;
//! Creates a TikZ output from a parsing reduction
public class TikzReduction {
private static final String tikzHeader =
"\\begin{tikzpicture}[\n"+
"every node/.style={%\n"+
"text height=1.5ex," +
"text depth=0.25ex,"+
"}]\n"+
"% Diagram generated by http://github.com/wetneb/MorozParser"+
"\n\n";
private static final String tikzFooter = "\n\\end{tikzpicture}\n";
//! Vertical space between the types and the links below them
private static final double distToTypes = 0.25;
//! Horizontal space between two simple types in the same word
private static final double typeSpacing = 0.4;
//! Horizontal space between the types of two words
private static final double wordSpacing = 1.1;
//! Vertical space between the original words and their types
private static final double textDistance = 0.5;
public static String draw(PhraseString phrase, List<String> words, TypeReduction red)
{
int n = phrase.size();
double[] pos = new double[n];
boolean[] used = new boolean[n];
String output = tikzHeader;
//! Compute the used types
for(int i = 0; i < n; i++)
used[i] = false;
for(TypeLink l : red)
{
used[l.start] = true;
used[l.end] = true;
}
//! Compute the position of the used types
double curPos = 0;
int curWord = 0;
int nbTypes = 0;
double sumPos = 0;
for(int i = 0; i < n-1; i++)
{
if(used[i])
{
pos[i] = curPos;
sumPos += curPos;
nbTypes++;
output += "\\node at ("+curPos+",0) (t"+i+") {$"+phrase.get(i).toLatex()+"$};\n";
curPos += typeSpacing;
}
else if(phrase.get(i).isRB() && nbTypes > 0)
{
output += "\\node at ("+(sumPos/nbTypes)+","+textDistance+") (w"+curWord+") {"+words.get(curWord)+"};\n";
curWord++;
sumPos = 0;
nbTypes = 0;
curPos += wordSpacing-typeSpacing;
}
}
//! Compute the maximum radius
double maxRad = 0;
for(TypeLink l : red)
{
double rad = (pos[l.end] - pos[l.start])/2.;
if(rad > maxRad && l.end != n-1)
maxRad = rad;
}
output += "\n";
//! Draw the curves
for(TypeLink l : red)
{
double from = pos[l.start];
double to = pos[l.end];
if(l.end != n-1)
{
double radius = (to - from)/2.;
double center = (from + to) /2.;
output += "\\draw ("+from+",-"+distToTypes+")"+
" .. controls ("+from+",-"+(distToTypes+0.555*radius)+")"+
" and ("+(center-0.555*radius)+",-"+(distToTypes+radius)+")"+
" .. ("+center+",-"+(distToTypes+radius)+")"+
" .. controls ("+(center+0.555*radius)+",-"+(distToTypes+radius)+")"+
" and ("+to+",-"+(distToTypes+0.555*radius)+")"+
" .. ("+to+",-"+distToTypes+");\n";
}
else
{
output += "\\draw ("+from+",-"+distToTypes+") -- ("+from+",-"+(distToTypes+maxRad)+");\n";
}
}
output += tikzFooter;
return output;
}
}