summaryrefslogtreecommitdiffstats
path: root/src/ui/syntax.h
blob: 528ad93281ee41e287ce16279d4af3bd95f7dfba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// SPDX-License-Identifier: GPL-2.0-or-later
/** @file Syntax coloring via Gtksourceview and Pango markup.
 */
/* Authors:
 *   Rafael Siejakowski <rs@rs-math.net>
 *
 * Copyright (C) 2022 Authors
 *
 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
 */

#ifndef SEEN_UI_UI_SYNTAX_H
#define SEEN_UI_UI_SYNTAX_H

#include <memory>
#include <optional>
#include <vector>
#include <gtkmm/textview.h>
#include <glibmm.h>
#include <glibmm/ustring.h>

#include "color.h"

namespace Inkscape::UI::Syntax {

/** The style of a single element in a (Pango markup)-enabled widget. */
struct Style
{
    std::optional<Glib::ustring> color;
    std::optional<Glib::ustring> background;
    uint8_t bold      : 1;
    uint8_t italic    : 1;
    uint8_t underline : 1;

    Style()
        : bold{false}
        , italic{false}
        , underline{false}
    {}

    bool isDefault() const { return !color && !background && !bold && !italic && !underline; }
    Glib::ustring openingTag() const;
    Glib::ustring closingTag() const;
};

/** The styles used for simple XML syntax highlighting. */
struct XMLStyles
{
    Style prolog;
    Style comment;
    Style angular_brackets;
    Style tag_name;
    Style attribute_name;
    Style attribute_value;
    Style content;
    Style error;
};

/** @brief A formatter for XML syntax, based on Pango markup.
 *
 * This mechanism is used in the TreeView in the XML Dialog,
 * where the syntax highlighting of XML tags is accomplished
 * via Pango markup.
 */
class XMLFormatter
{
public:
    XMLFormatter() = default;
    XMLFormatter(XMLStyles &&styles)
        : _style{styles}
    {}

    void setStyle(XMLStyles const &new_style) { _style = new_style; }
    void setStyle(XMLStyles &&new_style) { _style = new_style; }

    void openTag(char const *tag_name);
    void addAttribute(char const *attribute_name, char const *attribute_value);
    Glib::ustring finishTag(bool self_close = false);

    Glib::ustring formatContent(char const* content, bool wrap_in_quotes = true) const;
    Glib::ustring formatComment(char const* comment, bool wrap_in_comment_marks = true) const;
    Glib::ustring formatProlog(char const* prolog) const { return _format(_style.prolog, prolog); }

private:
    Glib::ustring _format(Style const &style, Glib::ustring const &content) const;
    Glib::ustring _format(Style const &style, char const *content) const
    {
        return style.openingTag() + Glib::Markup::escape_text(content) + style.closingTag();
    }

    XMLStyles _style;
    Glib::ustring _wip;
};

/// Build XML styles from a GTKSourceView syntax color theme.
XMLStyles build_xml_styles(const Glib::ustring& syntax_theme);

/// Syntax highlighting mode (language).
enum class SyntaxMode
{
    PlainText,     ///< Plain text (no highlighting).
    InlineCss,     ///< Inline CSS (contents of a style="..." attribute).
    CssStyle,      ///< File-scope CSS (contents of a CSS file or a <style> tag).
    SvgPathData,   ///< Contents of the 'd' attribute of the SVG <path> element.
    SvgPolyPoints  ///< Contents of the 'points' attribute of <polyline> or <polygon>.
};

/// Base class for styled text editing widget.
class TextEditView
{
public:
    virtual ~TextEditView() = default;
    virtual void setStyle(const Glib::ustring& theme) = 0;
    virtual void setText(const Glib::ustring& text) = 0;
    virtual Glib::ustring getText() const = 0;
    virtual Gtk::TextView& getTextView() const = 0;

    static std::unique_ptr<TextEditView> create(SyntaxMode mode);
};

} // namespace Inkscape::UI::Syntax

#endif // SEEN_UI_UI_SYNTAX_H

/*
  Local Variables:
  mode:c++
  c-file-style:"stroustrup"
  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
  indent-tabs-mode:nil
  fill-column:99
  End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :