1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#include "openedlist.h"
5
6#include "atom.h"
7
8#include <QtCore/qregularexpression.h>
9
10QT_BEGIN_NAMESPACE
11
12static const char roman[] = "m\2d\5c\2l\5x\2v\5i";
13
14OpenedList::OpenedList(ListStyle style) : sty(style), ini(1), nex(0) {}
15
16OpenedList::OpenedList(const Location &location, const QString &hint) : sty(Bullet), ini(1)
17{
18 static const QRegularExpression hintSyntax("^(\\W*)([0-9]+|[A-Z]+|[a-z]+)(\\W*)$");
19
20 auto match = hintSyntax.match(subject: hint);
21 if (match.hasMatch()) {
22 bool ok;
23 int asNumeric = hint.toInt(ok: &ok);
24 int asRoman = fromRoman(str: match.captured(nth: 2));
25 int asAlpha = fromAlpha(str: match.captured(nth: 2));
26
27 if (ok) {
28 sty = Numeric;
29 ini = asNumeric;
30 } else if (asRoman > 0 && asRoman != 100 && asRoman != 500) {
31 sty = (hint == hint.toLower()) ? LowerRoman : UpperRoman;
32 ini = asRoman;
33 } else {
34 sty = (hint == hint.toLower()) ? LowerAlpha : UpperAlpha;
35 ini = asAlpha;
36 }
37 pref = match.captured(nth: 1);
38 suff = match.captured(nth: 3);
39 } else if (!hint.isEmpty()) {
40 location.warning(QStringLiteral("Unrecognized list style '%1'").arg(a: hint));
41 }
42 nex = ini - 1;
43}
44
45QString OpenedList::styleString() const
46{
47 switch (style()) {
48 case Bullet:
49 default:
50 return ATOM_LIST_BULLET;
51 case Tag:
52 return ATOM_LIST_TAG;
53 case Value:
54 return ATOM_LIST_VALUE;
55 case Numeric:
56 return ATOM_LIST_NUMERIC;
57 case UpperAlpha:
58 return ATOM_LIST_UPPERALPHA;
59 case LowerAlpha:
60 return ATOM_LIST_LOWERALPHA;
61 case UpperRoman:
62 return ATOM_LIST_UPPERROMAN;
63 case LowerRoman:
64 return ATOM_LIST_LOWERROMAN;
65 }
66}
67
68QString OpenedList::numberString() const
69{
70 return QString::number(number());
71 /*
72 switch ( style() ) {
73 case Numeric:
74 return QString::number( number() );
75 case UpperAlpha:
76 return toAlpha( number() ).toUpper();
77 case LowerAlpha:
78 return toAlpha( number() );
79 case UpperRoman:
80 return toRoman( number() ).toUpper();
81 case LowerRoman:
82 return toRoman( number() );
83 case Bullet:
84 default:
85 return "*";
86 }*/
87}
88
89int OpenedList::fromAlpha(const QString &str)
90{
91 int n = 0;
92 int u;
93
94 for (const QChar &character : str) {
95 u = character.toLower().unicode();
96 if (u >= 'a' && u <= 'z') {
97 n *= 26;
98 n += u - 'a' + 1;
99 } else {
100 return 0;
101 }
102 }
103 return n;
104}
105
106QString OpenedList::toRoman(int n)
107{
108 /*
109 See p. 30 of Donald E. Knuth's "TeX: The Program".
110 */
111 QString str;
112 int j = 0;
113 int k;
114 int u;
115 int v = 1000;
116
117 for (;;) {
118 while (n >= v) {
119 str += roman[j];
120 n -= v;
121 }
122
123 if (n <= 0)
124 break;
125
126 k = j + 2;
127 u = v / roman[k - 1];
128 if (roman[k - 1] == 2) {
129 k += 2;
130 u /= 5;
131 }
132 if (n + u >= v) {
133 str += roman[k];
134 n += u;
135 } else {
136 j += 2;
137 v /= roman[j - 1];
138 }
139 }
140 return str;
141}
142
143int OpenedList::fromRoman(const QString &str)
144{
145 int n = 0;
146 int j;
147 int u;
148 int v = 0;
149
150 for (const QChar &character : str) {
151 j = 0;
152 u = 1000;
153 while (roman[j] != 'i' && roman[j] != character.toLower()) {
154 j += 2;
155 u /= roman[j - 1];
156 }
157 if (u < v) {
158 n -= u;
159 } else {
160 n += u;
161 }
162 v = u;
163 }
164
165 if (str.toLower() == toRoman(n)) {
166 return n;
167 } else {
168 return 0;
169 }
170}
171
172QT_END_NAMESPACE
173

source code of qttools/src/qdoc/qdoc/openedlist.cpp