Wie findet man die Position eines Wortes in einem wirren Satz?

Wie findet man die Position eines Wortes in einem wirren Satz?

Ich habe einen ersten Satz:

Der schnelle braune Fuchs springt über den faulen Hund.

Ich habe einen neuen Satz (der immer eine Aneinanderreihung des Originalsatzes ist):

Der faule Hund springt über den schnellen braunen Fuchs.

Im Originalsatz möchte ich für jedes Wort die Wortposition entsprechend dem durcheinandergewürfelten Satz hochstellen. Kann mir jemand erklären, wie ich das erreichen kann?

Jeder neuartige Ansatz (mit neuen Paketen) ist willkommen. Vielen Dank im Voraus. Im folgenden MWE erreiche ich offensichtlich nicht das, was ich eigentlich will.

\documentclass[12pt]{memoir}
\usepackage{listofitems}
\usepackage{amsmath}

\newcommand{\wordsI}
{   1. The,
    2. quick,
    3. brown,       
    4. fox      
    +
    5. jumps,
    6. over,
    7. the,
    8. lazy,
    9. dog
}

\newcommand{\wordsII}
{   The
    lazy
    dog         
    jumps
    over
    the
    quick
    brown
    fox
}

% Tokenize the words in order to display them
\newcommand{\tokenize}[1]
{%
    \setsepchar{+/,/./}
    \readlist*\textarray{#1}
    \foreachitem\groupoflines\in\textarray
    {
        \setsepchar{,}
        \readlist*\linearray{\groupoflines} 
        \foreachitem\line\in\linearray
        {  
            \setsepchar{.}
            \readlist*\wordarray{\line}
            $ \text{\wordarray[2]} ^ {\wordarray[1]} $
        }%
        \newline
    }
}

\begin{document}
\noindent
Actual sentence:
\newline
% The splitting of the sentence in 2 lines is intentional
\tokenize{\wordsI}

\noindent
Jumbled sentence:
\textbf{\wordsII}   
\end{document}

In diesem Beispiel erhalte ich das gewünschte Ergebnis, wenn ich stattdessen die folgende Definition habe:

\newcommand{\wordsI}
{   1. The,
    7. quick,
    8. brown,       
    9. fox      
    +
    4. jumps,
    5. over,
    6. the,
    2. lazy,
    3. dog
}

Die gewünschte Ausgabe

Ich möchte die Änderung aber nicht manuell vornehmen. Ich suche nach einer Möglichkeit, sie auf der Grundlage des durcheinandergewürfelten Satzes „dynamisch“ zu gestalten.

BEARBEITEN: Dies möchte ich auch in Szenarien wie diesem erreichen:

Anfangssatz:

der schnelle braune Fuchs springt über den faulen Hund.

Durcheinandergewürfelter Satz:

der faule Hund springt über den schnellen braunen Fuchs.

In diesem Fall brauche ich eine Art „Tags“ für die Wörter im Anfangssatz, damit der durcheinandergewürfelte Satz eindeutig ist.

\newcommand{\wordsI}
{   1. the,
    2. quick,
    3. brown,       
    4. fox      
    +
    5. jumps,
    6. over,
    7. the,
    8. lazy,
    9. dog
}

\newcommand{\wordsII}
{   7. the
    8. lazy
    9. dog         
    5. jumps
    6. over
    1. the
    2. quick
    3. brown
    4. fox
}

Gewünschte Ausgabe: Gewünschte Ausgabe

Antwort1

Meiner Meinung nach ist das Interessanteste an TeX der Schriftsatz und das Schlimmste die Programmiermöglichkeit. Daher ist es am besten, solche Programmierungen außerhalb von TeX durchzuführen (so weit weg wie möglich!) und TeX ausschließlich für den Schriftsatz zu verwenden. Alles kannmöglichmit TeX, aber es ist nicht unbedingt die einfachste/wartungsfreundlichste Lösung.

Wenn Sie TeX verwenden, ist diese Art der Programmierung mit LuaTeX jedoch einfacher (zumindest für mich und ich denke, für die meisten Leute). Kompilieren Sie die folgende Datei mit lualatex(Ihre „Tags“ sind optional: Sie können jedes Wort wie markieren the(1) quick(2) ...oder nur die doppelten Wörter markieren):

\documentclass[12pt]{memoir}
\usepackage{amsmath} % For \text

\newcommand{\printword}[2]{$\text{#1} ^ {#2}$\quad} % Or whatever formatting you like.
\newcommand{\linesep}{\newline}

\directlua{dofile('jumble.lua')}
\newcommand{\printjumble}[2]{
  \directlua{get_sentence1_lines()}{#1}
  \directlua{get_sentence2_words()}{#2}
  %
  \noindent
  Actual sentence:
  \newline
  \directlua{print_sentence1_lines()}

  \noindent
  Jumbled sentence:
  \textbf{\directlua{print_sentence2()}}
}

\begin{document}
\printjumble{
  the(1) quick brown fox
  +
  jumps over the(7) lazy dog
}{
  the(7) lazy dog jumps over the(1) quick brown fox
}
\end{document}

wobei jumble.lua(was in dieselbe .texDatei integriert werden könnte, ich es aber lieber getrennt behalte) das Folgende ist:

-- Expected from TeX: before calling print_sentence1_lines(),
--     call get_sentence1_lines() and get_sentence2_words()
--     define \printword and \linesep.
-- Globals: sentence2_words, position_for_word, sentence1_lines

function get_sentence1_lines()
   sentence1_lines = token.scan_string()
end

function get_sentence2_words()
   local sentence2 = token.scan_string()
   sentence2_words = {}
   position_for_word = {}
   local i = 0
   for word in string.gmatch(sentence2, "%S+") do
      i = i + 1
      assert(position_for_word[word] == nil, string.format('Duplicate word: %s', word))
      sentence2_words[i] = without_tags(word)
      position_for_word[word] = i
   end
end

function print_sentence2()
   for i, word in ipairs(sentence2_words) do
      tex.print(word)
   end
end

function print_sentence1_lines()
   for line in string.gmatch(sentence1_lines, "[^+]+") do
      for word in string.gmatch(line, "%S+") do
         position = position_for_word[word]
         assert(position_for_word[word] ~= nil, string.format('New word: %s', word))
         tex.print(string.format([[\printword{%s}{%s}]], without_tags(word), position))
      end
      tex.print([[\linesep]])
   end
end

function without_tags(word)
   local new_word = string.gsub(word, "%(.*%)", "")
   return new_word
end

Dadurch entsteht

Ausgabe

wie in der Frage.

Beachten Sie, dass Sie dies durch Verschieben etwas kürzer machen können (siehe z. B. die erste Überarbeitung dieser Antwort), aber ich finde es am saubersten, die Satzanweisungen .texund die Programmierung (so weit wie möglich) in der .luaDatei zu belassen.

Antwort2

Etwas wie das?

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\seq_new:N \l_jsp_sentence_temp_seq
\seq_new:N \l_jsp_sentence_original_seq
\seq_new:N \l_jsp_sentence_jumbled_seq
\prop_new:N \l_jsp_sentence_original_ind_prop
\prop_new:N \l_jsp_sentence_jumbled_ind_prop
\int_new:N \l_jsp_sentence_word_int

\NewDocumentCommand{\parseoriginalsentence}{m}
 {
  \seq_set_split:Nnn \l_jsp_sentence_temp_seq { + } { #1 }
  \seq_clear:N \l_jsp_sentence_original_seq
  \prop_clear:N \l_jsp_sentence_original_ind_prop
  \seq_map_inline:Nn \l_jsp_sentence_temp_seq
   {
    \int_zero:N \l_jsp_sentence_word_int
    \clist_map_inline:nn { ##1 }
     {
      \int_incr:N \l_jsp_sentence_word_int
      \seq_put_right:Nn \l_jsp_sentence_original_seq { ####1 }
      \prop_put:Nnx \l_jsp_sentence_original_ind_prop
       { ####1 } { \int_to_arabic:n { \l_jsp_sentence_word_int } }
     }
    \seq_put_right:Nn \l_jsp_sentence_original_seq { + }
   }
 }
\NewDocumentCommand{\parsejumbledsentence}{m}
 {
  \prop_clear:N \l_jsp_sentence_jumbled_ind_prop
  \seq_set_split:Nnn \l_jsp_sentence_jumbled_seq { , } { #1 }
  \int_zero:N \l_jsp_sentence_word_int
  \seq_map_inline:Nn \l_jsp_sentence_jumbled_seq
   {
    \int_incr:N \l_jsp_sentence_word_int
    \prop_put:Nnx \l_jsp_sentence_jumbled_ind_prop
     { ##1 } { \int_to_arabic:n { \l_jsp_sentence_word_int } }
   }
 }

\NewDocumentCommand{\printoriginalsentence}{s}
 {
  \IfBooleanTF{#1}
   {
    \jsp_sentence_print_from_original:
   }
   {
    \jsp_sentence_print_from_jumbled:
   }
 }

\cs_new_protected:Nn \jsp_sentence_print_from_original:
 {
  \seq_map_inline:Nn \l_jsp_sentence_original_seq
   {
    \tl_if_eq:nnTF { ##1 } { + }
     {
      \par
     }
     {
      \prop_item:Nn \l_jsp_sentence_original_ind_prop { ##1 }.\nobreakspace ##1 ~
     }
   }
 }

\cs_new_protected:Nn \jsp_sentence_print_from_jumbled:
 {
  \seq_map_inline:Nn \l_jsp_sentence_original_seq
   {
    \tl_if_eq:nnTF { ##1 } { + }
     {
      \par
     }
     {
      \prop_item:Nn \l_jsp_sentence_jumbled_ind_prop { ##1 }.\nobreakspace ##1 ~
     }
   }
 }
\ExplSyntaxOff

\begin{document}

\parseoriginalsentence{
  The,
  quick,
  brown,
  fox
  +
  jumps,
  over,
  the,
  lazy,
  dog
}
\parsejumbledsentence{
  The,
  lazy,
  dog,
  jumps,
  over,
  the,
  quick,
  brown,
  fox
}

\printoriginalsentence*

\bigskip

\printoriginalsentence

\end{document}

Bildbeschreibung hier eingeben

verwandte Informationen