Q&A 마당은 텍 관련 질문/답변을 위해 만들었습니다.
- 로그인 없이 자유롭게 글을 읽고 쓸 수 있는 철학은 처음과 같이 계속됩니다.
- 질문 전에 아래를 읽어 보세요. 좋은 질문이 좋은 답을 받을 수 있는 좋은 방법입니다.
- 질문에 맞는 제목을 붙이세요. 질문의 내용과 관련없는 "고수님", "긴급질문", "도와주세요"와 같은 제목은 답이 잘 올라오지 않습니다. 이 게시판에 올라오는 모든 글은 질문입니다. 굳이 [질문], [Q]를 적으실 필요도 없습니다.
- 내용을 충실히 적어 주시고, 같은 상황을 재현할 수 있는 최소한의 예제가 같이 있어야 합니다.
- 최소 예제는 "Minimal working example"을 읽어 보세요.
- 파일을 첨부하실 때에는 가능한 압축하여 파일 크기를 줄여서 올려주시길 바랍니다.
- 개인적으로 사용하신 글꼴이 들어 있는 경우, preparefont.sty에 관한 답변을 참조하세요.
- 스팸 글을 막기 위하여 짧은 시간 내에 다시 글이 등록되는 IP를 막거나, 광고 글을 막기 위하여 금지어로 .com, .net 등을 설정하고 있습니다. 다소간의 불편함이 있으시더라도 양해 바랍니다.
- 금지어에서 stackexchange, stackoverflow, ctan, overleaf, , github, google.com, gmail.com, .org, .io, sil.org, wiki.com, tistory.com등은 해제하였습니다.
- MathJax를 이용한 수식조판을 사용하실 수 있습니다. 여기를 참조하세요.
- 사용하는 편집기는 CKeditor입니다.
- 편집기에서 [enter]를 누르면 <p> 태그가 들어가고, 문단으로 생각하고 한 줄을 비웁니다.
- 글줄만 바꾸려면 [shift-enter]를 누르면 <BR> 태그가 들어가므로 용도에 맞게 나누어 쓸 수 있습니다.
- 수식를 문서내에 삽입하시려면 에디터를 툴바에서 [소스]를 눌러 HTML로 입력할 수 있게 바꾸신 후 <pre> </pre> tag를 사용하셔서 <pre> 여러 줄의 수식 </pre>처럼 입력하시면 좋습니다.
공백 문자를 식별하는 방법
2016.06.14 08:59
문자열을 받아 문자를 하나씩 분리하여 처리하는 매크로를 만들었습니다.
http://www.ktug.org/xe/index.php?document_srl=219521&mid=KTUG_open_board
\NewDocumentCommand \segment { m }
{
\tl_map_inline:nn { #1 }
{
\str_case:nnF {##1}
{
{.} { \segment_include:n {dot} }
{?} { \segment_include:n {QM} }
{|} {\space} %% 여기에서 스페이스를 식별할 방법이 없어서
}
{ \segment_include:n {##1} }
}
}
이 매크로는 스페이스를 처리하지 못하는 문제가 있습니다. \tl_map_inline:nn이 스페이스를 무시(?)해 버리고 ##1에 넘겨주지 않습니다.
스페이스의 캣코드가 다르다는 점, 중복된 공백 문자들을 텍이 모두 무시한다는 점 등을 고려하면 아주 이상한 처리라고 말할 수 없습니다. 해법을 찾다가 궁여지책으로 세로 막대기(|)를 사용했습니다.
\segment{O 20.9} 대신 \segmen{O|20.9}라고 쓰는 거죠.
이 문제에 대한 해법이 있을까요?
댓글 11
-
DohyunKim
2016.06.14 12:51
-
yihoze
2016.06.14 13:59
고맙습니다. 깔끔하게 해결되었습니다.
-
DohyunKim
2016.06.14 14:36
사실 그냥 텍 문법에 더 편합니다. 적어도 제게는.
\protected\def\segment#1{\segmenti #1^^J} \def\segmenti{\afterassignment\segmentii\let\next= } \def\segmentii{% \ifx ^^J\next \else \ifx .\next dot\else \ifx ?\next QM\else \next \fi\fi \expandafter\segmenti \fi }
-
yihoze
2016.06.14 16:11
손에 익은 에디터가 편하듯이, 텍 문법도 개인 선호의 문제라고 생각합니다...만, 플레인 텍 문법은 그다지 시스터매틱해 보이지 않아요.
-
JangNa
2016.06.14 16:37
fifo ofif 들어갑니다.
\def\fifo{\afterassignment\tap\let\nxt= }
\def\tap{\ifx\nxt\ofif\ofif\fi\process\nxt\fifo}
\def\ofif#1\fifo{\fi}
\def\process#1{\ifx#1.dot\else\ifx#1?QM\else#1\fi\fi}
\def\segment#1{\fifo #1\ofif}
-
yihoze
2016.06.14 18:05
무엇보다 연이은 \fi\fi ... 우아하지 않아요. ^^
-
DohyunKim
2016.06.14 21:15
fifo는 언제봐도 예술이네요. \fi 두개 정도야 뭐 일도 아니죠. 열 개 스무 개 붙이는 경우도 드물지 않습니다.
latex3는 문법이 너무 어려워요. 위 플레인텍 알고리듬을 l3로 만들어볼려고 하니 잘 안돼서 포기했습니다.
어쨌거나 첫번째 답변에서요, SplitList 안쓰고 명령 하나만 정의해서도 가능해야 하지 않겠습니까. 논리는 동일합니다.
\NewDocumentCommand \segment { m } { \seq_set_split:Nnn \l_tempa_seq { ~ } { #1 } \seq_map_inline:Nn \l_tempa_seq { \seq_set_split:Nnn \l_tempb_seq { } { ##1 } \seq_map_inline:Nn \l_tempb_seq { \str_case:nnF { ####1 } { {.} { dot } {?} { QM } } { ####1 } } \c_space_token } \tex_unskip:D }
-
yihoze
2016.06.15 09:11
코드가 훨씬 더, 적어도 제 눈에는, 아름답게 바뀌었습니다. 고맙습니다.
-
DohyunKim
2016.06.15 11:42
더 간단하게 할 수 있는 방법이 있네요.
\NewDocumentCommand \segment { m } { \tl_set:Nn \l_tmpa_tl { #1 } \tl_replace_all:Nnn \l_tmpa_tl {.} {dot} \tl_replace_all:Nnn \l_tmpa_tl {?} {QM} \tl_use:N \l_tmpa_tl }
-
yihoze
2016.06.15 14:28
글자 치환이 목적이 아니라 한 글자씩 떼어내서 그에 상응하는 글자 이미지를 삽입하는 것이 원래 목적이었습니다.
알려주신 이 방법은 다른 용도로 쓸 수 있을 것 같습니다. 거듭 감사드립니다.
-
DohyunKim
2016.06.15 14:55
예의 치환의 대상은 문자열(string)이 아니라 토큰열(token list)입니다.
dot
대신에\includegraphics{dot}
를 넣어도 기대한대로 조판이 될 걸로 생각합니다.
그러니까 스페이스는 스페이스로 유지하고 싶다는 말씀이시죠?
latex3 문법을 사용한다는 전제 하에, 한 가지 방법을 제시해봅니다.
\SplitList
는 xparse 문서를 참고하십시오.스페이스로 인자를 분리한 후 각각 따로 처리합니다.
그리고 분리 처리한 끝부분에 스페이스 토큰을 넣어주어 스페이스를 되살리는 겁니다.
단, 이렇게 하면 맨 뒤에 의도하지 않은 스페이스가 들어가므로 최종적으로
\unskip
해서 이를 없애줍니다.