Cutelee  6.1.0
i18ncp.cpp
1 /*
2  This file is part of the Cutelee template system.
3 
4  Copyright (c) 2010 Stephen Kelly <steveire@gmail.com>
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Lesser General Public
8  License as published by the Free Software Foundation; either version
9  2 of the Licence, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Library General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public
17  License along with this library. If not, see <http://www.gnu.org/licenses/>.
18 
19 */
20 
21 #include "i18ncp.h"
22 
23 #include <QtCore/QStringList>
24 
25 #include "abstractlocalizer.h"
26 #include "engine.h"
27 #include "exception.h"
28 #include "parser.h"
29 #include "template.h"
30 
31 #include <QtCore/QDebug>
32 #include <complex>
33 #include <util.h>
34 
35 I18ncpNodeFactory::I18ncpNodeFactory() {}
36 
37 Node *I18ncpNodeFactory::getNode(const QString &tagContent, Parser *p) const
38 {
39  auto expr = smartSplit(tagContent);
40 
41  if (expr.size() < 4)
42  throw Cutelee::Exception(
43  TagSyntaxError,
44  QStringLiteral("Error: i18ncp tag takes at least three arguments"));
45 
46  auto contextText = expr.at(1);
47 
48  if (!(contextText.startsWith(QLatin1Char('"'))
49  && contextText.endsWith(QLatin1Char('"')))
50  && !(contextText.startsWith(QLatin1Char('\''))
51  && contextText.endsWith(QLatin1Char('\'')))) {
52  throw Cutelee::Exception(
53  TagSyntaxError,
54  QStringLiteral(
55  "Error: i18ncp tag first argument must be a static string."));
56  }
57  contextText = contextText.mid(1, contextText.size() - 2);
58 
59  auto sourceText = expr.at(2);
60 
61  if (!(sourceText.startsWith(QLatin1Char('"'))
62  && sourceText.endsWith(QLatin1Char('"')))
63  && !(sourceText.startsWith(QLatin1Char('\''))
64  && sourceText.endsWith(QLatin1Char('\'')))) {
65  throw Cutelee::Exception(
66  TagSyntaxError,
67  QStringLiteral(
68  "Error: i18ncp tag second argument must be a static string."));
69  }
70  sourceText = sourceText.mid(1, sourceText.size() - 2);
71 
72  auto pluralText = expr.at(3);
73 
74  auto argsStart = 4;
75  if (!(pluralText.startsWith(QLatin1Char('"'))
76  && pluralText.endsWith(QLatin1Char('"')))
77  && !(pluralText.startsWith(QLatin1Char('\''))
78  && pluralText.endsWith(QLatin1Char('\'')))) {
79  argsStart = 3;
80  pluralText = sourceText;
81  } else {
82  pluralText = pluralText.mid(1, pluralText.size() - 2);
83  }
84 
85  QList<FilterExpression> feList;
86  for (auto i = argsStart; i < expr.size(); ++i) {
87  feList.append(FilterExpression(expr.at(i), p));
88  }
89 
90  return new I18ncpNode(contextText, sourceText, pluralText, feList);
91 }
92 
93 I18ncpVarNodeFactory::I18ncpVarNodeFactory() {}
94 
96  Parser *p) const
97 {
98  auto expr = smartSplit(tagContent);
99 
100  if (expr.size() < 6) {
101  throw Cutelee::Exception(
102  TagSyntaxError,
103  QStringLiteral("Error: i18ncp_var tag takes at least five arguments"));
104  }
105 
106  auto contextText = expr.at(1);
107 
108  if (!(contextText.startsWith(QLatin1Char('"'))
109  && contextText.endsWith(QLatin1Char('"')))
110  && !(contextText.startsWith(QLatin1Char('\''))
111  && contextText.endsWith(QLatin1Char('\'')))) {
112  throw Cutelee::Exception(
113  TagSyntaxError,
114  QStringLiteral(
115  "Error: i18ncp_var tag first argument must be a static string."));
116  }
117  contextText = contextText.mid(1, contextText.size() - 2);
118 
119  auto sourceText = expr.at(2);
120 
121  if (!(sourceText.startsWith(QLatin1Char('"'))
122  && sourceText.endsWith(QLatin1Char('"')))
123  && !(sourceText.startsWith(QLatin1Char('\''))
124  && sourceText.endsWith(QLatin1Char('\'')))) {
125  throw Cutelee::Exception(
126  TagSyntaxError,
127  QStringLiteral(
128  "Error: i18ncp_var tag second argument must be a static string."));
129  }
130  sourceText = sourceText.mid(1, sourceText.size() - 2);
131 
132  auto pluralText = expr.at(3);
133 
134  auto argsStart = 4;
135  if (!(pluralText.startsWith(QLatin1Char('"'))
136  && pluralText.endsWith(QLatin1Char('"')))
137  && !(pluralText.startsWith(QLatin1Char('\''))
138  && pluralText.endsWith(QLatin1Char('\'')))) {
139  argsStart = 3;
140  pluralText = sourceText;
141  } else {
142  pluralText = pluralText.mid(1, pluralText.size() - 2);
143  }
144 
145  QList<FilterExpression> feList;
146  for (auto i = argsStart; i < expr.size() - 2; ++i) {
147  feList.append(FilterExpression(expr.at(i), p));
148  }
149 
150  auto resultName = expr.last();
151 
152  return new I18ncpVarNode(contextText, sourceText, pluralText, feList,
153  resultName);
154 }
155 
156 I18ncpNode::I18ncpNode(const QString &contextText, const QString &sourceText,
157  const QString &pluralText,
158  const QList<Cutelee::FilterExpression> &feList,
159  QObject *parent)
160  : Node(parent), m_contextText(contextText), m_sourceText(sourceText),
161  m_pluralText(pluralText), m_filterExpressionList(feList)
162 {
163 }
164 
165 void I18ncpNode::render(OutputStream *stream, Context *c) const
166 {
167  QVariantList args;
168  Q_FOREACH (const FilterExpression &fe, m_filterExpressionList)
169  args.append(fe.resolve(c));
170  auto resultString = c->localizer()->localizePluralContextString(
171  m_sourceText, m_pluralText, m_contextText, args);
172 
173  streamValueInContext(stream, resultString, c);
174 }
175 
176 I18ncpVarNode::I18ncpVarNode(const QString &contextText,
177  const QString &sourceText,
178  const QString &pluralText,
179  const QList<Cutelee::FilterExpression> &feList,
180  const QString &resultName, QObject *parent)
181  : Node(parent), m_contextText(contextText), m_sourceText(sourceText),
182  m_pluralText(pluralText), m_filterExpressionList(feList),
183  m_resultName(resultName)
184 {
185 }
186 
188 {
189  Q_UNUSED(stream)
190  QVariantList args;
191  Q_FOREACH (const FilterExpression &fe, m_filterExpressionList)
192  args.append(fe.resolve(c));
193  auto resultString = c->localizer()->localizePluralContextString(
194  m_sourceText, m_pluralText, m_contextText, args);
195 
196  c->insert(m_resultName, resultString);
197 }
Q_INVOKABLE QStringList smartSplit(const QString &str) const
Definition: node.cpp:202
The Context class holds the context to render a Template with.
Definition: context.h:119
std::shared_ptr< AbstractLocalizer > localizer() const
Definition: context.cpp:230
void insert(const QString &name, QObject *object)
Definition: context.cpp:145
An exception for use when implementing template tags.
Definition: exception.h:85
A FilterExpression object represents a filter expression in a template.
QVariant resolve(OutputStream *stream, Context *c) const
Base class for all nodes.
Definition: node.h:78
void streamValueInContext(OutputStream *stream, const QVariant &input, Cutelee::Context *c) const
Definition: node.cpp:88
The OutputStream class is used to render templates to a QTextStream.
Definition: outputstream.h:81
The Parser class processes a string template into a tree of nodes.
Definition: parser.h:49
Node * getNode(const QString &tagContent, Parser *p) const override
Definition: i18ncp.cpp:37
void render(OutputStream *stream, Context *c) const override
Definition: i18ncp.cpp:165
Node * getNode(const QString &tagContent, Parser *p) const override
Definition: i18ncp.cpp:95
void render(OutputStream *stream, Context *c) const override
Definition: i18ncp.cpp:187
Utility functions used throughout Cutelee.