1 /**
2  * Copyright (c) 2017, Timothy Stack
3  *
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * * Redistributions of source code must retain the above copyright notice, this
10  * list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  * * Neither the name of Timothy Stack nor the names of its contributors
15  * may be used to endorse or promote products derived from this software
16  * without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  *
29  * @file highlighter.hh
30  */
31 
32 #ifndef highlighter_hh
33 #define highlighter_hh
34 
35 #include <set>
36 
37 #include "optional.hpp"
38 #include "pcrepp/pcrepp.hh"
39 #include "text_format.hh"
40 #include "view_curses.hh"
41 
42 struct highlighter {
highlighterhighlighter43     highlighter()
44         : h_code(nullptr),
45           h_code_extra(nullptr) { };
46 
highlighterhighlighter47     explicit highlighter(pcre *code)
48         : h_code(code)
49     {
50         pcre_refcount(this->h_code, 1);
51         this->study();
52     };
53 
54     highlighter(const highlighter &other);
55 
56     highlighter &operator=(const highlighter &other);
57 
~highlighterhighlighter58     virtual ~highlighter() {
59         if (this->h_code != nullptr && pcre_refcount(this->h_code, -1) == 0) {
60             free(this->h_code);
61             this->h_code = nullptr;
62         }
63         free(this->h_code_extra);
64     };
65 
66     void study();
67 
with_patternhighlighter68     highlighter &with_pattern(const std::string &pattern) {
69         this->h_pattern = pattern;
70 
71         return *this;
72     }
73 
with_rolehighlighter74     highlighter &with_role(view_colors::role_t role) {
75         this->h_role = role;
76 
77         return *this;
78     };
79 
with_attrshighlighter80     highlighter &with_attrs(int attrs) {
81         this->h_attrs = attrs;
82 
83         return *this;
84     };
85 
with_text_formathighlighter86     highlighter &with_text_format(text_format_t tf) {
87         this->h_text_formats.insert(tf);
88 
89         return *this;
90     }
91 
with_format_namehighlighter92     highlighter &with_format_name(intern_string_t name) {
93         this->h_format_name = name;
94 
95         return *this;
96     };
97 
with_colorhighlighter98     highlighter &with_color(const styling::color_unit &fg, const styling::color_unit &bg) {
99         this->h_fg = fg;
100         this->h_bg = bg;
101 
102         return *this;
103     };
104 
with_nestablehighlighter105     highlighter &with_nestable(bool val) {
106         this->h_nestable = val;
107         return *this;
108     }
109 
get_attrshighlighter110     int get_attrs() const
111     {
112         ensure(this->h_attrs != -1);
113 
114         return this->h_attrs;
115     };
116 
117     void annotate(attr_line_t &al, int start) const;
118 
119     std::string h_pattern;
120     view_colors::role_t h_role{view_colors::VCR_NONE};
121     styling::color_unit h_fg{styling::color_unit::make_empty()};
122     styling::color_unit h_bg{styling::color_unit::make_empty()};
123     pcre *h_code;
124     pcre_extra *h_code_extra;
125     int h_attrs{-1};
126     std::set<text_format_t> h_text_formats;
127     intern_string_t h_format_name;
128     bool h_nestable{true};
129 };
130 
131 #endif
132