“写 300 句关于 \Lipsum 的句子”?这样的 `\Lipsum` 宏会很棒

“写 300 句关于 \Lipsum 的句子”?这样的 `\Lipsum` 宏会很棒

免责声明:这个问题不是为了满足一般需要。它甚至不是我自己的问题需要,或者任何其他人的“需要”。只是建议一个简洁的使用和抛出宏。

在为我和我的学生制作模板LaTeX文件时,我认为写下以下内容会很有趣:

Write \Lipsum 300 sentences.

该宏\Lipsum需要一个数字和一个终止序列。在上面的例子中,数字是整数 300。终止序列始终相同:sentences.,即标记的序列:“ s”,“ e”,...,“ e”,“ s”,“ .”。

宏将扩展为指定句子数的 Lipsum 文本。如果这些文本不总是相同就好了。

答案1

以下是利用 PGF 功能的可能解决方案:

\documentclass{article}

\usepackage{pgffor}

\def\getRandomSentence{%
   \pgfmathparse{random(5)}%
   \ifcase\pgfmathresult\relax
      Sentence 1.
   \or
      Sentence 2.
   \or
      Sentence 3.
   \or
      Sentence 4.
   \or
      Sentence 5.
   \else
      Default Sentence.
   \fi
}

\def\Lipsum#1 sentences.{%
   \ifnum#1<1
      ERROR!
   \else
      \foreach \n in {1,...,#1} {%
%         (\n)
         \getRandomSentence
      }%
   \fi
   \ignorespaces
}

\begin{document}
Test A:
Write \Lipsum 1 sentences. Test

Test B:
Write \Lipsum 10 sentences. Test

Test C:
Write \Lipsum 0 sentences. Test
\end{document}

只需添加适当数量的句子并相应地更改数字random(5)\Lipsum测试句子数是否大于或等于 1,如果不大于或等于,则写入“ERROR”。

\Lipsum 1 sentences.数字前的空格处选修的而数字后面的空格是强制的喜欢sentences.


不过我建议使用类似的正常语法\LipsumSentences{300}

答案2

我在我的博客中更详细地解释了这个实现:http://tobiw.de/tbdm/blindtext(仅限德语​​)

更新:

该实现现在尝试立即防止重复句子(和标点符号)。尝试获取不同含义的最大次数设置为 10,但可以在代码中更改。此外,调试信息稍好一些,现在也写入日志文件(终端)。


这是使用 LaTeX3 函数的另一种实现。在此解决方案中,可以设置带有 的句子池\SetLipsumPool和带有 的标点符号池\SetPunctPool

生成文本使用

\LipsumI <N> sentences.

或者

\LipsumII{<N>}

我会使用后者……

代码:

\documentclass{article}

\usepackage{pgffor,xparse}

\ExplSyntaxOn

% pool for sentences
\seq_new:N \g_yossi_lipsum_pool_seq
% count of sentences in pool
\int_new:N \g_yossi_lipsum_pool_int
% numbers for generating a random number
\int_new:N \g_yossi_current_int
\int_new:N \g_yossi_tries_int
\int_new:N \g_yossi_last_lipsum_int
\int_new:N \g_yossi_last_punct_int
% number of max tries to get a differnet random number than last on
\int_new:N \c_yossi_max_tries_int
\int_set:Nn \c_yossi_max_tries_int { 10 }
% pool for punctuation
\seq_new:N \g_yossi_punct_pool_seq
% count of punctuation marks in pool
\int_new:N \g_yossi_punct_pool_int
% boolean for debug mode
\bool_new:N \c_yossi_debug_bool
%\bool_set_true:N \c_yossi_debug_bool% debug mode on

\cs_new:Npn \yossi_add_to_lipsum_pool:n #1 {
   % set from argument by spliting at dots
   \seq_gset_split:Nnn \tmpa_seq { . } { #1 }
   \seq_gconcat:NNN \yossi_lipsum_pool_seq \yossi_lipsum_pool_seq \tmpa_seq
   % remove the duplicates
   \seq_gremove_duplicates:N \yossi_lipsum_pool_seq
   % remove emtpy sentences
   \seq_remove_all:Nn \yossi_lipsum_pool_seq { }
   % save number of sentences in pool
   \int_gset:Nn \g_yossi_lipsum_pool_int { \seq_count:N \yossi_lipsum_pool_seq }
}

% user macro to set up the pool
\NewDocumentCommand { \SetLipsumPool } { m } {
   \seq_gclear:N \yossi_lipsum_pool_seq
   \yossi_add_to_lipsum_pool:n { #1 }
}

% user macro to add sentences to the pool
\NewDocumentCommand{ \AddToLipsumPool }{ m }{
   \yossi_add_to_lipsum_pool:n { #1 }
}

% user macro to set up the pool
\NewDocumentCommand { \SetPunctPool } { m } {
   % set from argument
   \seq_gset_split:Nnn \g_yossi_punct_pool_seq { } { #1 }
   % save number of puctuation marks in pool
   \int_gset:Nn \g_yossi_punct_pool_int { \seq_count:N \g_yossi_punct_pool_seq }
}

\cs_new:Npn \yossi_get_random_number:NN #1#2 {
   \int_gzero:N \g_yossi_tries_int
   \bool_do_while:nn {
      \int_compare_p:n { #2 = \g_yossi_current_int }
      &&
      \int_compare_p:n { \g_yossi_tries_int < \c_yossi_max_tries_int }
   } {
      \pgfmathparse { random(1,#1) }
      \int_gset:Nn \g_yossi_current_int { \pgfmathresult }
      \int_gincr:N \g_yossi_tries_int
      \iow_term:x {
         [
            find ~ random ~ number: ~
            curr = \int_use:N \g_yossi_current_int \c_space_tl
            last = \int_use:N #2 \c_space_tl
            try = \int_use:N \g_yossi_tries_int
         ]
      }
   }
   % debug info
   \bool_if:NT \c_yossi_debug_bool {
      \newline (
      get ~ random ~ number: ~
      current\,=\,\int_use:N \g_yossi_current_int ; ~
      last\,=\,\int_use:N #2 ; ~
      tries\,=\,\int_use:N \g_yossi_tries_int )
      \newline
   }
   \int_gset_eq:NN #2 \g_yossi_current_int
}

% internal macro to get random sentecs
\cs_new_protected:Nn \yossi_get_random_sentence: {
   % get random sentence from pool
   \yossi_get_random_number:NN \g_yossi_lipsum_pool_int \g_yossi_last_lipsum_int
   \seq_item:Nn \yossi_lipsum_pool_seq { \g_yossi_current_int }
   % add random punctiation
   \yossi_get_random_number:NN \g_yossi_punct_pool_int \g_yossi_last_punct_int
   \seq_item:Nn \g_yossi_punct_pool_seq { \g_yossi_current_int }
   % add space
   \c_space_tl
}

% user macro to get #1 sentences
\def\LipsumI#1~sentences. {%
   \iow_term:x {
      ===================================== ^^J
      START LIPSUMS ^^J
      -------------------------------------
   }
   % test if ' is bigger than 1
   \int_compare:nTF { #1 < 1 } {% TRUE - #1 is smaller: Error
      ERROR!
   } {% FALSE - #1 is bigger: loop #1 times
      \foreach \n in {1,...,#1} {%
         % debug info
         \bool_if:NT \c_yossi_debug_bool {
            \par\bigskip
            \fbox{\textbf{n\,=\,\n}}
         }
         \iow_term:x {
            \n . ~ SENTENCE
         }
         % get random sentence (incl. punct and space)
         \yossi_get_random_sentence:
      }%
   }
   \iow_term:x {
      ------------------------------------- ^^J
      END LIPSUMS ^^J
      =====================================
   }
   % ignore spaces (on was added by \yossi_get_random_sentence: already)
   \ignorespaces
}

% alternative user macro with normal syntax
% (copy the implementation if you want to use this version)
\NewDocumentCommand{ \LipsumII } { m } {
   \LipsumI #1~sentences.
}


\ExplSyntaxOff

% preset pools
\SetLipsumPool{Lorem ipsum dolor sit amet, consectetur adipiscing elit.}
\SetPunctPool{.}

\begin{document}
% set pools
\SetLipsumPool{
   Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis lectus elit,
   tempus quis efficitur ut, consequat sed lorem. Cras convallis et nibh id
   accumsan.
}
\SetPunctPool{........:?!}% make dot more likely

Write \LipsumI 1 sentences. Test

Write \LipsumI 10 sentences. Test

Write \LipsumI 0 sentences. Test

\AddToLipsumPool{Another senseless sentence.}

Write \LipsumI 10 sentences. Test

\AddToLipsumPool{
   Pellentesque mollis, magna sed placerat mattis, quam nisl euismod dui, et
   sollicitudin orci lacus ac dolor. Phasellus pretium, purus ac lobortis
   mattis, leo libero lobortis ligula, ut rhoncus mauris purus at odio. Morbi
   vitae mollis ipsum. Morbi risus augue, feugiat quis posuere a, dapibus sed
   arcu. Fusce pharetra massa vitae tristique auctor. Sed sagittis placerat
   vestibulum. Curabitur a tempus arcu, eget ullamcorper urna. Maecenas
   malesuada placerat enim, sit amet commodo risus scelerisque vel. Sed vel
   feugiat est. Pellentesque habitant morbi tristique senectus et netus et
   malesuada fames ac turpis egestas. Praesent rhoncus facilisis quam in
   faucibus.
}

Write \LipsumI 10 sentences. Test

\SetLipsumPool{Only one sentence}

Write \LipsumI 10 sentences. Test

\bigskip
Write \LipsumII{5} Test
\end{document}

笔记:
该实现还包括一个基本的调试模式。

相关内容