Skip to content

Utilisation de TikZ pour représenter l'intonation

[*]Il est essentiel d'interpréter correctement le code avant de l'adapter à votre travail, si vous voulez apporter quelque chose, vous pouvez le dire dans les commentaires.

Solution :

[*]Suite à la réponse de Matthew Leingang, voici la même approche liée à un peu de sucre syntaxique. Il s'amuse avec catcode stuff, donc il faut faire attention.

documentclass{standalone}
usepackage{tikz}

newcountcontourmarkcount
newdimencontourraise

{catcode`|=13
gdefinstallbarmark#1ignorespaces{%
    #1ignorespaces%
    catcode`|=13%
    globalcontourmarkcount=0relax%
    globaldeflastmarkshift{0}%
    let|=marktext}%
}

defstar{*}
newcommandmarktext[1][*]{%
    defmarkshift{#1}%
    % When not followed by the optional argument
    % the contour mark is set at the previous height.
    ifxmarkshiftstar
        letmarkshift=lastmarkshift%
    fi
    globaladvancecontourmarkcount by1relax%
    xdeftmpmark{thecontourmarkcount}%
    tikz[remember picture, overlay, y=pgfkeysvalueof{/tikz/contour scale}]
        path [yshift=contourraise, shift={(0,markshift)}]
                coordinate (contourmarkprefix-tmpmark);%
    globalcontourmarkcount=tmpmarkrelax% 
    globalletlastmarkshift=markshift%
}

tikzset{
    intonation contour/.style={%
        execute at begin node={%
            installbarmark%
        },
        append after command={%
            pgfextra{%
                ifnumcontourmarkcount>1
                    draw [contour] (contourmarkprefix-1)
                        foreach y in {2,...,thecontourmarkcount}{ -- (contourmarkprefix-y) };
                fi
            }
        }
    },
    % How far above the base line of the text,
    raise contour/.code=pgfmathsetlengthcontourraise{#1},
    % The `scale' for the values in the contour height specification
    contour scale/.initial=3pt,
    % The prefix for the contour marks.
    contour mark prefix/.code=xdefcontourmarkprefix{#1},
    contour mark prefix=intonation contour,
    contour/.style={
        draw, 
        rounded corners=1ex,
    }           
}

begin{document}

begin{tikzpicture}[remember picture]

node [intonation contour, raise contour=0.5cm] 
    {|[10]Where |[3]are |[3]you |[5]go|[2]ing|[0]?};

end{tikzpicture}

begin{tikzpicture}[remember picture]

node [intonation contour, raise contour=0.5cm, contour mark prefix=my contour] 
    {|[2]I  |am  |[7]fina|lly |[4]go|ing |[2]home|[0].};

path [draw=red, ->] ([yshift=0.25cm]my contour-2) -- ([yshift=0.25cm]my contour-3)
        node [midway, left] {tiny rising};

path [draw=red, ->] ([yshift=0.25cm]my contour-4) -- ([yshift=0.25cm]my contour-5)
    node [midway, right] {tiny falling};
end{tikzpicture}

end{document}

[*]Entrez la description de l'image ici

[*]Et juste pour le fun, voici une version qui n'utilise pas remember picture donc pas besoin de deux compilations. De plus, il n'y a pas de bêtises à faire avec les codes de catégories. C'est, malheureusement, un peu plus impliqué, et les lettres ne sont pas tapées idéalement car elles sont toutes dans des boîtes séparées.

[*]EDIT Un peu plus de polyvalence a été implémentée, mais en conséquence, c'est un peu plus complexe.

documentclass{standalone}
usepackage{tikz}

newdimencontourraise

tikzset{
    % How far above the base line of the text,
    raise contour/.code=pgfmathsetlengthcontourraise{#1},
    % The `scale' for the values in the contour height specification
    contour scale/.initial=3pt,
    % The prefix for the contour marks.
    contour mark prefix/.code=xdefcontourmarkprefix{#1},
    contour mark prefix=contour,
    % The style for the contour path
    contour/.style={
        draw, 
        rounded corners=1ex,
    },
    % The style for the token nodes
    contour token/.style={
        anchor=base west, 
        inner sep=0pt,
        text depth=0.6ex, % controls underline depth
    },
    contour underline/.style={
        draw
    },
    % The character to insert a mark (use with care)
    contour mark character/.store in=contourmarkchar,
    contour mark character=|
}

makeatletter

def[email protected]{@}

newcountlasttokennumber
newcountcurrenttokennumber
newcountcontourmarkcount
newcountcontourtokenunderlinestate
newcommandcontour[2][]{%
    begin{scope}[#1]
        coordinate (token-0);
        currenttokennumber=0relax%
        lasttokennumber=0relax%
        contourmarkcount=0relax%
        deflastcontourheight{0}%
        contourtokenunderlinestate=0relax%
        @contour#[email protected]%
}

% Must check for a spaces
def@contour{futurelet@token@checkforspace}

def@uscore{_}
def@checkforspace{%
    ifx@token@sptoken%
        let@next=@replacespace%
    else%
        if@tokencontourmarkchar%
            let@next=@[email protected]
        else%
            if@token@uscore
                let@next=@contourtoggleunderline%
            else%
                let@next=@@contour%
            fi%
        fi%
    fi%
    @next%
}

def@contourtoggleunderline#1{%
    advancecontourtokenunderlinestate by1relax
    ifnumcontourtokenunderlinestate>3relax%
        contourtokenunderlinestate=0relax%
    fi%
    @contour%
}

def@[email protected]{%
    afterassignment@@[email protected]let@token=%
}

def@@[email protected]{%
    futurelet@token@@@[email protected]}%

def@@@[email protected]{%
    if@token[%
        let@next=@@@@[email protected]%
    else%
        letcurrentcontourheight=lastcontourheight%
        let@next=@@@@@[email protected]%
    fi%
    @next%
}

def@@@@[email protected][#1]{%
    def@tmp{#1}%
    ifx@tmp@empty%
        letcurrentcontourheight=lastcontourheight%
    else%
        defcurrentcontourheight{#1}%
    fi%
    @@@@@[email protected]}

def@@@@@[email protected]{%
    advancecontourmarkcount by1relax%
    % Code for inserting mark
    coordinate (contourmarkprefix-thecontourmarkcount)
        at ([yshift=contourraise, y=pgfkeysvalueof{/tikz/contour scale}, 
        shift={(0,currentcontourheight)}]token-thecurrenttokennumber.base east);
    %
    letlastcontourheight=currentcontourheight
@contour}

defcustomspace{{hbox to 1ex{hfill}}}

def@replacespace#1{%
    @contourcustomspace#1%
}

def@@contour#1{%
    def@token{#1}%
    if@token[email protected]
        let@next=@@@contour%
    else%
        lasttokennumber=currenttokennumber%
        advancecurrenttokennumber by1%
        % Code for typesetting token
        node [contour token/.try] at (token-thelasttokennumber.base east) (token-thecurrenttokennumber) {@token};
        % Manage underline state
        ifnumcontourtokenunderlinestate=1relax%
            coordinate (underline start) at (token-thecurrenttokennumber.south west);
            contourtokenunderlinestate=2relax%
        else
            ifnumcontourtokenunderlinestate=3relax%
                coordinate (underline end) at (token-thecurrenttokennumber.south west);
                draw (underline start) -- (underline end);
                contourtokenunderlinestate=0relax
            fi%
        fi%
        let@next=@contour
        %
    fi%
    @next%
}
def@@@contour{%
    ifnumcontourmarkcount>1
        % Code for drawing contour
        draw [contour] (contourmarkprefix-1)
            foreach y in {2,...,thecontourmarkcount}{ -- (contourmarkprefix-y) };
        %
    fi%
    end{scope}%
}

makeatother

begin{document}

begin{tikzpicture}[baseline={(0,-0.25)}]

    contour[raise contour=0.5cm]
        {|[10]Where |[3]are |[3]_you_ |[5]go|[2]ing|[0]?}

end{tikzpicture} 

begin{tikzpicture}[baseline={(0,-0.25)}]

contour[
    raise contour=0.5cm, 
    contour mark prefix=my contour, 
    contour/.style={
        thick, 
        rounded corners=1mm,
        line cap=round,
        dotted},
    contour mark character=*] 
    {*[2]I *am  *[7]_{fi}na*lly_ *[4]go*ing *[2]home*[0].};

path [draw=red, ->] ([yshift=0.25cm]my contour-2) -- ([yshift=0.25cm]my contour-3)
        node [midway, left] {tiny rising};

path [draw=red, ->] ([yshift=0.25cm]my contour-4) -- ([yshift=0.25cm]my contour-5)
    node [midway, right] {tiny falling};

path (0,-0.25);
end{tikzpicture}

end{document}

[*]Entrez la description de l'image ici

[*]EDIT : version améliorée qui, espérons-le, couvre tous les cas d'utilisation donnés ci-dessus.

documentclass{standalone}
usepackage{tikz}
usetikzlibrary{fit}

newdimencontourraise
newdimencontourspacetokenwidth
newcountlasttokennumber
newcountcurrenttokennumber
newcountcontourmarkcount
newcountcontourtokenunderlinestate
newboxcontourbox

tikzset{
    tight fit/.style={
        inner sep=0pt,
        outer sep=0pt,
    },
    %
    %
    % How far above the reference anchor of the text,
    contour raise/.code=pgfmathsetlengthcontourraise{#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, 
        inner sep=0pt,
    },
    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-thecontourmarkcount)
          at ([yshift=contourraise, y=contourscale,               
          shift={(0,currentcontourheight)}]token-thecurrenttokennumber.contourreferenceanchor);
    },
    contour token code={%
        node [every contour token/.try] at 
        (token-thelasttokennumber.base east) 
            (token-thecurrenttokennumber) {token};
    },
    contour code={
        draw [contour] (contourmarkprefix-1)
            foreach y in {2,...,thecontourmarkcount}{ -- 
                    (contourmarkprefix-y) };                  
    },
    %
    % 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={setboxcontourbox=hboxbgroup},
            execute at end node=egroupphantom{boxcontourbox}%
        },
        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 
                (token-thelasttokennumber.base east |- 
                0,currentcontourheight) 
                (token-thecurrenttokennumber) {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=pgfmathsetlengthcontourspacetokenwidth{#1},
    space token width=0.125cm
}

makeatletter

def[email protected]{@}

newcommandcontour[2][]{%
    begin{scope}[#1]
        coordinate (token-0);
        currenttokennumber=0relax%
        lasttokennumber=0relax%
        contourmarkcount=0relax%
        deflastcontourheight{0}%
        contourtokenunderlinestate=0relax%
        @contour#[email protected]%
}

% Must check for a spaces
def@contour{futurelet@token@checkforspace}

def@uscore{_}
def@checkforspace{%
    ifx@token@sptoken%
        let@next=@replacespace%
    else%
        if@tokencontourmarkchar%
            let@next=@[email protected]
        else%
            if@token@uscore
                let@next=@contourtoggleunderline%
            else%
                let@next=@@contour%
            fi%
        fi%
    fi%
    @next%
}

def@contourtoggleunderline#1{%
    advancecontourtokenunderlinestate by1relax
    ifnumcontourtokenunderlinestate>3relax%
        contourtokenunderlinestate=0relax%
    fi%
    @contour%
}

def@[email protected]{%
    afterassignment@@[email protected]let@token=%
}

def@@[email protected]{%
    futurelet@token@@@[email protected]}%

def@@@[email protected]{%
    if@token[%
        let@next=@@@@[email protected]%
    else%
        letcurrentcontourheight=lastcontourheight%
        let@next=@@@@@[email protected]%
    fi%
    @next%
}

def@@@@[email protected][#1]{%
    def@tmp{#1}%
    ifx@tmp@empty%
        letcurrentcontourheight=lastcontourheight%
    else%
        defcurrentcontourheight{#1}%
    fi%
    @@@@@[email protected]}

def@@@@@[email protected]{%
    advancecontourmarkcount by1relax%
     % Code for inserting mark
    contourmarkcode%
    letlastcontourheight=currentcontourheight%
    @contour}

defcontourspacetoken{{hbox to contourspacetokenwidth{hfill}}}

def@replacespace#1{%
    @contourcontourspacetoken#1%
}

def@@contour#1{%
    def@token{#1}%
    if@token[email protected]%
        @contourdounderline%
        [email protected]{[email protected]@[email protected]}{}{%
            node [tight fit, fit={(tokengroup)}, token group/.try] {};
            globallet[email protected]@[email protected]=relax%
        }%
        let@next=@@@contour%
    else%
        lasttokennumber=currenttokennumber%
        advancecurrenttokennumber by1%
        lettoken=@token%
        % Code for typesetting token
        contourtokencode%
        % Manage underline state
        @contourdounderline%
        def@@token{contourspacetoken}%
        ifx@token@@token%
            [email protected]{[email protected]@[email protected]}{}{%
                [email protected]{[email protected]@[email protected]}{}{%
                    node [tight fit, fit={(tokengroup) (underline)}] 
                    (tokengroup) 
                {};}%
                node [tight fit, fit={(tokengroup)}, token group/.try] {};
                globallet[email protected]@[email protected]=relax%
            }%
        else
            [email protected]{[email protected]@[email protected]}{%
                node [tight fit, 
                fit={(token-thecurrenttokennumber)}] 
                (tokengroup) {};
            }{%
                node [tight fit, 
                fit={(token-thecurrenttokennumber) 
                (tokengroup)}] 
                (tokengroup){};
            }%
        fi%
        let@next=@contour
        %
    fi%
    @next%
}

def@contourdounderline{%
    ifcasecontourtokenunderlinestate%
     or
         node [tight fit, fit={(token-thecurrenttokennumber)}] 
         (underline) {};
         contourtokenunderlinestate=2relax%
     or%
            node [tight fit,fit={(token-thecurrenttokennumber) (underline)}]
            (underline) {};
     or%
            node [tight fit, fit={(underline)}, underline token/.try] 
            (underline) {};
         draw [underline/.try]
                    (underline.south west) -- (underline.south east);
            [email protected]{[email protected]@[email protected]}{}{%
                 node [tight fit, fit={(tokengroup) (underline)}] 
                 (tokengroup) {};%
                 node [tight fit, fit={(tokengroup)}, token group/.try] {};
                 globallet[email protected]@[email protected]=relax%
                 globallet[email protected]@[email protected]=relax%
             }
         contourtokenunderlinestate=0relax
     fi%
}
def@@@contour{%
    ifnumcontourmarkcount>1
        % Code for drawing contour
        contourcode%
    fi%
    end{scope}%
}

makeatother

begin{document}

begin{tabular}{c}
\
begin{tikzpicture}
    contour[tokens follow contour]
        {|[10]_Where_ |[3]are you |[6]_go_|[1]ing?|[0]}
end{tikzpicture} 

\[0.5cm]

begin{tikzpicture}
    contour[tokens follow contour, box tokens, space token width=0.2cm]
       {|[10]_Where_ |[3]are you |[6]_go_ |[1]ing?|[0]}
end{tikzpicture} 

\[0.5cm]

begin{tikzpicture}
    contour[contour raise=0.5cm]
        {|[10]_Where_ |[3]are you |[6]_go_|[1]ing?|[0]}
end{tikzpicture} 

\[0.5cm]

begin{tikzpicture}
    contour[contour raise=0.5cm]
        {|[10]Where |[3]are |[3]_you_ |[5]go|[2]ing?|[0]}

    contour[contour raise=0.5cm, contour only, contour/.append style={dashed}]
            {|[0]Where |[2]are |[8]you |[2]go|[2]ing?|[1]}

end{tikzpicture} 

\[1cm]

begin{tikzpicture}
contour[tokens follow contour,
    contour mark character=*] 
    {*[2]I *am  *[7]_{fi}na*lly_ *[4]go*ing *[2]_home_*[0]};
end{tikzpicture} 
\[0.5cm]
begin{tikzpicture}
contour[
    contour raise=0.5cm, 
    contour mark prefix=my contour,
    contour/.style={
        thick, 
        rounded corners=1mm,
        line cap=round,
        dotted},
    contour mark character=*] 
    {*[2]I *am  *[7]_{fi}na*lly_ *[4]go*ing *[2]home*[0].};

path [draw=red, ->] ([yshift=0.25cm]my contour-2) -- ([yshift=0.25cm]my 
contour-3)
        node [midway, left] {tiny rising};

path [draw=red, ->] ([yshift=0.25cm]my contour-4) -- ([yshift=0.25cm]my 
contour-5)
    node [midway, right] {tiny falling};

end{tikzpicture}

end{tabular}
end{document}

[*]Entrez la description de l'image ici

[*]J'utiliserais le fameux tikzmark et la combiner avec les coordonnées d'intersection. Voici le code :

documentclass{standalone}
usepackage{tikz}
newcommand{tikzmark}[1]{tikz[overlay,remember picture,baseline] node [anchor=base] (#1) {};}%
tikzstyle{intonation}=[rounded corners=2mm,yshift=1.5ex]
begin{document}

begin{tikzpicture}[remember picture]
node{tikzmark{w}Where tikzmark{a}are tikzmark{y}you tikzmark{g}gotikzmark{i}ingtikzmark{q}?};
draw[intonation] (w |- 0,1) -- (a |- 0,0.2) -- (y |- 0,0.2) -- (g |- 0,0.6) -- (q |- 0,0);
end{tikzpicture}

end{document}

[*]Le site tikzmark enregistre les coordonnées du point du document où elle est appelée. Ainsi, le texte du nœud tikzmark{w}Where tikzmark{a}are... enregistre les coordonnées appelées w, aetc., à divers endroits de la phrase.

[*]Si A et B sont des nœuds ou des coordonnées TikZ, alors (A |- B) est l'intersection d'une ligne verticale passant par A et d'une ligne horizontale passant par B. Donc (w |- 0,1) a pour objet x le point de la ligne de base gauche du w sur et y coordonnée 1. Vous pouvez modifier cette y coordonnée comme vous le souhaitez pour les autres noms de coordonnées.

[*]Voici le résultat :

[*]Exemple de sortie de code

[*]Vous pourriez concevoir une macro qui spécifie/marque le texte et définit la coordonnée y-valeurs dans le même argument. Mais ceci est une implémentation possible.

[*]Je ne suis pas sûr d'avoir mis les coordonnées au bon endroit (et réutilisé zzb en deux points) mais quelque chose comme

[*]Entrez la description de l'image ici

%!TEX TS-program = xelatex
%!TEX encoding = UTF-8 Unicode

documentclass[a4paper,12pt, oneside]{article}

usepackage{fontspec}
defaultfontfeatures{Mapping=tex-text, Scale=MatchLowercase}
setmainfont{Charis SIL}

makeatletter
defsavecoordinate#1#2{sbox0{#2}edef#1{[email protected]wd0}}
makeatother

usepackage{tikz}

begin{document}

savecoordinatezza{Where }
savecoordinatezzb{Where are you}
savecoordinatezzc{Where are you going?}

begin{table}[hbtp]
begin{tabular}{l}
tikz[x=1pt,y=1mm,rounded corners=2mm] draw[very thick, gray](0,10)--(zza,2)--(zzb,2)--(zzb,6)--(zzc,0); \
mbox{Where are you going?}
end{tabular}
end{table}

end{document}

Ici vous pouvez voir les commentaires et les évaluations des utilisateurs

[*]Si vous avez trouvé cet article utile, il serait très utile que vous le partagiez avec plus de programmeurs afin de nous aider à diffuser nos informations.



Utilisez notre moteur de recherche

Ricerca
Generic filters

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.