RTL 텍스트 환경에서 화살표 방향이 잘못됨

이 문제는 Discourse의 bidi(양방향 텍스트) 설정과는 전혀 관련이 없습니다.

->를 입력하면 화살표 문자 →로 변환되어, A -> B가 "A → B"로 표시됩니다. 꽤 멋진 기능이죠.

하지만 RTL(오른쪽에서 왼쪽으로 읽는) 텍스트에서는 화살표 방향이 잘못 표시됩니다. א -> ב를 입력하면 화살표 방향이 반대인 "א → ב"로 렌더링됩니다. (이 버그가 수정된 후 이 글을 읽는다면, 원래는 "א → ב"로 렌더링되었습니다.)

여기서 입력된 문자열의 문자 시퀀스는 다음과 같습니다:

문자 이름
א HEBREW LETTER ALEF
SPACE
- HYPHEN-MINUS
> GREATER-THAN SIGN
SPACE
ב HEBREW LETTER BET

이 문자열 א -> ב을 https://unicodedecode.com/ 도구로 복사하여 붙여넣으면 확인할 수 있습니다.

이는 화살표 문자가 Unicode에서 bidi 미러링(bidi-mirror)을 하지 않기 때문입니다. 관련 문서: https://www.unicode.org/L2/L2022/22026r-non-bidi-mirroring.pdf

특히, 화살표 및 화살표 모양의 문자는 각각 대칭 문자가 있는 경우가 많습니다. Bidi_Mirrored=Yes 속성 값을 가졌어야 한다고 주장할 수도 있지만, 실제로는 그렇지 않으며, 이제 그 값을 부여할 수도 없습니다.

불행히도 bidi 방향에 따라 자동으로 반전되는 화살표 문자가 존재하지 않습니다. 즉, 이 치환을 올바르게 수행하려면 주변 텍스트의 bidi 방향을 결정하여 <-와 → 화살표 중 올바른 것을 선택해야 합니다. 쉬운 작업이 아닙니다.

1개의 좋아요

@falco 이건 기능 요청이 아니라 실제로 버그라고 생각합니다. 출력이 사용자의 의도와 기대와 정반대입니다.

다음과 같이

즉, 우리는 현재 유니코드 사양을 따르고 있으므로, 새로운 기능을 구축해야 합니다. 그래서 이를 Contribute > Feature 요청으로 재분류했습니다.

실제로 문제를 해결하는 것에 대해 말씀드리자면, 기존 api.decorateCooked API를 사용하여 #customization:theme-component에서 쉽게 수행할 수 있다고 생각합니다.

2개의 좋아요

감사합니다. 특정 포럼에서 문제를 해결하는 데 서두를 이유는 없으며, 다만 이 문제가 Discourse에서 수정되어야 한다고 생각합니다.

의미론에 대해 의미 없는 논쟁을 벌이고 싶지 않으므로 이 정도로 하겠습니다. 제 생각은 이미 말씀드렸고, 이는 버그로 간주되어야 한다고 생각하지만, 그 이후에 어떻게 처리할지는 이제 여러분의 몫입니다.

관심과 빠른 답변에 감사드립니다 :slight_smile:

1개의 좋아요

음… 사람은 한계가 있잖아요. 마지막으로 한 가지만 말씀드릴게요 (약속합니다). 제가 아는 한, Unicode 사양은 ->를 →로 변환하는 것을 권장하지 않습니다(그리고 이 문제가 그 이유 중 하나가 될 수 있겠죠). 따라서 기존 Discourse의 이 기능은 어떤 Unicode 사양도 따르지 않고 있습니다. 텍스트에 대해 잘못된 가정을 하고 있고, 그 과정에서 이 버그를 유발합니다. 제 생각은 이렇습니다. (다만 이 기능 자체는 여전히 괜찮긴 합니다)

이제 할 말은 다 했어요!

3개의 좋아요

우측에서 좌측으로 쓰이는 언어(RTL)로 입력할 때, ‘dash’(하이픈)를 입력한 뒤 ‘less than’(작음 기호)을 입력하면 왼쪽 화살표(←)로 변환되기를 기대할 수 있을 것입니다. 저에게는 꽤 합리적인 기대라고 생각합니다. 하지만 'less than’을 입력하면 편집기에 ‘greater than’(큼 기호)이 삽입됩니다. 이는 매우 예상치 못한 결과였습니다. 이것이 버그인가요?

RTL 텍스트 박스(예: aljazeera.net의 검색창)에서는 RTL 텍스트 내에서 숫자와 수학적 기호가 LTR(좌측에서 우측으로) 순서로 삽입되는 것을 확인할 수 있습니다. 이는 충분히 자연스러운 동작입니다. (라틴 문자도 동일한 방식으로 처리됩니다.)

아래에서는 RTL 컨텍스트에서 "less than is < and greater than is >"를 입력해 보겠습니다. (이것이 RTL 로케일에서 실제로 어떻게 동작하는지 정확히 알 수는 없지만요.)

‮less than is < and greater than is >

3개의 좋아요

일상생활에서 우에서 왼쪽(RTL) 문자를 사용하시나요? 아닙니다よね? (아니시죠?) 당신이 설명한 내용에는 버그가 없습니다. 당신의 말에 모호한 부분이 있어서 혼동을 방지하기 위해 먼저 댓글의 두 번째 부분을 다룰 것입니다.

이것은 정확히 그렇게 작동해야 하는 방식입니다. 이렇게 생각해 보세요:

> 문자는 문자 그대로 "크다(greater than)"를 의미합니다. "A > B"라는 문자열은 "A가 B보다 크다"는 뜻입니다.

마찬가지로, "א가 ב보다 크다"라고 하려면 "is greater than(보다 크다)"라는 부분을 같은 큼 기호인 U+003E 코드의 >로 대체합니다. 그러나 이 문자열이 완전히 RTL(우에서 왼쪽)이므로, "א"는 "ב"의 오른쪽에 표시됩니다. 만약 “크다” 기호가 LTR(왼쪽에서 오른쪽)과 동일하게 렌더링된다면, 다음과 같이 보일 것입니다: א<ب. 이는 “א가 ב보다 작다” 또는 "ב가 א보다 크다"로 읽히며, 설명하려는 관계와 정반대가 됩니다.

이것이 크다(greater-than) 기호를 렌더링할 때 RTL 환경에서는 시각적으로 뒤집히는 이유입니다. 하지만 기본 문자와 이를 뒷받침하는 Unicode 데이터는 여전히 “크다” 기호입니다. 이 문자열은 여전히 "א가 ב보다 크다"는 의미를 가집니다.

이제 첫 번째 질문으로 돌아가 보겠습니다:

키보드 레이아웃을 RTL 언어(히브리어나 아랍어 등)로 변경했다면, Shift+, 조합키(<가 인쇄된 키)는 실제로 “크다” 기호인 >를 입력하게 됩니다. 이는 당신이 발견한 검색 상자처럼 RTL 컨텍스트에서 ‏>‏로 렌더링됩니다.

[편집: 다음 단락은 당신이 테스트했다고 한 것을 제가 약간 오해했을 때 작성되었습니다. 저는 당신이 LTR 키보드로 RTL 상자에 입력하고 있다고 생각했지만, 실제로는 그 반대 상황이었습니다. 그래도 당신의 혼란을 해소했기를 바랍니다.]

하지만 당신은 여전히 라틴 문자 키보드 레이아웃을 사용하므로, 그 조합키를 누르면 “작음” 기호인 <가 삽입됩니다. 하지만 렌더링은 ‏<‏로 이루어집니다. 왜냐하면 RTL에서는 오른쪽에 있는 것이 왼쪽에 있는 것보다 작다는 의미가 되기 때문입니다.

결론: 문자는 동일하지만, 렌더링이 거울처럼 뒤집힙니다.

지금까지 제가 설명한 내용을 이해하셨다면, -< 또는 RTL에서는 ‏-<‏가 된다는 것을 이해하실 것이며, 이것이 당신이 의도한 바가 아니라고 생각합니다.

제가 성공적으로 설명했나요, 아니면 오히려 더 혼란스러워지셨나요?

1개의 좋아요

공식 유니코드 문서가 더 낫다고 생각되면, 이 문서를 시도해 보세요: UAX #9: Unicode Bidirectional Algorithm 'mirror’로 Ctrl+F를 누르면 좋은 설명과 예시를 몇 가지 찾을 수 있습니다.

1개의 좋아요

정말 맞으시네요. 저는 경험도 없이, 게다가 라틴 키보드까지 들고 뛰어든 셈이죠!

그러니 조용히 있어야 할 텐데… 그래도 알자지라 검색창에 (제 라틴 키보드로) 3<6을 입력하면 이런 결과가 나옵니다:

아마도 이는 당신이 맞고 제가 틀렸다는 것을 보여주는 것일 텐데, 그런 결과는 당연한 일이죠!

2개의 좋아요

전혀 아닙니다! 만약 RTL 사용자가 RTL 버그에 대해 논의하고 수정할 수만 있다면, 우리는 훨씬 더 불리한 상황에 놓이게 될 것입니다! 저는 이 기회를 빌려 이 주제에 대해 여러분을 소개해 드린 것뿐입니다. 이 주제를 완전히 이해하는 데는 시간이 좀 걸릴 수 있습니다. 이 주제와 관련하여 더 궁금한 점이나 질문이 있으시면 기꺼이 답변해 드리겠습니다.

1개의 좋아요

이런 경우의 해결책이 될 수 있는 Unicode 추가 사항을 제안하기 위해 Unicode 메일링 리스트에 가입했습니다. 제가 받은 답변 중 하나는 다음과 같습니다:

(나:) 문제는 이 치환이 (제가 아는 한) 어떤 렌더링 컨텍스트 밖에서, 텍스트가 단순히 문자 코드 시퀀스인 상태에서 수행된다는 것입니다. 텍스트가 어떤 방향으로 흘러가는지 아는 것은 합리적이지 않습니다. 텍스트 방향이 치환 시점에 사용할 수 없는 컨텍스트에 의존하는 경우, 그것은 완전히 불가능할 수도 있습니다.

위 설명은 엄밀히 말하면 부정확합니다. 오늘날 모든 진지한 텍스트 렌더링은 HarfBuzz와 같은 셰이핑 엔진(shaping engine)을 필요로 하며, "->"를 "→"로 연결하는 리가처(연결 문자) 생성은 리가처를 지원하는 폰트와 협력하여 이러한 셰이퍼에 의해 수행됩니다. 셰이핑 엔진은 자신이 셰이핑하는 텍스트의 바이디(bidi) 컨텍스트와 스크립트를 인식하므로, 원칙적으로 화살표를 미러링할 수 있습니다.

그들은 다음과 같은 것을 이야기하고 있습니다: GitHub - tonsky/FiraCode: Free monospaced font with programming ligatures · GitHub

눈먼 문자 치환 대신 리가처 방식을 사용하는 것으로 전환하는 것을 고려해 보세요. 또 다른 논쟁의 여지가 있는 장점은 복사-붙여넣기 했을 때 텍스트가 화살표가 아닌 여전히 "->"로 남아있을 것이라는 점입니다.

이것을 구현하는 기술적 세부 사항은 조사해 보지 않았습니다. 이 해결책을 사용하기로 결정하신다면 그것은 당신에게 맡기겠습니다.

수정: 글쎄, 놀랍지 않게도 Fira Text는 특히 RTL을 염두에 두고 설계되지 않았기 때문에 렌더링이 어긋나 있습니다 - 하지만 적어도 화살표 방향은 맞습니다! https://fonts.google.com/specimen/Fira+Code?preview.text=A%20->%20B,%20א%20->%20ב
Firefox:

오늘날 이걸 올바르게 수행하고 RTL/바이디를 명시적으로 지원하는 폰트가 존재하는지 확실하지 않습니다.

1개의 좋아요

흥미롭게도 Chromium에서는 다른 결과가 나옵니다:
수정: 지금은 재현할 수 없으니, 이 스크린샷을 찍을 때 잘못 입력한 것 같습니다.
수정: 그리고 지금은 다시 재현할 수 있습니다. 상황이 심각합니다.

브라우저 렌더링 엔진/셰이퍼가 이 작업을 수행할 수 있는 수준이 아닌 것 같습니다. 더 조사해야 하지만, 이건 지금 제가 집중해야 할 부분이 아닙니다…

수정: 포럼의 제한 때문에 이전 답변에서 이 내용을 삭제해야 했습니다:
참고로, 이 치환을 담당하는 코드는 다음과 같습니다:

1개의 좋아요

앞서 언급했듯이, 저는 이 문제에 대한 Unicode 해결책을 제안하는 작업을 진행 중입니다. 해당 문서에서 문제를 자세히 설명했으며, 여기서 설명한 것보다 더 명확하게 서술했을 것입니다. 아직 작업 중(WIP)이지만, 아래 링크를 확인해 주시면 감사하겠습니다: Create [<message>] git stash create. (영구 링크)

특히 Discourse 섹션을 꼭 살펴보세요.

물론, Unicode에서 이 제안을 수용하더라도(제가 마침내 제출했을 때), 널리 구현되어 신뢰할 수 있을 때까지 수년이 걸릴 것이므로, 그것을 기다리는 것은 좋은 계획이 아닙니다.