Předpokládám, že bych chtěl cenzurovat slovo kletby <word> pomocí grawlixes , např „Co děláš # @ $ !!“ Jak mohu definovat příkaz \censor tak, aby výsledkem \censor{<word>} byl řetězec těchto symbolů? Nejsem si úplně jistý, které nebo kolik symbolů by mělo být použito vzhledem ke slovu <word>. Předpokládám, že počet použitých symbolů by se měl přibližně rovnat počtu znaků v <word>.

Děkujeme za váš příspěvek!

Komentáře

  • Je mnohem jednodušší to udělat ve zdroji textového editoru než v TeXu. (luatex je pravděpodobně jednodušší než klasický tex, pokud to opravdu chcete udělat na úrovni textu) (Je to dost snadné v omezených textových kontextech, ale těžké, pokud to potřebujete v libovolných odstavcích a seznamech atd.)
  • viz také tex.stackexchange.com/questions/88394/…
  • @percusse I # @ $! &%? !% $ @!% $.
  • @GonzaloMedina Mohu si koupit samohlásku?
  • No, alespoň Dnes jsem se naučil nové slovo . Proč ale ‚ není množné číslo grawlices ?

Odpovědět

Náhodný symbol je převzat ze seznamu a připojen k seznamu tokenů; je-li šířka nashromážděných symbolů větší než šířka slova minus 2 body, symboly se vytisknou, jinak se přidá další symbol.

\documentclass{article} \usepackage{xparse,pgf} \ExplSyntaxOn \NewDocumentCommand{\censor}{m} { \pointer_censor:n { #1 } } \seq_new:N \g_pointer_grawlixes_seq \tl_map_inline:nn { @ * \# ! \$ \% ? ! \# @ \% *} { \seq_gput_right:Nn \g_pointer_grawlixes_seq { #1 } } \int_const:Nn \c_pointer_grawlix_list_int { \seq_count:N \g_pointer_grawlixes_seq } \dim_new:N \l_pointer_censor_dim \dim_new:N \l_pointer_try_dim \box_new:N \l_pointer_censor_box \tl_new:N \l_pointer_grawlixes_tl \cs_new_protected:Npn \pointer_censor:n #1 { \tl_clear:N \l_pointer_grawlixes_tl \hbox_set:Nn \l_pointer_censor_box { #1 } \dim_set:Nn \l_pointer_censor_dim { \box_wd:N \l_pointer_censor_box } \pointer_add_grawlix: } \cs_new_protected:Npn \pointer_add_grawlix: { \hbox_set:Nn \l_pointer_censor_box { \l_pointer_grawlixes_tl } \dim_compare:nTF { \l_pointer_censor_dim - 2pt < \box_wd:N \l_pointer_censor_box } { \tl_use:N \l_pointer_grawlixes_tl } { \pgfmathparse{random(1,\int_eval:n {\c_pointer_grawlix_list_int})} \tl_put_right:Nx \l_pointer_grawlixes_tl { \seq_item:Nn \g_pointer_grawlixes_seq { \pgfmathresult } } \pointer_add_grawlix: } } \ExplSyntaxOff \begin{document} Censored \censor{Censored} \end{document} 

zde zadejte popis obrázku

Odpověď

Pokorný pokus s lualatex:

Náhradní kód je velmi naivní, potřebovali bychom něco robustnějšího.

\documentclass{article} \directlua{ % my list of bad words bad_words = { "fish", "cat", "dog", "horse", "alligator" } % the replacement string replacement = "duck" % a replacement function which returns % both the altered line and the number % of occurrences function replace(line) for _, element in pairs(bad_words) do if string.find(line, element) then return string.gsub(line, element, replacement) end end return line, 0 end % my "naive" censor function, it simply % replaces any occurrences of the % list of bad words by the replacement % string function censor(line) occurrences = 0 repeat line, occurrences = replace(line) until occurrences == 0 return line end % add the hook callback.register("process_input_buffer", censor)} \begin{document} Once upon a time, there was a little cat who lived inside an igloo. Don"t ask me what he was doing there. One day, the cat was visited by his two other friends, the dog and the alligator! --- ``What are you guys doing here?"", said the cat. --- ``We came to visit you, mr.\ cat!"", said the dog. --- ``Our friend horse will be late, he went to the store to buy some frozen fish for you``, replied the alligator. \end{document} 

Výstup:

Více kachen

Morální příběh: Vyprávění příběhů je hrozné. :)

Nyní přidejme grawlixy . Jelikož potřebuji lepší kód Lua, vytvořme externí soubor censor.lua a zavoláme jej z .tex kódu:

\begin{filecontents*}{censor.lua} -- a list of symbols to represent the -- grawlixe symbols -- note that we need to escape -- some chars grawlixe_symbols = { "\\$", "\\#", "@", "!", "*", "\\&" } -- generate a grawlixe of length s -- note that the seed is not so random, so -- same values of s might get the same -- grawlixe pattern (I could add another seed -- mid code, but I"m lazy) function grawlixe(s) math.randomseed(os.time()) local u = table.getn(grawlixe_symbols) local i = math.random(u) local r = grawlixe_symbols[i] local current local w = 1 repeat current = math.random(u) while current == i do current = math.random(u) end i = current r = r .. grawlixe_symbols[i] w = w + 1 until w == s return r end -- a list of bad words to be censored bad_words = { "fish", "cat", "dog", "horse", "alligator" } -- our replacement function, it returns -- the new line and the number of -- replacements made -- note that this is a very naive replacement -- function, there"s a lot of room for -- improvement function replace(line) for _, element in pairs(bad_words) do if string.find(line, element) then return string.gsub(line, element, grawlixe(string.len(element))) end end return line, 0 end -- the censor function, it repeats -- ad nauseam until the line has -- nothing more to be censored function censor(line) local occurrences = 0 repeat line, occurrences = replace(line) until occurrences == 0 return line end -- register the callback callback.register("process_input_buffer", censor) \end{filecontents*} \documentclass{article} \directlua{dofile("censor.lua")} \begin{document} Once upon a time, there was a little cat who lived inside an igloo. Don"t ask me what he was doing there. One day, the cat was visited by his two other friends, the dog and the alligator! --- ``What are you guys doing here?"", said the cat. --- ``We came to visit you, mr.\ cat!"", said the dog. --- ``Our friend horse will be late, he went to the store to buy some frozen fish for you``, replied the alligator. \end{document} 

Výstup:

Grawlixes

Morálka nového příběhu: přidáním grawlixů do textu to vypadá nezbedně. :)

Komentáře

  • +1 (i když jsem doufal, že uvidím kachní obrázek, možná byl cenzurován?)

Odpověď

Když vynechám výhody a nevýhody toho, jak a proč to udělat, považuji to za pěkné malé cvičení s xstring . Takže tady na to přijdu:

\documentclass{article} \usepackage{xstring} \def\grawlix{{\makeatletter@\makeatother}\textdollar{$\sharp$}*?!} \newcommand{\censor}[1]{\StrLen{#1}[\result]% \expandarg\StrLeft{\grawlix}{\result}[]} \begin{document} What the \censor{word} is this??? \end{document} 

Jak vidíte, omezení spočívá v tom, že grawlix bude složen ze stejné sady znaků ve stejném pořadí. (Můžete předefinovat znakovou sadu nebo najít způsob, jak je náhodně vybrat při každém vyvolání makra … ale to je jiný příběh! ;)) Ale váš grawlix bude tak dlouhý jako cenzurované slovo.

Co se stane, je to, že xstring má své vlastní způsoby rozšiřování argumentů a makra nelze vnořovat. Výsledek z makra, které najde délka cenzurovaného slova je vrácena v jiném makru (zde imaginárně nazvaném \result), které bude (znovu) použito k rozdělení předdefinovaných \grawlix na správném místě.

Makro \expandarg zajišťuje správné provedení expanze. Podle xstring dokumentace, umožní všechny předané argumenty přesně rozbalit jednou. Proto je třeba dbát na ochranu skupin, které představují jeden znak se složenými závorkami (např. \sharp symbol žije v matematickém režimu, ale nezůstáváme Znaky dolaru, které jej vymezují, aby byly považovány za samostatné tokeny).

Komentáře

  • Nemám ‚ t myslet \makeatletter a \makeatother jsou kolem @ … nezbytné. Může být použit jako symbol hned.
  • @cgnieder To ‚ sa dobrá práce nejsou nutné, protože nemají vůbec žádný účinek, pokud jsou použity uvnitř definice jako zde: – )
  • @DavidCarlisle pravda, o tom jsem ‚ nepřemýšlel … potřebuji více kávy

Odpověď

Jednoduché řešení TeX bez dalších balíčků, založené na nápadech Keese van der Laana.

\documentclass{article} \begin{document} \newcount\cur \newcount\cura \def\fifo#1{\ifx\ofif#1\ofif\fi \process#1\fifo} \def\ofif#1\fifo{\fi} \def\mynum#1{\cur\the\lccode`#1\relax\the\cur } \def\process#1{\cur\the\lccode`#1\relax\cura\cur \divide\cura by7 \multiply\cura by7 \advance\cur by-\cura\ifcase\cur!\or@\or\#\or\$\or\%\or\&\or*\else ERROR\fi } \fifo censored \ofif \bigskip \def\censor#1{\fifo #1\ofif} \censor{fuck} \censor{WORD} it is \censor{shit} \end{document} 

Pravděpodobně chcete mít výsledek spojený s použitým slovem.V tomto řešení se jedná o \lccode znakového modulu 7. Můžete napsat buď

 \fifo censored \ofif 

nebo, jak je navrženo (omlouvám se za můj jazyk),

\censor{fuck} \censor{WORD} it is \censor{shit} 

získání

zde zadejte popis obrázku

Několik vysvětlení. Hlavním nástrojem je implementace fronty FIFO (First-In-First-Out) navržené Keesem van der Laanem:

\def\fifo#1{\ifx\ofif#1\ofif\fi \process#1\fifo} \def\ofif#1\fifo{\fi} 

volá makro \process, které zpracovává jednotlivé argumenty. Každý token je zpracováván do \ofif.

Zbytek je jednoduchý. Manipulací na pultech \cur a \cura získáme číslo mezi 0 a 6 a \ifcase bere různé znaky cenzury pro různé hodnoty.

Poznámka. Velmi mě zajímají skutečná pravidla ( pokud existují) nahrazení prokletých slov řetězci symbolů podobných @.

Komentáře

  • Velmi pěkné. Mohli byste snad trochu prominout (promiňte hříčku), jak kód ve skutečnosti funguje?
  • @AlanMunn Ano, ale po návratu domů (pozdě večer).
  • \censor{MSWORD}

odpověď

Stabilním způsobem výměny symbolů je změna kódování písma nebo překódovat písmo. Jednoduchý příklad

\documentclass{article} \begin{document} \newcommand\censor[1]{\fontencoding{OMS}\selectfont #1} \censor{Censored} \end{document} 

S lualatexem bude v budoucnu (až bude rozhraní stabilnější) pravděpodobně možné vytvářet virtuální překódovaná písma na místě létat, v současné době by to už mělo být možné udělat se souborem funkcí.

Odpověď

Toto je rozšíření pro @egreg „s odpověď pomocí jiné odpovědi od @egreg.

Pomocí tohoto kódu můžete zadat celou větu do \censor a všechna slova původně přidaná do seznamu pomocí \addcensor jsou nahrazena grawlixes. Argument \addcensor může být buď jedno slovo nebo seznam oddělených čárkami.

\documentclass{article} \usepackage{xparse,pgf} \ExplSyntaxOn \NewDocumentCommand{\censor}{m} { \pointer_badseq:n { #1 } } \tl_new:N \g_pointer_badwords_tl \NewDocumentCommand{\addcensor}{m} { \clist_map_inline:nn { #1 } { \tl_gput_right:Nn \g_pointer_badwords_tl { {##1}{} } } } \cs_generate_variant:Nn \str_case:nnTF { nV } \cs_new_protected:Npn \pointer_badseq:n #1 { \seq_set_split:Nnn \l_tmpa_seq { ~ } { #1 } \seq_map_inline:Nn \l_tmpa_seq { \str_case:nVTF { ##1 } \g_pointer_badwords_tl { \pointer_censor:n { ##1 } } { ##1 } ~ % Readd space } \tex_unskip:D % Remove the trailing space } % From @egreg"s answer \seq_new:N \g_pointer_grawlixes_seq \tl_map_inline:nn { @ * \# ! \$ \% ? ! \# @ \% *} { \seq_gput_right:Nn \g_pointer_grawlixes_seq { #1 } } \int_const:Nn \c_pointer_grawlix_list_int { \seq_count:N \g_pointer_grawlixes_seq } \dim_new:N \l_pointer_censor_dim \dim_new:N \l_pointer_try_dim \box_new:N \l_pointer_censor_box \tl_new:N \l_pointer_grawlixes_tl \cs_new_protected:Npn \pointer_censor:n #1 { \tl_clear:N \l_pointer_grawlixes_tl \hbox_set:Nn \l_pointer_censor_box { #1 } \dim_set:Nn \l_pointer_censor_dim { \box_wd:N \l_pointer_censor_box } \pointer_add_grawlix: } \cs_new_protected:Npn \pointer_add_grawlix: { \hbox_set:Nn \l_pointer_censor_box { \l_pointer_grawlixes_tl } \dim_compare:nTF { \l_pointer_censor_dim - 2pt < \box_wd:N \l_pointer_censor_box } { \tl_use:N \l_pointer_grawlixes_tl } { \pgfmathparse{random(1,\int_eval:n {\c_pointer_grawlix_list_int})} \tl_put_right:Nx \l_pointer_grawlixes_tl { \seq_item:Nn \g_pointer_grawlixes_seq { \pgfmathresult } } \pointer_add_grawlix: } } \ExplSyntaxOff \addcensor{censored,duck} \addcensor{street} \begin{document} A censored man walk down the street together with his duck. \censor{A censored man walk down the street together with his duck}. \end{document} 

zadejte popis obrázku zde

Komentáře

  • Naštve mě, když použijete tradiční umisťování otevřených a uzavírací složená závorka (otevřená složená závorka sousedící s funkcí, pak nový řádek, poté kód a pak samotná uzavírací složená závorka v novém řádku – bez odrážky -), smícháním s doporučeným způsobem LaTeX3 (obě samostatně na novém řádku, odsazeno stejné množství prostoru).
  • @Manuel Omlouváme se, Doufám, že moje aktualizovaná odpověď odpovídá doporučenému stylu.
  • Určitě lepší (IMO). Líbí se mi tento způsob, dokonce i teď, když ‚ m čtu zdrojový kód ConTeXt a ten píše úplně jinak (alespoň nepoužívají ‚ t úvodní složená závorka, nový řádek, kód, nová zavírací závorka řádku bez přílišného odsazení, ale něco jako %, nový řádek, úvodní složená závorka a kód, další kód a uzavírací složená výzva další ke kódu).

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *