File indexing completed on 2024-05-12 04:37:48

0001 /*
0002     SPDX-FileCopyrightText: 2012 Miha Čančula <miha@noughmad.eu>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #ifndef KDEVPLATFORM_TEMPLATERENDERER_H
0008 #define KDEVPLATFORM_TEMPLATERENDERER_H
0009 
0010 #include <QVariantHash>
0011 
0012 #include <language/languageexport.h>
0013 
0014 class QUrl;
0015 
0016 namespace KDevelop {
0017 class SourceFileTemplate;
0018 
0019 class DocumentChangeSet;
0020 class TemplateRendererPrivate;
0021 
0022 /**
0023  * @brief Convenience class for rendering multiple templates with the same context
0024  *
0025  * The TemplateRenderer provides easy access to common template operations.
0026  * Internally, it encapsulates a Grantlee::Engine and a Grantlee::Context.
0027  *
0028  * It is used by adding a set of variables, and then rendering a template string
0029  * @code
0030  * TemplateRenderer renderer;
0031  * renderer.addVariable("greeting", "Hello");
0032  * renderer.addVariable("target", "World");
0033  * QString text = renderer.render("{{ greeting }}, {{ target }}!");
0034  * // text == "Hello, World!"
0035  * @endcode
0036  *
0037  * If you wish to include other templates using the Grantlee {% include %} tag,
0038  * make sure TemplateRenderer can find those template by using
0039  * addTemplateDirectories() and addArchive(). This adds everything in the specified
0040  * directories or archive files to the list of files search for inclusion.
0041  *
0042  * Directories named "kdevcodegen/templates" in the "data" resource type are always included in the search path,
0043  * there is no need to add them explicitly. Additionally, TemplateRenderer adds the "lib" resource directories
0044  * to the Grantlee plugin search path, so plugins installed there will be available to templates.
0045  *
0046  **/
0047 class KDEVPLATFORMLANGUAGE_EXPORT TemplateRenderer
0048 {
0049 public:
0050     /**
0051      * Policy for working with empty lines
0052      **/
0053     enum EmptyLinesPolicy
0054     {
0055         /**
0056          * Keep empty lines as they are in the rendered output.
0057          * The output from the template is returned unmodified.
0058          */
0059         KeepEmptyLines,
0060         /**
0061          * If the template output has more than one line, the renderer
0062          * performs a smart trim on the rendered output.
0063          * @li single empty lines are removed
0064          * @li two or more consecutive empty lines are compressed into a single empty line
0065          * @li a single empty line is kept at the end
0066          */
0067         TrimEmptyLines,
0068         /**
0069          * Removes all empty lines from the template output, and appends a newline at the end if needed.
0070          */
0071         RemoveEmptyLines
0072     };
0073 
0074     TemplateRenderer();
0075     virtual ~TemplateRenderer();
0076 
0077     /**
0078      * Adds @p variables to the Grantlee::Context passed to each template.
0079      *
0080      * If the context already contains a variables with the same name as a key in @p variables,
0081      * it is overwritten.
0082      *
0083      **/
0084     void addVariables(const QVariantHash& variables);
0085 
0086     /**
0087      * Adds variable with name @p name and value @p value to the Grantlee::Context passed to each template.
0088      *
0089      * If the context already contains a variables with the same @p name, it is overwritten.
0090      *
0091      **/
0092     void addVariable(const QString& name, const QVariant& value);
0093 
0094     /**
0095      * Returns the current variables defined for this renderer
0096      *
0097      * @sa addVariable(), addVariables()
0098      */
0099     QVariantHash variables() const;
0100 
0101     /**
0102      * @brief Renders a single template
0103      *
0104      * Any rendering errors are reported by errorString().
0105      * If there were no errors, errorString() will return an empty string.
0106      *
0107      * @param content the template content
0108      * @param name (optional) the name of this template
0109      * @return the rendered template
0110      **/
0111     QString render(const QString& content, const QString& name = QString());
0112 
0113     /**
0114      * @brief Renders a single template from a file
0115      *
0116      * Any rendering errors are reported by errorString().
0117      * If there were no errors, errorString() will return an empty string.
0118      *
0119      * @param url the URL of the file from which to load the template
0120      * @param name (optional) the name of this template
0121      * @return the rendered template
0122      **/
0123     QString renderFile(const QUrl& url, const QString& name = QString());
0124 
0125     /**
0126      * @brief Renders a list of templates
0127      *
0128      * This is a convenience method, suitable if you have to render a large number of templates
0129      * with the same context.
0130      *
0131      * @param contents the template contents
0132      * @return the rendered templates
0133      **/
0134     QStringList render(const QStringList& contents);
0135 
0136     /**
0137      * @brief Sets the policy for empty lines in the rendered output
0138      *
0139      * The default is KeepEmptyLines, where the template output is return unmodified.
0140      *
0141      * @param policy policy for empty lines in the rendered output
0142      * @sa EmptyLinesPolicy
0143      */
0144     void setEmptyLinesPolicy(EmptyLinesPolicy policy);
0145 
0146     /**
0147      * Returns the currently set policy for empty lines in the rendered output
0148      * @sa EmptyLinesPolicy, setEmptyLinesPolicy()
0149      */
0150     EmptyLinesPolicy emptyLinesPolicy() const;
0151 
0152     /**
0153      * @brief Renders all templates in the archive represented by @p fileTemplate
0154      *
0155      * Output files are saved to corresponding URLs in @p fileUrls
0156      *
0157      * For each output file, TemplateRenderer add two variables named @c output_file_x
0158      * and @c output_file_x_absolute, where @c x is replaced
0159      * with the file name specified in the template description file.
0160      * The variable name is entirely lowercase and cleaned by replacing
0161      * all non-alphanumerical characters with underscores.
0162      * For example, if the file is named "Public Header" in
0163      * the description file, the variable will be @c output_file_public_heder.
0164      *
0165      * As their name suggests, @c output_file_x contains the relative path from baseUrl() to the URL of the
0166      * x's output location, while @c output_file_x_absolute contains x's absolute output URL.
0167      * Both are available to templates as strings.
0168      *
0169      * @param fileTemplate the source file template to render
0170      * @param baseUrl the base URL used for calculating relative output file URLs
0171      * @param fileUrls maps output file identifiers to desired destination URLs
0172      * @return KDevelop::DocumentChangeSet
0173      */
0174     DocumentChangeSet renderFileTemplate(const KDevelop::SourceFileTemplate& fileTemplate,
0175                                          const QUrl& baseUrl, const QHash<QString, QUrl>& fileUrls);
0176 
0177     /**
0178      * Returns the error string from the last call to render(), renderFile() or renderFileTemplate().
0179      * If the last render was successful and produced no errors, this function returns an empty string.
0180      *
0181      * @return the last error string
0182      **/
0183     QString errorString() const;
0184 
0185 private:
0186     const QScopedPointer<class TemplateRendererPrivate> d_ptr;
0187     Q_DECLARE_PRIVATE(TemplateRenderer)
0188 };
0189 }
0190 
0191 #endif // KDEVPLATFORM_TEMPLATERENDERER_H