list = entry.getValue();
66 | if (!map_single)
67 | {
68 | m_printer.println(filename);
69 | m_printer.println();
70 | }
71 | if (list.isEmpty())
72 | {
73 | if (!map_single)
74 | {
75 | m_printer.print("* ");
76 | }
77 | m_printer.println("Everything is OK!");
78 | }
79 | else
80 | {
81 | for (Advice ad : list)
82 | {
83 | PositionRange pr = ad.getPositionRange();
84 | m_printer.setForegroundColor(Color.YELLOW);
85 | m_printer.print("* " + pr);
86 | m_printer.resetColors();
87 | m_printer.print(" ");
88 | wrap(ad.getMessage() + " [" + ad.getRule().getName() + "]", " ", pr.toString().length() + 2);
89 | m_printer.println();
90 | m_printer.setForegroundColor(Color.WHITE);
91 | renderExcerpt(ad, ad.getLine(), ad.getRange());
92 | }
93 | }
94 | }
95 | }
96 |
97 | /**
98 | * Renders a line of text and "highlights" a portion of it. The highlight
99 | * here is simulated with a series of "^" characters, like this:
100 | *
101 | * the quick brown fox jumps over the lazy dog
102 | * ^^^^^^^^^^^^^^^
103 | *
104 | * @param ad Advice to render
105 | * @param l The line of text
106 | * @param range The range to highlight
107 | */
108 | protected void renderExcerpt(/*@ non_null @*/ Advice ad, /*@ non_null @*/ Line l, /*@ non_null @*/ Range range)
109 | {
110 | String line = l.toString();
111 | int indent = 2;
112 | int left = ad.getReferenceString().getOriginalPosition(range.getStart()).getColumn();
113 | int right = ad.getReferenceString().getOriginalPosition(range.getEnd()).getColumn();
114 | int range_width = right - left;
115 | int mid_point = left + range_width / 2;
116 | int offset = 0;
117 | if (range_width < line.length())
118 | {
119 | if (mid_point + m_lineWidth / 2 >= line.length())
120 | {
121 | int char_dif = (mid_point + m_lineWidth / 2) - line.length();
122 | offset = Math.max(0, (mid_point - m_lineWidth / 2) - char_dif);
123 | }
124 | else
125 | {
126 | offset = Math.max(0, mid_point - m_lineWidth / 2);
127 | }
128 | }
129 | String line_to_display = line.substring(offset, Math.min(line.length(), offset + m_lineWidth));
130 | printSpaces(indent);
131 | m_printer.println(line_to_display);
132 | // Show squiggly line
133 | printSpaces(indent + Math.max(0, left - offset));
134 | m_printer.setForegroundColor(Color.LIGHT_RED);
135 | for (int i = 0; i < range_width + 1; i++)
136 | {
137 | m_printer.append("^");
138 | }
139 | m_printer.resetColors();
140 | m_printer.println();
141 | }
142 |
143 | /**
144 | * Prints some spaces
145 | * @param n The number of spaces to print
146 | */
147 | protected void printSpaces(int n)
148 | {
149 | for (int i = 0; i < n; i++)
150 | {
151 | m_printer.print(" ");
152 | }
153 | }
154 |
155 | /**
156 | * Prints a sequence of words, using word wrapping and indenting each
157 | * new line
158 | * @param message The sequence of words to print
159 | * @param indent The indent (a sequence of spaces) to append at the
160 | * beginning of each new line
161 | * @param start_pos The start position on the first line (set to greater
162 | * than 0 to append text to an existing line)
163 | */
164 | protected void wrap(/*@ non_null @*/ String message, /*@ non_null @*/ String indent, int start_pos)
165 | {
166 | int cur_width = start_pos;
167 | String[] words = message.split(" ");
168 | for (String word : words)
169 | {
170 | cur_width += word.length() + 1;
171 | if (cur_width > m_terminalLineWidth)
172 | {
173 | m_printer.println();
174 | m_printer.print(indent);
175 | cur_width = word.length() + 1;
176 | }
177 | if (word.startsWith("[") && word.endsWith("]"))
178 | {
179 | m_printer.setForegroundColor(Color.BROWN);
180 | m_printer.print(word + " ");
181 | m_printer.resetColors();
182 | }
183 | else
184 | {
185 | // Language Tool advice has this strange markup
186 | word = word.replaceAll("", "'");
187 | word = word.replaceAll("", "'");
188 | m_printer.print(word + " ");
189 | }
190 | }
191 | }
192 | }
--------------------------------------------------------------------------------
/Source/Core/src/ca/uqac/lif/textidote/render/SinglelineAdviceRenderer.java:
--------------------------------------------------------------------------------
1 | /*
2 | TeXtidote, a linter for LaTeX documents
3 | Copyright (C) 2018-2019 Sylvain Hallé
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 | package ca.uqac.lif.textidote.render;
19 |
20 | import java.util.List;
21 | import java.util.Map;
22 |
23 | import ca.uqac.lif.petitpoucet.function.strings.Range;
24 | import ca.uqac.lif.textidote.Advice;
25 | import ca.uqac.lif.textidote.AdviceRenderer;
26 | import ca.uqac.lif.textidote.as.AnnotatedString;
27 | import ca.uqac.lif.textidote.as.AnnotatedString.Line;
28 | import ca.uqac.lif.textidote.as.Position;
29 | import ca.uqac.lif.util.AnsiPrinter;
30 | import ca.uqac.lif.util.AnsiPrinter.Color;
31 |
32 | /**
33 | * Renders advice to a terminal (such as {@code stdin}), printing a single line
34 | * per advice, using colored output.
35 | *
36 | * @author toolcreator
37 | */
38 | public class SinglelineAdviceRenderer extends AdviceRenderer
39 | {
40 | /**
41 | * Creates a new advice renderer
42 | *
43 | * @param printer
44 | * The printer to which the advice will be printed
45 | */
46 | public SinglelineAdviceRenderer(AnsiPrinter printer)
47 | {
48 | super(printer);
49 | }
50 |
51 | @Override
52 | public void render()
53 | {
54 | for (Map.Entry> entry : m_advice.entrySet())
55 | {
56 | String filename = entry.getKey();
57 | List list = entry.getValue();
58 | if (!list.isEmpty())
59 | {
60 | for (Advice ad : list)
61 | {
62 | m_printer.setForegroundColor(Color.YELLOW);
63 | m_printer.print(filename + "(" + ad.getPositionRange() + ")");
64 | m_printer.resetColors();
65 | m_printer.print(": ");
66 | m_printer.print(
67 | ad.getMessage().replaceAll("", "").replaceAll("= line.length())
98 | {
99 | m_printer.print(line.substring(start.getColumn(), line.length()));
100 | }
101 | else
102 | {
103 | m_printer.print(line.substring(start.getColumn(), end.getColumn() + 1));
104 | m_printer.setForegroundColor(Color.WHITE);
105 | m_printer.print(line.substring(end.getColumn() + 1, line.length()));
106 | }
107 | }
108 | else
109 | {
110 | m_printer.print(line);
111 | }
112 | m_printer.resetColors();
113 | m_printer.print("\"");
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/Source/Core/src/ca/uqac/lif/textidote/render/postamble.html:
--------------------------------------------------------------------------------
1 |
2 | Output produced by TeXtidote v0.9 beta, © 2018-2023 Sylvain Hallé - All rights reserved.
3 | See the TeXtidote website for more information.
4 |