Tegyük fel, hogy egy átokszót <word> cenzúrázni szeretnék a grawlixes , pl “Mi a # @ $! Csinálsz ?!” Hogyan definiálhatok egy \censor parancsot úgy, hogy a \censor{<word>} e szimbólumokból álló karaktersorozatot eredményezzen? Nem vagyok teljesen biztos abban, hogy melyik vagy hány szimbólumot kell használni a <word> szóra való tekintettel. Feltételezem, hogy a használt szimbólumok számának hozzávetőlegesen meg kell egyeznie a <word> karakterek számával.

Köszönjük a közreműködést!

Megjegyzések

  • Ezt sokkal könnyebb megtenni a szövegszerkesztő forrásban, mint a TeX-ben. (A luatex valószínűleg könnyebb, mint a klasszikus tex, ha valóban szöveges szinten akarja megtenni) (Elég egyszerű ezt korlátozott szöveges kontextusban megtenni, de nehéz, ha tetszőleges bekezdésekben és listákban kell megtenni stb.)
  • lásd még: tex.stackexchange.com/questions/88394/…
  • @percusse I # @ $! &%? !% $ @!% $.
  • @GonzaloMedina Vásárolhatok magánhangzót?
  • Nos, legalább ma megtanultam egy új szót . De miért nem ‘ t a többes számú szemcsék ?

válasz

Véletlenszerű szimbólumot veszünk fel egy listáról, és egy token listához csatolunk; ha a felhalmozott szimbólumok szélessége meghaladja a 2pt mínusz szó szélességét, akkor a szimbólumok kinyomtatásra kerülnek, különben egy másik szimbólum kerül hozzá.

\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} 

írja ide a kép leírását

Válasz

Alázatos kísérlet a :

A helyettesítő kód nagyon naiv, valami erősebbre lenne szükségünk.

\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} 

A kimenet:

További kacsa

Erkölcs a történet: Szörnyű vagyok a történetek elmondásában. :)

Most adjuk hozzá a grawlixeket . Mivel jobb Lua kódra van szükségem, hozzunk létre egy külső fájlt censor.lua, és hívjuk ki .tex kódból:

\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} 

A kimenet:

Grawlixes

Az új történet morálja: grawlixek hozzáadása egy szöveghez csintalannak tűnik. :)

Megjegyzések

  • +1 (bár reméltem, hogy kacsa képet látok, talán cenzúrázták?)

Válasz

Eltekintve az előnyeivel és hátrányaival, hogyan és miért kell ezt csinálni, jó kis gyakorlatnak tartom a következőt: xstring . Tehát itt állok vele:

\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} 

Amint láthatja, a korlátozás az, hogy a grawlix ugyanazokból a karakterekből áll, ugyanabban a sorrendben. (Lehet, hogy újradefiniálja a karakterkészletet, vagy megtalálhatja a módját, hogy véletlenszerűen véletlenszerűsítse őket a makró minden egyes meghívásakor … de ez “más történet! ;)) De a grawlixje olyan hosszú lesz mint a cenzúrázott szó.

Az történik, hogy xstring megvannak a maga módszerei az argumentumok kiterjesztésére, és a makrókat nem lehet egymásba ágyazni. Tehát a megtalált makró eredménye a cenzúrázott szó hossza egy másik makróban kerül visszaadásra (ötletesen itt nevezzük \result), amelyet (előre) az előre definiált \grawlix a megfelelő helyen.

A \expandarg makró gondoskodik a bővítés megfelelő végrehajtásáról. A xstring szerint dokumentációval, lehetővé teszi az összes átadott argumentum pontosan kibővítését egyszer. Ezért gondosan ügyelni kell arra, hogy zárójelekkel védjük azokat a csoportokat, amelyek egy egyetlen karaktert képviselnek (pl. a \sharp szimbólum mathmode-ban él, de mi nem t a dollárjelek azt határolják, hogy külön jelzőknek tekintsék).

Megjegyzések

  • Nem ‘ Nem gondolom, hogy \makeatletter és \makeatother szükségesek a @ körül … Ez azonnal használható szimbólumként használható.
  • @cgnieder Ez ‘ jó munka, nincs szükség rájuk, mivel egyáltalán nincs hatásuk, ha a definíciót belül használják, mint itt: – )
  • @DavidCarlisle igaz, nem gondoltam ‘ erre nem gondoltam … Több kávéra van szükségem

Válasz

Egyszerű TeX megoldás további csomagok nélkül, Kees van der Laan ötletei alapján.

\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} 

Valószínűleg az eredményt szeretné összekapcsolni a használt szóval.Ebben a megoldásban ez egy modul modul 7 \lccode karaktere. Írhat akár

 \fifo censored \ofif 

, akár a javaslat szerint (elnézést a nyelvemért),

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

lekérés

írja ide a kép leírását

Néhány magyarázat. A fő eszköz a Kees van der Laan által javasolt FIFO (First-In-First-Out) sor beültetése:

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

A parancs meghív egy makrót \process, amely kezeli az egyes argumentumokat. Minden tokent a \ofif -ig feldolgozunk.

A többi egyszerű. A \cur és a \cura számlálókon 0 és 6 és \ifcase számot kapunk különböző cenzor karaktereket vesz fel különböző értékekhez.

Megjegyzés. Nagyon érdekelnek a valós szabályok ( ha vannak ilyenek), akkor az átok szavakat @ típusú szimbólumokkal kell felváltani.

Megjegyzések

  • Nagyon szép. Esetleg kibővítené (elnézést a szójátékért) egy kicsit a kód tényleges működéséről?
  • @AlanMunn Igen, de miután hazatért (késő este).
  • \censor{MSWORD}

Válasz

A szimbólumok cseréjének stabil módja a fontkódolás megváltoztatása vagy a betűtípus újrakódolásához. Egyszerű példa

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

A lualatex használatával a jövőben (amikor az interfész stabilabb lesz) valószínűleg virtuális újrakódolt betűtípusokat lehet létrehozni a repülni, jelenleg lehetővé kell tenni egy funkciófájl használatával.

Válasz

Ez a @egreg “s válasz másik választ használ a @egreg által.

Ezzel a kóddal egész mondatot írhat be a és a listához a \addcensor használatával eredetileg hozzáadott összes szó helyébe grawlixek lépnek. A \addcensor argumentum lehet egyetlen szó vagy vesszővel elválasztott lista.

\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} 

írja be a kép leírását itt

Megjegyzések

  • Idegesít, ha a nyílt nyíl hagyományos elhelyezését használom és záró zárójel (nyitott zárójel a függvény mellett, majd új sor, majd a kód, majd a záró zárójel egyedül egy új sorban – behúzás nélkül), összekeverve az ajánlott LaTeX3 módszerrel (mindkettő egyedül egy új soron, ugyanannyi helyet behúzott).
  • @Manuel Sajnáljuk, Remélem, hogy frissített válaszom megfelel az ajánlott stílusnak.
  • Határozottan jobb (IMO). Tetszik ez a módszer, még most is, amikor ‘ olvasom a ConTeXt forráskódot, és teljesen másként ír (legalábbis nem használnak ‘ a nyitó zárójel, új vonal, kód, új vonal záró zárójel túl nagy behúzás nélkül, de valami hasonló %, új sor, nyitó zárójel és kód, további kód és záró zárójel kódhoz).

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük