使用 gb4e 对齐多种语言的注释

使用 gb4e 对齐多种语言的注释

我正在使用该包格布注释我的语言示例。它很好地将原始语言中的单词与其注释对齐。但这种对齐不会超出注释的第一行。如果我想用多种语言注释单词,则第一行注释之外不会有任何对齐。我该如何强制执行这种对齐?

\documentclass{article}
\usepackage{gb4e}
\begin{document}
\begin{exe}
    \ex
    \gll gef hundinum matinn\\
    gje hunden maten\\
    give {the dog} {the food}\\
    gib {dem Hunde} {das Essen}\\
\end{exe}
\end{document}

在此处输入图片描述

答案1

cgloss4e由 加载的包能够gb4e使用\glll(注意额外的l)宏自动解释具有两行注释的示例:

\documentclass{article}
\usepackage{gb4e}
\begin{document}
\begin{exe}
    \ex
    \glll gef hundinum matinn\\
    give {the dog} {the food}\\
    gib {dem Hunde} {das Essen}\\
\end{exe}
\end{document}

但是,对于您的示例,您还需要一行注释,而该包实际上并不是为此设计的。但添加相关代码并不难。在这里,我创建了一个\gliv命令来引入一个带有 3 行额外注释的示例。

\documentclass{article}
\usepackage{gb4e}
\makeatletter
\newbox\linefour
\newbox\wordfour
\def\gliv%                 % Introduces 4-line text-and-gloss.
   {\begin{flushleft}
     \ifx\@gsingle1% 
        \vskip\baselineskip\def\baselinestretch{1}%
        \@selfnt\vskip-\baselineskip\fi%
    \bgroup
    \foursent
   }
\@ifundefined{eachwordfour}{\let\eachwordfour=\rmfamily}{\relax}   
\gdef\foursent#1\\ #2\\ #3\\ #4\\{% #1 = first line, #2 = second line, #3 = third, #4 = fourth
    \getwords(\lineone,\eachwordone)#1 \\%
    \getwords(\linetwo,\eachwordtwo)#2 \\%
    \getwords(\linethree,\eachwordthree)#3 \\%
    \getwords(\linefour,\eachwordfour)#4 \\%
    \loop\lastword{\eachwordone}{\lineone}{\wordone}%
         \lastword{\eachwordtwo}{\linetwo}{\wordtwo}%
         \lastword{\eachwordthree}{\linethree}{\wordthree}%
         \lastword{\eachwordfour}{\linefour}{\wordfour}%
         \global\setbox\gline=\hbox{\unhbox\gline
                                    \hskip\glossglue
                                    \vtop{\box\wordone   % vtop was vbox
                                          \nointerlineskip
                                          \box\wordtwo
                                          \nointerlineskip
                                          \box\wordthree
                                          \nointerlineskip
                                          \box\wordfour
                                         }%
                                   }%
         \testdone
         \ifnotdone
    \repeat
    \egroup % matches \bgroup in \gloss
   \gl@stop}
\makeatother

\begin{document}
\begin{exe}
    \ex
    \gliv gef hundinum matinn\\
    gje hunden maten\\
    give {the dog} {the food}\\
    gib {dem Hunde} {das Essen}\\
\end{exe}
\end{document}

gb4e或者,你可以使用以下方式将 ExPex 注释句子嵌入到示例中:expex-glossonly软件包中加载了该[gb4e]选项。请参阅这个答案例如 ExPex 光泽。

代码输出

答案2

可以通过以下方式手动实现此目的tabbing

在此处输入图片描述

\documentclass{article}
\usepackage{gb4e}
\begin{document}
\begin{exe}
    \ex \begin{tabbing}
      give \= dem Hunde \= das Essen \kill
      gef \> hundinum \> matinn \\
      gje \> hunden \> maten\\
      give \> the dog \> the food \\
      gib \> dem Hunde \> das Essen
    \end{tabbing}
\end{exe}
\end{document}

\kill行包含每种语言翻译中最长的单词,用于标记制表点\=

答案3

在此处输入图片描述

为了完整性,也为了方便不受软件包约束的读者,此功能已内置于 中。它已经定义了 3 个级别的注释(a、b 和 c),您可以定义自己的注释。自定义它们的外观非常简单。在文档中expex详细了解 的注释机制的其他潜力。expex

\documentclass{article}
\usepackage{expex}
\begin{document}
\ex
 \begingl
 \gla gef hundinum matinn//
 \glb gje hunden maten//
 \glb give {the dog} {the food}//
 \glb gib {dem Hunde} {das Essen}//
 \endgl
\xe

\defineglwlevels{english,german}
\lingset{everygla=\bfseries,everyglenglish=\footnotesize,everyglgerman=\ttfamily} 

\ex
 \begingl
 \gla gef hundinum matinn//
 \glb gje hunden maten//
 \glenglish give {the dog} {the food}//
 \glgerman gib {dem Hunde} {das Essen}//
 \endgl
\xe
\end{document}

答案4

通用 expl3 宏的实验性精简版,\glinlines它将无限数量的行和单词解析为逐字堆叠的单元,再加上最后的无限数量的翻译/注释行。

它可以插入gb4e示例环境(*/标记新行):

\begin{exe}
    \ex
\glinlines{% 
       gef hundinum matinn
*/    gje hunden maten
*/    give {the dog} {the food}
*/    gib {dem Hunde} {das Essen}
}
\end{exe}

猎犬

对于以 为前缀的项目,可使用用户定义的格式(带开关).

平均能量损失

\documentclass{article}
\usepackage{xcolor}
\usepackage{fontspec}
\setmainfont{Noto Serif}
\setsansfont{Noto Sans}
\usepackage{xparse}
\usepackage{gb4e}


%-------------------------------------------------------------
\ExplSyntaxOn

%       \cs_generate_variant:Nn 
%           \seq_gset_split:Nnn 
%           { cno }

        \cs_generate_variant:Nn 
            \seq_gset_split:Nnn 
            { coo }

        \cs_generate_variant:Nn 
        \regex_match:nnT
        { nvT }
        
        
\tl_new:N \g_fc_namespace_tl 

%------------------
%****************************************************
%* procedures
%****************************************************
%------------------
\tl_new:N \g__gloss_intoseqname_tl
\tl_new:N \g__gloss_fromseqname_tl
\int_new:N \g__gloss_clausecount_int
\int_new:N \g__gloss_clauseloop_int
\tl_new:N \g__gloss_clauseloop_tl

\int_new:N \g__gloss_basenamecount_int
\int_new:N \g__gloss_basenameloop_int
\tl_new:N \g__gloss_basenameloop_tl

\int_new:N \g__gloss_wordloop_int
\tl_new:N \g__gloss_wordloop_tl

\int_new:N \g__gloss_maxlinecount_int
\int_new:N \g__gloss_maxwordcount_int

\bool_new:N \g__gloss_vpar_bool
\int_new:N \g__gloss_vpar_int




%------------------
    \cs_set:Npn \gl_functexttrans:n #1 { 
                                        \tex_space:D
                                        \\
                                                        \seq_item:cn
                                                                { g_gloss_glossglosses \int_use:N \g__gloss_maxlinecount_int _seq }
                                                                { #1 }
}

%------------------
    \cs_set:Npn \gl_funcboxall:nnnn #1#2#3#4 { 
    % 1=from seq base name
    % 2=base name loop start
    % 3=base name loop finish
    % 4=words seq 1 (words to box)
    
    
    
% outer loop
\int_set:Nn 
        \g__gloss_basenamecount_int
        { 
                #3      
        }   
    \int_set:Nn
            \g__gloss_basenameloop_int
            { #2 }
            
    \int_do_until:nNnn 
        { \g__gloss_basenameloop_int } > { \g__gloss_basenamecount_int } 
     {
    
    
\tl_set:Nx
     \g__gloss_fromseqname_tl 
     { 
            #1 
            \int_use:N \g__gloss_basenameloop_int
     }
     
\tl_set:Nx \g__gloss_intoseqname_tl 
        { 
            #1 
            \int_use:N \g__gloss_basenameloop_int
            #4
        }


\int_set:Nn 
        \g__gloss_clausecount_int
        { 
                \seq_count:c
                        { g_gloss_ \g_fc_namespace_tl \g__gloss_intoseqname_tl _seq }       
        }

% loop start

    \int_set:Nn
            \g__gloss_clauseloop_int
            { 1 }

    \int_set:Nn
            \g__gloss_wordloop_int
            { 1 }
    \int_do_until:nNnn 
        { \g__gloss_wordloop_int } > { \seq_count:c
                { g_gloss_ \g_fc_namespace_tl \g__gloss_intoseqname_tl _seq } } 
     {

%---
            \int_compare:nNnT
                            { \g__gloss_wordloop_int } > { \g__gloss_maxwordcount_int }
                            {
                                    \int_set:Nn
                                            \g__gloss_maxwordcount_int
                                            { \g__gloss_wordloop_int }
                    }
%---


\tl_set:Nx
        \g__gloss_wordloop_tl
        { \int_use:N \g__gloss_wordloop_int }

\cs_if_free:cT
        { g_gloss_ \g_fc_namespace_tl \g__gloss_intoseqname_tl \g__gloss_clauseloop_tl\g__gloss_wordloop_tl _box }
        { \box_new:c
                { g_gloss_ \g_fc_namespace_tl \g__gloss_intoseqname_tl \g__gloss_clauseloop_tl\g__gloss_wordloop_tl _box }
        }


    \tl_set:Nx
                \l_tmpc_tl
            {
                \seq_item:cn
                            { g_gloss_ \g_fc_namespace_tl \g__gloss_intoseqname_tl  _seq }
                            { \int_use:N \g__gloss_wordloop_int }
                }
                
                

%vvv
%    .text  >  .{\mfsposformat text}
        \regex_replace_all:nnN
                { (\.)(\w+) }
                { \1 \cB\{ \c{mfsposformat} \2 \cE\} }
                \l_tmpc_tl

%       :command;    > \command 
        \regex_replace_all:nnN
                { (\:)(\w+)(;) }
                { \c{\2}  }
                \l_tmpc_tl
                
%       :command    >   \command
        \regex_replace_all:nnN
                { (\:)(\w+) }
                { \c{\2}  }
                \l_tmpc_tl
                

        \regex_match:nvT
                { \+ }
                { l_tmpc_tl } 
                { \int_set_eq:NN 
                            \g__gloss_vpar_int 
                            \g__gloss_wordloop_int }
                
        \regex_replace_all:nnN
                { \+ }
                {  }
                \l_tmpc_tl


                
    \hbox_gset:cn 
            { g_gloss_ \g_fc_namespace_tl \g__gloss_intoseqname_tl \g__gloss_clauseloop_tl\g__gloss_wordloop_tl _box }
            {
                    \tl_use:N
                            \l_tmpc_tl
            }


        
        %============================
        
        \int_incr:N
                    \g__gloss_wordloop_int
                    
        } % loop finish


        \int_incr:N
                    \g__gloss_basenameloop_int
                    
        } % outer loop finish


%+++++++++++++++++++++++++
% stack the boxes

\tex_space:D %=


%\int_set:Nn \g__gloss_vpar_int { 0 }

% outer loop
    \int_set:Nn
            \g__gloss_clauseloop_int
            { 1 }

    \int_set:Nn
            \g__gloss_wordloop_int
            { 1 }

    \int_do_until:nNnn 
        { \g__gloss_wordloop_int } > { \seq_count:c
                { g_gloss_ \g_fc_namespace_tl \g__gloss_intoseqname_tl _seq } } 
     {
    
    

% loop start

\int_set:Nn 
        \g__gloss_basenamecount_int
        { 
                #3      
        }   
    \int_set:Nn
            \g__gloss_basenameloop_int
            { #2 }

\vbox_set_top:Nn
        \l__vpair_box
        { %^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            
    \int_do_until:nNnn 
        { \g__gloss_basenameloop_int } > { \g__gloss_basenamecount_int } 

     {

\tl_set:Nx
     \g__gloss_fromseqname_tl 
     { 
            #1 
            \int_use:N \g__gloss_basenameloop_int
     }
     
\tl_set:Nx \g__gloss_intoseqname_tl 
        { 
            #1 
            \int_use:N \g__gloss_basenameloop_int
            #4
        }

\int_set:Nn 
        \g__gloss_clausecount_int
        { 
                \seq_count:c
                        { g_gloss_ \g_fc_namespace_tl \g__gloss_intoseqname_tl _seq }       
        }


\tl_set:Nx
        \g__gloss_wordloop_tl
        { \int_use:N \g__gloss_wordloop_int }

    \box_use:c
{ g_gloss_ \g_fc_namespace_tl \g__gloss_intoseqname_tl \g__gloss_clauseloop_tl\g__gloss_wordloop_tl _box }


        %============================
        \int_incr:N
                    \g__gloss_basenameloop_int
        } % loop finish
        
        } %^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        
\hbox_set:Nn
        \l__hunit_box
        {
                    \box_use:N %=
                                \l__vpair_box
                    }   

        \box_use:N %=
                \l__hunit_box 
                
                        \int_compare:nNnTF
                            { \g__gloss_vpar_int  } = { \g__gloss_wordloop_int }
                            {
                                    \\
                                    \int_set:Nn \g__gloss_vpar_int { 0 }
                            }
                {
                            \tex_space:D %=
                            \tex_space:D %=     
                }

                            
                             


                
        \int_incr:N
                    \g__gloss_wordloop_int
        } % outer loop finish


            \int_compare:nNnT
                            { \seq_count:c
                                    { g_gloss_glossglosses \int_use:N \g__gloss_maxlinecount_int _seq }
                             } > { 1 }
                            {
                                \smallskip
                                \int_step_function:nnnN
                                        { 2 } 
                                        { 1 } 
                                        { \seq_count:c
                                    { g_gloss_glossglosses \int_use:N \g__gloss_maxlinecount_int _seq } } 
                                          \gl_functexttrans:n
                                            }
                            
}




%------------------
    \cs_set:Npn \gl_funcsplitloopseq:nnnnn #1#2#3#4#5 { 
    % 1=from seq base name
    % 2=base name loop start
    % 3=base name loop finish
    % 4=by what
    % 5=into seq
    
% outer loop
\int_set:Nn 
        \g__gloss_basenamecount_int
        { 
                #3      
        }   
    \int_set:Nn
            \g__gloss_basenameloop_int
            { #2 }
            
    \int_do_until:nNnn 
        { \g__gloss_basenameloop_int } > { \g__gloss_basenamecount_int } 
     {
    
    
\tl_set:Nx
     \g__gloss_fromseqname_tl 
     { 
            #1 
            \int_use:N \g__gloss_basenameloop_int
     }
     
\tl_set:Nx \g__gloss_intoseqname_tl 
        { 
            #1 
            \int_use:N \g__gloss_basenameloop_int
            #5 
        }

\int_set:Nn 
        \g__gloss_clausecount_int
        { 
                \seq_count:c
                        { g_gloss_ \g_fc_namespace_tl \g__gloss_fromseqname_tl _seq }       
        }

% loop start

    \int_set:Nn
            \g__gloss_clauseloop_int
            { 1 }
    \int_do_until:nNnn 
        { \g__gloss_clauseloop_int } > { \g__gloss_clausecount_int } 
     {

\tl_set:Nx
        \g__gloss_clauseloop_tl
        { \int_use:N \g__gloss_clauseloop_int }

\cs_if_free:cT
        { g_gloss_ \g_fc_namespace_tl \g__gloss_intoseqname_tl \g__gloss_clauseloop_tl _seq }
        { \seq_new:c
                { g_gloss_ \g_fc_namespace_tl \g__gloss_intoseqname_tl \g__gloss_clauseloop_tl _seq }
        }

    \seq_gclear:c 
        { g_gloss_ \g_fc_namespace_tl \g__gloss_intoseqname_tl \g__gloss_clauseloop_tl _seq }

            \exp_args:Nnnx
    \seq_gset_split:coo 
        { g_gloss_ \g_fc_namespace_tl \g__gloss_intoseqname_tl \g__gloss_clauseloop_tl _seq }
            { #4 } % separator
            { 
                \seq_item:cn
                            { g_gloss_ \g_fc_namespace_tl \g__gloss_fromseqname_tl  _seq }
                            { \int_use:N \g__gloss_clauseloop_int }
             }

        %--------------------------------
        
        
        %============================
        
        \int_incr:N
                    \g__gloss_clauseloop_int
                    
        } % loop finish


        \int_incr:N
                    \g__gloss_basenameloop_int
                    
        } % outer loop finish

}





%------------------
    \cs_set:Npn \gl_funcsplitseq:nnn #1#2#3 { 
    % 1=from seq
    % 2=by what
    % 3=into seq
    
\tl_set:Nx \g__gloss_fromseqname_tl { #1 }
\tl_set:Nx \g__gloss_intoseqname_tl { #3 }

%\tl_show:N \g__gloss_fromseqname_tl 
%\tl_show:N \g__gloss_intoseqname_tl 

\int_set:Nn 
        \g__gloss_clausecount_int
        { 
                \seq_count:c
                        { g_gloss_ \g_fc_namespace_tl \g__gloss_fromseqname_tl _seq }       
        }

% loop start

    \int_set:Nn
            \g__gloss_clauseloop_int
            { 1 }
    \int_do_until:nNnn 
        { \g__gloss_clauseloop_int } > { \g__gloss_clausecount_int } 
     {

\tl_set:Nx
        \g__gloss_clauseloop_tl
        { \int_use:N \g__gloss_clauseloop_int }

\cs_if_free:cT
        { g_gloss_ \g_fc_namespace_tl \g__gloss_intoseqname_tl \g__gloss_clauseloop_tl _seq }
        { \seq_new:c
                { g_gloss_ \g_fc_namespace_tl \g__gloss_intoseqname_tl \g__gloss_clauseloop_tl _seq }
        }

    \seq_gclear:c 
        { g_gloss_ \g_fc_namespace_tl \g__gloss_intoseqname_tl \g__gloss_clauseloop_tl _seq }

            \exp_args:Nnnx
    \seq_gset_split:coo 
        { g_gloss_ \g_fc_namespace_tl \g__gloss_intoseqname_tl \g__gloss_clauseloop_tl _seq }
            { #2 } 
            { 
                \seq_item:cn
                            { g_gloss_ \g_fc_namespace_tl \g__gloss_fromseqname_tl  _seq }
                            { \int_use:N \g__gloss_clauseloop_int }
             }

        
        \int_incr:N
                    \g__gloss_clauseloop_int
                    
        } % loop finish

}







%------------------
    \cs_set:Npn \gl_funcsplit:nnn #1#2#3 { 
    % 1=into seq
    % 2=what
    % 3=by what

\tl_set:Nx \g__gloss_intoseqname_tl { #1 }
\tl_set:Nx \g__gloss_intoseqwhat_tl { #2 }
\tl_set:Nx \g__gloss_intoseqbywhat_tl { #3 }




\cs_if_free:cT
        { g_gloss_ \g_fc_namespace_tl \g__gloss_intoseqname_tl _seq }
        { \seq_new:c
                { g_gloss_ \g_fc_namespace_tl \g__gloss_intoseqname_tl _seq }
        }

    \seq_gclear:c 
        { g_gloss_ \g_fc_namespace_tl \g__gloss_intoseqname_tl _seq }

%           \exp_args:Nnnx
    \seq_gset_split:coo 
        { g_gloss_ \g_fc_namespace_tl \g__gloss_intoseqname_tl _seq }
            { #3 } 
            { #2 }


\int_set:Nn 
        \g__gloss_maxlinecount_int
        {
            \seq_count:c
                { g_gloss_ \g_fc_namespace_tl \g__gloss_intoseqname_tl _seq }   
        }

}



%****************************************************
%* main commands
%****************************************************
%--------------------
\NewDocumentCommand { \glinlinesbase } { o m m +m } { 
    % 1=namespace
    % 2=seq
    % 3=sep
    % 4=data

                \IfNoValueTF { #1 } 
                        { \tl_clear:N \g_fc_namespace_tl } 
                        { \tl_gset:Nn \g_fc_namespace_tl { #1 } }

\int_set:Nn \g__gloss_maxlinecount_int { 0 }
    % split into input lines
    \gl_funcsplit:nnn {#2inlines}{#4}{#3}
    % 1=into seq
    % 2=what
    % 3=by what
    \gl_funcsplitseq:nnn 
            {#2inlines}
            {glt}
            {glosses}

    \gl_funcsplitloopseq:nnnnn 
                {glosses}
                {1}
                {
                        \int_use:N
                            \g__gloss_maxlinecount_int
                    }
                {~}
                {words}

\int_set:Nn \g__gloss_maxwordcount_int { 0 }

    \gl_funcboxall:nnnn 
                {glosses}
                {1}
                {
                        \int_use:N
                            \g__gloss_maxlinecount_int
                        }
                {words1}

}





%--------------------
\NewDocumentCommand { \glinlines } { +m } { 
    % 1==data
        \glinlinesbase[gloss]{ex2a}{*/}{#1}
}

\box_new:N \l__vpair_box
\box_new:N \l__hunit_box

%--------------------
\NewDocumentCommand { \mfsposformat } { } { 
            \scshape\color{blue}
}
%--------------------
\NewDocumentCommand { \mfssetposformat } { m } { 
            \renewcommand{\mfsposformat}{#1}
}

\ExplSyntaxOff

\begin{document}


\begin{exe}
    \ex
\glinlines{% end-of-line counts as an extra space
       gef hundinum matinn
*/    gje hunden maten
*/    give {the dog} {the food}
*/    gib {dem Hunde} {das Essen}
}
\end{exe}


\begin{exe}
    \ex
\glinlines{% end-of-line counts as an extra space
       gef hundinum matinn
*/    give.tense hound.case meat.case
*/    gje hunden maten
*/    give {the dog} {the food}
*/    .vrb {.art .noun} {.art .noun}
*/    .cmd .subj .obj
*/    gib {dem Hunde} {das Essen}
glt    One of the daily chores.
glt    Multiple translation/note lines.
glt    Formal literal colloquial idiom
glt    A note
}
\end{exe}


\mfssetposformat{\scshape\bfseries\sffamily}
\begin{exe}
    \ex 
    \glinlines{%
    kma t'-əlčqu-(ɣ)in 
*/ .1sg  .1sg.sub-see-.2sg.obj
glt `I saw you.' (S1:71)
        }
\end{exe}


\end{document}

它使用 expl3 序列来存储和分割文本。

相关内容