1/* This file is part of the KDE libraries
2 SPDX-FileCopyrightText: 2008 Chusslove Illich <caslav.ilic@gmx.net>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include <common_helpers_p.h>
8
9// If pos points to alphanumeric X in "...(X)...", which is preceded or
10// followed only by non-alphanumerics, then "(X)" gets removed.
11static QString removeReducedCJKAccMark(const QString &label, int pos)
12{
13 if (pos > 0 && pos + 1 < label.length() //
14 && label[pos - 1] == QLatin1Char('(') //
15 && label[pos + 1] == QLatin1Char(')') //
16 && label[pos].isLetterOrNumber()) {
17 // Check if at start or end, ignoring non-alphanumerics.
18 int len = label.length();
19 int p1 = pos - 2;
20 while (p1 >= 0 && !label[p1].isLetterOrNumber()) {
21 --p1;
22 }
23 ++p1;
24 int p2 = pos + 2;
25 while (p2 < len && !label[p2].isLetterOrNumber()) {
26 ++p2;
27 }
28 --p2;
29
30 const QStringView labelView(label);
31 if (p1 == 0) {
32 return labelView.left(n: pos - 1) + labelView.mid(pos: p2 + 1);
33 } else if (p2 + 1 == len) {
34 return labelView.left(n: p1) + labelView.mid(pos: pos + 2);
35 }
36 }
37 return label;
38}
39
40QString removeAcceleratorMarker(const QString &label_)
41{
42 QString label = label_;
43
44 int p = 0;
45 bool accmarkRemoved = false;
46 while (true) {
47 p = label.indexOf(c: QLatin1Char('&'), from: p);
48 if (p < 0 || p + 1 == label.length()) {
49 break;
50 }
51
52 const QStringView labelView(label);
53 const QChar marker = label.at(i: p + 1);
54 if (marker.isLetterOrNumber()) {
55 // Valid accelerator.
56 label = labelView.left(n: p) + labelView.mid(pos: p + 1);
57
58 // May have been an accelerator in CJK-style "(&X)"
59 // at the start or end of text.
60 label = removeReducedCJKAccMark(label, pos: p);
61
62 accmarkRemoved = true;
63 } else if (marker == QLatin1Char('&')) {
64 // Escaped accelerator marker.
65 label = labelView.left(n: p) + labelView.mid(pos: p + 1);
66 }
67
68 ++p;
69 }
70
71 // If no marker was removed, and there are CJK characters in the label,
72 // also try to remove reduced CJK marker -- something may have removed
73 // ampersand beforehand.
74 if (!accmarkRemoved) {
75 bool hasCJK = false;
76 for (const QChar c : std::as_const(t&: label)) {
77 if (c.unicode() >= 0x2e00) { // rough, but should be sufficient
78 hasCJK = true;
79 break;
80 }
81 }
82 if (hasCJK) {
83 p = 0;
84 while (true) {
85 p = label.indexOf(c: QLatin1Char('('), from: p);
86 if (p < 0) {
87 break;
88 }
89 label = removeReducedCJKAccMark(label, pos: p + 1);
90 ++p;
91 }
92 }
93 }
94
95 return label;
96}
97

source code of ki18n/src/i18n/common_helpers.cpp