在我最近提出的問題取得了非常有成效的成果之後語調,我有底氣來問一個相關的問題。在前一種方法中,特定的音高水平被連接起來以產生語調輪廓,但是對於聲調語言(單字中的每個音節通常都有與之相關的特定音高),需要一種不同的方法,其中音高水平由小水平線指示我有幾種已經有效的方法,現在我根據 Matthew Leingang 解決前一問題的方法創建了一個新的 TikZ 方法,但我確信可以在下面的 MWE 中列出這些選項。 ,使用非洲班圖語kiKongo 的範例。
%!TEX TS-program = xelatex
%!TEX encoding = UTF-8 Unicode
\documentclass{article}
\usepackage{fontspec}
\defaultfontfeatures{Mapping=tex-text, Scale=MatchLowercase}
\setmainfont{Charis SIL}
\usepackage{tikz}
\usetikzlibrary{backgrounds}
\newcommand{\tikzpitch}[1]{\tikz[overlay, remember picture, baseline] \coordinate (#1);}%
\tikzstyle{pitchlevel}=[x=1mm, y=1mm, yshift=-7mm, semithick]
% Charis SIL pitchlevel glyphs
\newcommand \pitch[1]{\char"F1F#1} % use \pitch1..9 to generate the 9 pitch-level marks fromthe glyphs F1F{1..9}
% John Frampton's pitchlevels code
\usepackage{pstricks}
\newdimen\dimpla
\newdimen\dimplb
\newdimen\dimplc
\def\1{\contourpitch{-2.5ex}{-2.5ex}}
\def\2{\contourpitch{-2.1ex}{-2.1ex}}
\def\3{\contourpitch{-1.7ex}{-1.7ex}}
\def\4{\contourpitch{-1.3ex}{-1.3ex}}
\def\5{\contourpitch{-.9ex}{-.9ex}}
\def\6{\contourpitch{-.5ex}{-.5ex}}
% level pitches
\def\contourpitch #1#2#3{\setbox0=\hbox{#3}\dimpla=.5\wd0 \dimplb=.5\wd0
\advance\dimpla by -.25em
\advance\dimplb by .25em
\dimplc=#1
\ifdim#2<#1 \dimplc=#2 \fi
\dimplc=-\dimplc
\advance\dimplc by 1ex
\psline(\dimpla,#1)(\dimplb,#2)
\vrule width0pt depth\the\dimplc #3}
% glides
\def\pitchup{\contourpitch{-2.5ex}{-1.7ex}}
\def\pitchdown{\contourpitch{-1.7ex}{-2.5ex}}
\def\steepup{\contourpitch{-2.5ex}{-.5ex}}
% format fbox
\setlength\fboxsep{1pt}
\begin{document}
% generate glides in Charis SIL
\fontspec[Renderer=Graphite]{Charis SIL}
\section{Pitchlevel marking using xelatex}
In Africanist linguistics, pitchlevel marks are often used so that the pitches can be discussed without drawing premature conclusions as to how these pitches should be represented in the eventual tone-marking.
\subsection{Word-side (inline) marking}
The example of \textbf{ibuuna [~\pitch1\, \pitch9\pitch9\, \pitch1~]} (\textit{so}) can be used to show inline marking of individual words. This solution uses the pitchlevel glyphs in Charis SIL. Glide variants are possible:
[~\pitch1\, \pitch9\, \pitch1\pitch5~]
[~\pitch1\, \pitch9\, \pitch1\pitch1\pitch5~]
[~\pitch1\, \pitch9\, \pitch1\pitch1\pitch5\pitch5~]
[~\pitch1\, \pitch9\, \pitch1\pitch5\pitch5~]
\bigskip
\noindent An alternative solution to the same issue of showing \noindent \textbf{ibuuna} [ \tikz\draw[x=1mm, y=1mm, semithick](0,0)--(1.5,0) (2.5,2)--(5,2) (6,0)--(7.5,0); ] uses TikZ. Glide variants are also possible here:
[ \tikz\draw[x=1mm, y=1mm, semithick](0,0)--(1.5,0) (2.5,2)--(5,2) (6,0)--(7.5,1); ]
[ \tikz\draw[x=1mm, y=1mm, semithick](0,0)--(1.5,0) (2.5,2)--(5,2) (6,0)--(7.5,0)--(8.5,1); ]
[ \tikz\draw[x=1mm, y=1mm, semithick](0,0)--(1.5,0) (2.5,2)--(5,2) (6,0)--(7.5,0)--(8.5,1)--(10,1); ]
[ \tikz\draw[x=1mm, y=1mm, semithick](0,0)--(1.5,0) (2.5,2)--(5,2) (6,0)--(7.5,1)--(9,1); ]
\subsection{Parallel marking}
\subsubsection{Using Charis font features}
\noindent ibuuna · basiidi kilumbu · ki-bakweenda kuna-kiziitu \\
\pitch1~~\pitch9\pitch9~~\pitch1~~~\pitch1~~\pitch9~~\pitch7~~\pitch5~\pitch3~~~~~\pitch1\pitch5 ~~~~\pitch1~~~\pitch1~~~~\pitch9\pitch9~~~\pitch8~~~\pitch4~~\pitch1~~~\pitch5~\pitch5~\fbox{\pitch1\pitch5} \\
\textit{so · they set aside a day · on which they would go to the in-laws \dots}
\subsubsection{Using pstricks}
\noindent\1ib\5u\5un\1a · b\1as\5i\5id\4i k\3il\2umb\pitchup u · k\1i-b\1akw\5e\5end\4a k\3un\1a-k\3iz\3i\3it\fbox{\pitchup u}\\
\textit{so · they set aside a day · on which they would go to the in-laws \dots}
\subsubsection{Using TikZ}
\noindent\begin{tikzpicture}[remember picture]
\node{\tikzpitch{1}ib\tikzpitch{2}u\tikzpitch{3}un\tikzpitch{4}a · b\tikzpitch{5}as\tikzpitch{6}iid\tikzpitch{7}i k\tikzpitch{8}il\tikzpitch{9}umb\tikzpitch{10}u · k\tikzpitch{11}i-b\tikzpitch{12}akw\tikzpitch{13}eend\tikzpitch{14}a k\tikzpitch{15}un\tikzpitch{16}a-k\tikzpitch{17}iz\tikzpitch{18}iit\tikzpitch{19}u}; \\
\draw[pitchlevel] (1 |- 0,0)--+(2,0) (2 |- 0, 4.5)--+(2,0) (3 |- 0, 4.5)--+(2,0) (4 |- 0, 0)--+(2,0) (5 |- 0,0)--+(2,0) (6 |- 0, 4.5)--+(2,0) (7 |- 0, 4)--+(2,0) (8 |- 0, 3)--+(2,0) (9 |- 0,1.5)--+(2,0) (10 |- 0, 0)--+(1,0.5)--+(2,1.5) (11 |- 0,0)--+(2,0) (12 |- 0, 0)--+(2,0) (13 |- 0, 4.5)--+(3,0) (14 |- 0, 3.5)--+(2,0) (15 |- 0,3)--+(2,0) (16 |- 0, 1)--+(2,0) (17 |- 0, 3)--+(2,0) (18 |- 0, 3)--+(2,0) (19 |- 0,0)--+(1,0.5)--+(2,1.5);
\end{tikzpicture}\\
\mbox{\textit{so · they set aside a day · on which they would go to the in-laws \dots}}
\end{document}
內聯標記(1.1)很簡單。關於並行標記的三個版本(1.2):
1.2.1:Charis SIL 只能與 XeTeX 一起使用。 (對於 LaTeX,有一種使用tipa
套件和一些附加程式碼的替代方法 - 請參閱這個問題.)這似乎是目前唯一包含這些字形(在其私人使用區域中)的字體,但實際上這不太可能成為問題。主要問題是,就像在語調問題中一樣,有必要使用反覆試驗來間隔字形以匹配單字。一個好處是可以用來\fbox
突出顯示特定的音調。
1.2.2:此pstricks
代碼由 的作者 John Frampton 慷慨提供expex
。主要好處是它將音高嵌入到文本中,從而更容易寫出範例。 An\fbox
可用於突出顯示音高(儘管它也標記字母,但視覺吸引力較差)。音高線也比其他兩個選項「更尖銳」。與此相反,編譯速度較慢,且目前程式碼不允許字側(內聯)間距標記。 (它似乎也不適用於 LaTeX,但也許這只是我的問題。)
1.2.3:這是我透過騷擾 Matthew Leingang 對語調問題的解決方案而整理出來的(我什至不知道從哪裡開始使用 mwibrow 更全面的代碼!)。我所做的就是取得座標,然後從該座標到向右 2mm 的點畫一條線。 (理想情況下,我會在坐標的每一側繪製 1 毫米,但是如何繪製?)這實際上效果很好 - 特別是可以更詳細地指定滑動。然而,就目前情況而言,它需要兩次編譯,因為remember picture
我無法突出顯示一個音高。此外,出於某種原因,kiKongo 文字似乎略有縮排。
所有這些都有效,但我對任何改進建議很感興趣,特別是整理 TikZ 解決方案,因為它適用於 LaTeX 和 XeTeX,並且與字體無關。
答案1
編輯添加一些修復和內聯使用的範例(可能應該綁定在巨集中)。
透過對語調問題的程式碼進行一些額外的添加(我在此處提供整個程式碼,因為它包含許多修復),可以添加標記。不確定字體無關,可能不是現在的樣子。當然,如果不做額外的工作,從右到左的語言就會很垃圾。
基本概念是將符號與標記相關聯,然後在字元排版後對其進行解析。主要目的是能夠將標記符號對齊在文字上方,這看起來比在文字中放置標記要乾淨一些。
\contour[contour marks={0.55.0..0.55.?..3.2..+..0..0..5|..!..3.2..3.33.+}]
{ibuuna basiidi kilumbu ki-bakweenda kuna-kiziitu};
下面顯示的範例在語言上不應該是正確的,而只是說明它可以做什麼。
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{fit}
\newdimen\contourraise
\newdimen\contourspacetokenwidth
\newdimen\contourtokenkern
\newcount\lasttokennumber
\newcount\currenttokennumber
\newcount\contourmarkcount
\newcount\contourtokenunderlinestate
\newbox\contourbox
\makeatletter
\tikzset{
tight fit/.style={
inner sep=0pt,
outer sep=0pt,
},
%
%
% How far above the reference anchor of the text,
contour raise/.code=\pgfmathsetlength\contourraise{#1},
contour reference anchor/.store in=\contourreferenceanchor,
contour reference anchor=base east,
% The `scale' for the values in the contour height specification
contour scale/.store in=\contourscale,
contour scale=3pt,
% The prefix for the contour marks.
contour mark prefix/.store in=\contourmarkprefix,
contour mark prefix=contour,
% The style for the contour path
contour/.style={
draw,
rounded corners=1ex,
},
% The style for the token nodes
every contour token/.style={
anchor=base west,
tight fit,
},
contour underline/.style={
draw
},
% The character to insert a mark (use with care)
contour mark character/.store in=\contourmarkchar,
contour mark character=|,
% Want to change the code for contour marks? Use this key.
contour mark code/.store in=\contourmarkcode,
% Want to change the code for tokens? Use this key.
contour token code/.store in=\contourtokencode,
% Want to change the code for drawing the contour? Use this key.
contour code/.store in=\contourcode,
%
% Default stuff
contour mark code={%
\coordinate (\contourmarkprefix-\the\contourmarkcount)
at ([yshift=\contourraise, y=\contourscale,
shift={(0,\currentcontourheight)}]token-\the\currenttokennumber.\contourreferenceanchor);
},
contour token code={%
\node [every contour token/.try] at
([xshift=\contourtokenkern]token-\the\lasttokennumber.base east)
(token-\the\currenttokennumber) {\token};
},
contour code={
\draw [contour] (\contourmarkprefix-1)
\foreach \y in {2,...,\the\contourmarkcount}{ --
(\contourmarkprefix-\y) };
},
contour marks/.style={
contour mark list={#1},
contour code={
\draw [y=\contourscale, contour] \contourpath;
},
contour mark code={%
\coordinate (@a) at ([yshift=\contourraise]token-\the\currenttokennumber.base west);
\coordinate (@b) at ([yshift=\contourraise]token-\the\currenttokennumber.base east);
\node [tight fit, fit={(@a) (@b)}] (\contourmarkprefix-\the\contourmarkcount) {};
},
},
% Don't draw the contour.
tokens only/.style={
contour code={}
},
%
% Only draw the contour (but the space is still used for the tokens)
contour only/.style={
every contour token/.append style={
execute at begin node={\setbox\contourbox=\hbox\bgroup},
execute at end node=\egroup\phantom{\box\contourbox}%
},
underline/.style={
draw=none
}
},
%
% Make tokens follow the contour marks.
tokens follow contour/.style={
tokens only,
contour token code={%
\node [every contour token/.try, y=\contourscale] at
([xshift=\contourtokenkern]token-\the\lasttokennumber.base east |-
0,\currentcontourheight)
(token-\the\currenttokennumber) {\token};
},
},
% What style to use when drawing underline
underline/.style={
draw
},
% The underline is drawn along the south side of a node which
% takes this style.
underline token/.style={
inner ysep=1pt
},
% When grouping tokens (e.g., for putting box around)
% this style is applied to a node that is fitted around the group
token group/.style={
inner xsep=1pt,
inner ysep=2pt,
rounded corners=2pt
},
% Draw boxes around tokens groups.
box tokens/.style={
token group/.append style={
draw
}
},
% Change the width of the spaces.
space token width/.code=\pgfmathsetlength\contourspacetokenwidth{#1},
space token width=0.125cm,
contour mark list/.store in=\@contourmarklist%
}
\def\at@{@}
\let\@contourmarklist=\@empty
\def\contour{%
\pgfutil@ifnextchar[{\contour@opts}{\contour@opts[]}}
\def\contour@opts[#1]{%
\pgfutil@ifnextchar x{\contour@@opts[#1]}{\contour@@opts[#1]}}
\def\contour@@opts[#1]#2;{%
\begin{scope}[#1]
\coordinate (token-0);
\currenttokennumber=0\relax%
\lasttokennumber=0\relax%
\contourmarkcount=0\relax%
\def\lastcontourheight{0}%
\contourtokenunderlinestate=0\relax%
\let\lastcontourtoken=\relax%
\contourtokenkern=0pt\relax%
\def\contourpath{}%
\@contour#2@%
}
% Must check for a spaces
\def\@contour{\futurelet\@token\@checkforspace}
\def\@uscore{_}
\def\@checkforspace{%
\ifx\@token\pgfutil@sptoken%
\let\@next=\@replacespace%
\else%
\if\@token\contourmarkchar%
\let\@next=\@contour@insertmark
\else%
\if\@token\@uscore
\let\@next=\@contourtoggleunderline%
\else%
\let\@next=\@@contour%
\fi%
\fi%
\fi%
\@next%
}
\def\@contourtoggleunderline#1{%
\advance\contourtokenunderlinestate by1\relax
\ifnum\contourtokenunderlinestate>3\relax%
\contourtokenunderlinestate=0\relax%
\fi%
\@contour%
}
\def\@contour@insertmark{%
\afterassignment\@@contour@insertmark\let\@token=%
}
\def\@@contour@insertmark{%
\futurelet\@token\@@@contour@insertmark}%
\def\@@@contour@insertmark{%
\if\@token[%
\let\@next=\@@@@contour@insertmark%
\else%
\let\currentcontourheight=\lastcontourheight%
\let\@next=\@@@@@contour@insertmark%
\fi%
\@next%
}
\def\@@@@contour@insertmark[#1]{%
\def\@tmp{#1}%
\ifx\@tmp\@empty%
\let\currentcontourheight=\lastcontourheight%
\else%
\def\currentcontourheight{#1}%
\fi%
\@@@@@contour@insertmark}
\def\@@@@@contour@insertmark{%
\advance\contourmarkcount by1\relax%
% Code for inserting mark
\contourmarkcode%
\let\lastcontourheight=\currentcontourheight%
\@contour}
\def\contourspacetoken{{\hbox to \contourspacetokenwidth{\hfill}}}
\def\@replacespace#1{%
\@contour\contourspacetoken#1%
}
\def\@@countour@afterlatenode{%
\pgf@x=\pgfpositionnodelatermaxx\relax%
\advance\pgf@x by-\pgfpositionnodelaterminx\relax%
\global\edef\@contournodewidth{\the\pgf@x}%
}
\def\@@contour#1{%
\def\@token{#1}%
\if\@token\at@%
\@contourdounderline%
\pgfutil@ifundefined{pgf@sh@ns@tokengroup}{}{%
\node [tight fit, fit={(tokengroup)}, token group/.try] {};
\global\let\pgf@sh@ns@tokengroup=\relax%
}%
\let\@next=\@@@contour%
\else%
\lasttokennumber=\currenttokennumber%
\advance\currenttokennumber by1%
\contourtokenkern=0pt\relax%
\ifnum\currenttokennumber>1\relax%
%
% Take care of kerning.
%
% First get the width of the last and current token in the same hbox.
%
\let\pgfpositionnodelaterbox=\contourbox
\pgfpositionnodelater\@@countour@afterlatenode%
\def\token{\lastcontourtoken\@token}%
\begingroup%
\tikzset{every contour token/.append style={tight fit}}%
\contourtokencode%
\endgroup%
\let\@contourkerntmp=\@contournodewidth%
%
% Now subtract the width of last and current token in separate boxes.
%
\def\token{\hbox{\lastcontourtoken}\hbox{\@token}}%
\begingroup%
\tikzset{every contour token/.append style={tight fit}}%
\contourtokencode%
\endgroup%
\pgfmathsetlength\contourtokenkern{\@contourkerntmp-\@contournodewidth}%
\pgfpositionnodelater\relax%
\fi%
%
% OK, now actually typset the current token
%
\let\token=\@token%
\contourtokencode%
\let\lastcontourtoken=\token%
% Manage underline state
\@contourdounderline%
\def\@@token{\contourspacetoken}%
\ifx\@token\@@token%
\pgfutil@ifundefined{pgf@sh@ns@tokengroup}{}{%
\pgfutil@ifundefined{pgf@sh@ns@underline}{}{%
\node [tight fit, fit={(tokengroup) (underline)}]
(tokengroup)
{};}%
\node [tight fit, fit={(tokengroup)}, token group/.try] {};
\global\let\pgf@sh@ns@tokengroup=\relax%
}%
\else
\pgfutil@ifundefined{pgf@sh@ns@tokengroup}{%
\node [tight fit,
fit={(token-\the\currenttokennumber)}]
(tokengroup) {};
}{%
\node [tight fit,
fit={(token-\the\currenttokennumber)
(tokengroup)}]
(tokengroup){};
}%
\fi%
\let\@next=\@contour
%
\fi%
\@next%
}
\def\@contourdounderline{%
\ifcase\contourtokenunderlinestate%
\or
\node [tight fit, fit={(token-\the\currenttokennumber)}]
(underline) {};
\contourtokenunderlinestate=2\relax%
\or%
\node [tight fit,fit={(token-\the\currenttokennumber) (underline)}]
(underline) {};
\or%
\node [tight fit, fit={(underline)}, underline token/.try]
(underline) {};
\draw [underline/.try]
(underline.south west) -- (underline.south east);
\pgfutil@ifundefined{pgf@sh@ns@tokengroup}{}{%
\node [tight fit, fit={(tokengroup) (underline)}]
(tokengroup) {};%
\node [tight fit, fit={(tokengroup)}, token group/.try] {};
\global\let\pgf@sh@ns@tokengroup=\relax%
\global\let\pgf@sh@ns@underline=\relax%
}
\contourtokenunderlinestate=0\relax
\fi%
}
\def\@@@contour{%
\ifx\@contourmarklist\@empty%
\else%
\@contourdolist%
\fi%
\ifnum\contourmarkcount>1
% Code for drawing contour
\contourcode%
\fi%
\end{scope}%
\ignorespaces%
}
\def\@contourstackpop{%
\let\@contourstackitem=\@empty%
\ifx\@contourstack\@empty%
\else%
\expandafter\@@contourstackpop\@contourstack\@@contourstackpop%
\fi%
}
\def\@@contourstackpop#1#2\@@contourstackpop{%
\def\@contourstackitem{#1}%
\ifx\@contourstackitem\@empty%
\def\@contourstackitem{#2}%
\let\@contourstack=\@empty%
\else%
\def\@contourstack{#2}%
\fi%
}
\def\@contourdolist{%
\let\@contourstack=\@contourmarklist%
\let\@contourstacklastitem=\@empty%
\let\contourpath=\@empty%
\edef\contourtotaltokens{\the\currenttokennumber}%
\currenttokennumber=0\relax%
\contourmarkcount=0\relax%
\@@contourdolist%
}
\def\@@contourdolist{%
\@contourstackpop%
\advance\currenttokennumber by1\relax%
\ifx\@contourstackitem\@empty%
\let\@next=\relax%
\else%
\expandafter\ifx\csname contourcontourpathcommand@\@contourstackitem @\endcsname\relax%
\else%
\advance\contourmarkcount by1\relax%
\let\currentcontourheight=\@contourstackitem%
\contourmarkcode%
\def\contourmarkstart{\contourmarkprefix-\the\contourmarkcount.west}%
\def\contourmarkend{\contourmarkprefix-\the\contourmarkcount.east}%
\edef\contourpath{\contourpath \csname contourcontourpathcommand@\@contourstackitem @\endcsname}%
\fi%
\let\@next=\@@contourdolist%
\let\@contourstacklastitem=\@contourstackitem%
\fi
\@next%
}
% \contourcontourpathcommand{<symbol>}{<contour path command code>}
% \contourmarkstart and \contourmarkend are setup as the
% left and right points of the charactor at zero contour height.
\def\contourcontourpathcommand#1{\expandafter\def\csname contourcontourpathcommand@#1@\endcsname}
% \contourmark{<symbol>}{<mark start height>}{<mark end height>}
%
\def\contourmark#1#2#3{%
\contourcontourpathcommand{#1}{([shift={(0,#2)}]\contourmarkstart) -- ([shift={(0,#3)}]\contourmarkend)}
}
\makeatother
% Separator.
\contourcontourpathcommand{.}{}
\contourmark{0}{0}{0}
\contourmark{1}{1}{1}
\contourmark{2}{2}{2}
\contourmark{3}{3}{3}
\contourmark{4}{4}{4}
\contourmark{5}{5}{5}
\contourmark{+}{0}{1}
\contourcontourpathcommand{!}{
(\contourmarkstart) .. controls ++(0,2) and ++(0,2) .. (\contourmarkend)
}
\contourcontourpathcommand{?}{
(\contourmarkstart) .. controls ++(0,-1) and ++(0,-1) .. ([shift={(0,2)}]\contourmarkend)
}
\contourcontourpathcommand{|}{
% Continue previous path
-- ([shift={(0, 3)}]\contourmarkend)
}
\begin{document}
\begin{tabular}{c}
\begin{tikzpicture}
\contour[contour/.append style={rounded corners=0}, contour raise=-0.75cm,
contour marks={0.55.0..0.55.?..3.2..+..0..0..5|..!..3.2..3.33.+}]
{ibuuna basiidi kilumbu ki-bakweenda kuna-kiziitu};
\end{tikzpicture}
\\[0.5cm]
in line marking: ibuuna [\tikz[baseline={(0,0.25ex)}]%
\contour[contour only, contour scale=2ex/6,
contour marks={0.55.0}]
{ibuuna};]
\end{tabular}
\end{document}