Metapost 中的语言学风格树

Metapost 中的语言学风格树

我正在尝试找到绘制语言学风格树的最佳方法,这种方法尽可能不受所用 TeX 种类的影响(LaTeX、ConTeXt 或普通 TeX)。可以理解的是,大多数绘制树的方法都是为 LaTeX(变体qtreeforest)设计的,并且不容易适应 ConTeXt 或普通 TeX。

我的第一个想法是使用 METAPOST 绘制树木并将结果作为 PDF 或 PS 图形包含在内,因为这样可以消除对 TeX 变体的任何依赖。我发现metaobjMETAPOST 包使绘制树木变得容易。例​​如,我有以下 MWE:

input metaobj;

prologues:=3;

beginfig(1);

    setObjectDefaultOption("Tree")("hbsep")(5mm);
    setObjectDefaultOption("Tree")("treenodehsize")(2cm);
    setCurveDefaultOption("arrows")("draw");

    t:=_T(Tr_(btex VoiceP etex))
        (
            Tr_(btex \vbox{\hbox{DP}\hbox{He}} etex),
            _T(Tr_(""))
            (
                Tr_(btex Voice etex),
                Tr_(btex \vbox{\hbox{$v$P}\hbox{runs}} etex)
            )
        );

    Obj(t).c=origin;
    draw_Obj(t);
    
endfig;

Metapost 树

为了进行比较,我将包括用以下方法制作的同一棵树qtree

\documentclass{standalone}

\usepackage{qtree}

\begin{document}
    \Tree [.VoiceP [.DP\\He ] [ [.Voice ] [.$v$P\\runs ] ] ]
\end{document}

QTree 树

METAPOST 版本已实现 90% 的功能,但在metaobj绘制树的方式上存在一些问题:

  1. 每个节点的分支都是从不同的点绘制的,而不是从节点中心底部的公共点绘制的。
  2. 整个树的分支角度和分支长度并不一致。理想情况下,它们应该是相同的,这样节点文本的高度就不会过多地改变树结构,无节点的分支也不会弯曲。
  3. 我不确定如何使多行标签居中。

如何metaobj使用 /METAPOST 来获得所需的树样式?退一步说,从 METAPOST 来看,这是以这种风格绘制树的最佳方式吗?这种方式与所用的 TeX 变体无关。我选择 METAPOST,因为它生成的图表可以轻松用于任何类型的 TeX,它允许在绘图例程中包含 TeX 代码(例如,切换字体),并且它可以生成高质量的图形,支持许多有用的东西(例如,使用常规 METAPOST 箭头绘制移动箭头、颜色、所有常规绘图功能、支持同一文件中的多个图形等)。

答案1

免责声明:这不是 Metapost 中的解决方案,但它可能有用。

正如 Alan Munn 所评论的,TikZ/PGF 是通用的,因此tikz-qtree应该可以移植到 Plain TeX 和 ConTeXt。forest也是基于 TikZ/PGF,但由于其对 LaTeX 的依赖,因此很棘手。以下是tikz-qtreeConTeXt 中的一个例子,我并不为此感到自豪,但它是一个概念证明。

\usemodule[tikz]

\unprotect
%Shamelessly taken from:
%https://wiki.contextgarden.net/LaTeX_Math_in_ConTeXt
\let\@@end=\end
\appendtoks
\let\end=\@@end
\to \everystoptext

%This is really ad hoc.
%It will possibly break things when you try
%loading other packages better suited
%to LaTeX
\def\begin#1{%
    \csname #1\endcsname}
\def\end#1{%
    \csname end#1\endcsname}

\input pgfsubpic.tex
\input pgftree.tex
\input tikz-qtree.tex
\protect  

\starttext
\starttikzpicture
[level distance=40pt]
\Tree [.S [.NP [.N this ] ]
[.VP [.V is ]
[.NP \edge[roof]; {a noun phrase} ] ] ]
\stoptikzpicture
\stoptext

在此处输入图片描述

由于某种原因,类似的 Plain 方法对我来说不起作用,而且我也没有想到,因为我不是 Plain 用户,但正如您所见,这是可行的。

答案2

免责声明:此在 Metapost 中,但这实际上并不是该问题的正确答案。

当然,也可以画出任何事物与 Metapost 配合得很好,比如你的树的这个版本:

在此处输入图片描述

但正如您在下面看到的,我并没有使用qtree-like 语法来做到这一点。您是否认为这“简单”取决于您的观点、经验、您想要做的树的数量等。

您可以花时间编写一些处理qtree符号的 MP,或者进行修补metaobj,或者为您自己的符号编写宏,或者您可以一次画一棵树,如下所示:

prologues := 3;
outputtemplate := "%j%c.eps";

beginfig(1);

    numeric dx, dy;
    dx = 34; dy = -13; 

    z0 = origin;
    z1 = z0 + (-dx, dy);
    z2 = z0 + (+dx, dy);

    z21 =  z2 + 3/4(-dx, dy);
    z22 =  z2 + 3/4(+dx, dy);

    z100 = (x1, 3dy); 
    z200 = (x22, 3dy);

    draw z1 -- z0 -- z2;
    draw z21 -- z2 -- z22;

    label.top(btex VoiceP etex, z0);

    picture p[];
    p1  = thelabel.bot(btex DP etex, z1);
    p21 = thelabel.bot(btex Voice etex, z21);
    p22 = thelabel.bot(btex {\it v\/}P etex, z22);
    p100 = thelabel.bot(btex \strut He etex, z100);
    p200 = thelabel.bot(btex \strut runs etex, z200);
    forsuffixes $=1, 21, 22:
        draw p$;
    endfor
    forsuffixes $=100, 200: 
        draw p$ withcolor 2/3 blue;
    endfor
    
    vardef connect(suffix a, b) = 
        draw point 1/2 of bbox p.a -- point 5/2 of bbox p.b dashed withdots scaled 1/4;
    enddef;
    connect(1, 100);
    connect(22, 200);

    undraw bbox currentpicture; % add a small margin
    
endfig;
end.

关于您遇到的具体问题metaobj

  • 我看不出有什么简单的方法可以让它按照你想要的方式绘制线条——它瞄准每个节点的中心并在边界框处切割线条,这意味着线条通常处于不同的角度。似乎没有任何选项可以让它以规则的角度绘制线条。

  • 多行标签居中是一个简单的 TeX 问题,而不是一个metaobj问题。每个标签都像往常一样放在一个位置\hbox,因此您可以在文件顶部附近添加一个这样的块

     verbatimtex
     \def\s#1{\vbox{\let\\\cr\halign{\hfil ##\hfil\cr #1\crcr}}}.  
     etex
    

    然后你可以做类似的事情:label(btex \s{Above\\below} etex, origin);

相关内容