ALib C++ Library
Library Version: 2510 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
paragraphs.inl
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header-file is part of module \alib_format of the \aliblong.
4///
5/// \emoji :copyright: 2013-2025 A-Worx GmbH, Germany.
6/// Published under \ref mainpage_license "Boost Software License".
7//==================================================================================================
8ALIB_EXPORT namespace alib {
9namespace format {
10//==================================================================================================
11/// This class is used to format textual output, like console output.
12///
13/// One central \b static method is #Format, which formats a "paragraph" that starts at a
14/// certain index of the managed \b %AString buffer and reaches to its end.
15///
16/// When an instance of the class is created, the members of the class provide the text
17/// buffer as well as the other parameters which are needed for the static method. With methods
18/// #Add, member #Formatter is used to append the given parameters and then the new paragraph is
19/// formatted using the static method #Format.<br>
20/// This way, a longer text might be built by repetitive calls.
21//==================================================================================================
23{
24 // #############################################################################################
25 // Fields
26 // #############################################################################################
27 protected:
28 /// Allocator used for internal container types.
30
31 /// Internal buffer, used for field #Paragraphs, if no external string object was given.
33
34 public:
35 /// A reference to the text buffer. Either refers to otherwise protected field #text or to
36 /// what was given in alternative construction.
38
39 /// The formatter to use.
40 /// In the constructor, this shared pointer is initialized with the
41 /// - \alib{format;Formatter::Default;ALib Default Formatter},
42 /// in the case that this object's template character type equals \ref alib::character, or
43 /// - A shared pointer to a newly created formatter object of a corresponding character type
44 /// otherwise.
46
47 /// Used as parameter \p{lineWidth} of static method invocations.
49
50 /// Used as parameter \p{justifyChar} of static method invocations.
51 /// Usually set to <c>' '</c> to enable paragraph width justification.<br>
52 /// Defaults to <c>'\\0'</c> which disables it.
54
55 /// Used to detect special commands given with format strings.
56 /// \see Method #AddMarked for more information.
57 ///
58 /// Defaults to <c>'@'</c>.
60
61 /// The bullet used with increasing bullet depths.
62 /// Defaults to <c>'*'</c>, <c>'-'</c>, <c>'*'</c>, <c>'-'</c>, <c>'*'</c>, <c>'-'</c>.
64
65 /// Used as parameter \p{indent} of static method invocations.<br>
66 /// The indent string of the first line.
67 ///
68 /// This field can either be manipulated by direct access or preferably with
69 /// overloaded methods #PushIndent and #PopIndent.
71
72 /// Used as parameter \p{indent} of static method invocations.<br>
73 /// The indent string of text lines, excluding the first line.
74 ///
75 /// This field can either be manipulated by direct access or preferably with
76 /// overloaded methods #PushIndent and #PopIndent.
78
79 /// The stack of indent substring sizes in string #IndentFirstLine.
80 /// Used with #PushIndent and #PopIndent.
81 std::stack<integer, StdDequeMono<integer>> IndentSizesFirstLine;
82
83 /// The stack of indent substring sizes in string #IndentOtherLines.
84 /// Used with #PushIndent and #PopIndent.
85 std::stack<integer, StdDequeMono<integer>> IndentSizesOtherLines;
86
87 /// This field is increased whenever a line of text added is longer than its current
88 /// value.
89 /// Might be used by to detect the maximum line width when field #LineWidth is set to \c 0
90 /// and hence no auto wrap is done.
92
93
94 protected:
95 /// Internally reused list of boxes.
97
98 /// Buffer for processing marked text.
100
101 /// Buffer for processing marked text.
103
104 // #############################################################################################
105 // Constructor/Destructor
106 // #############################################################################################
107 public:
108 /// Parameterless constructor.
109 /// Internal buffer #text will be used with reference #Buffer.
110 /// For field #Formatter, \alib{format;Formatter::Default} will be used.
112
113 /// Alternative constructor that accepts an external buffer to use.
114 /// @param externalBuffer The external buffer to use and fill.
115 ALIB_DLL Paragraphs( AString& externalBuffer );
116
117 // #############################################################################################
118 // Interface
119 // #############################################################################################
120 public:
121 //==============================================================================================
122 /// Formats one or more paragraphs (separated by \b NewLine symbols) with three optional
123 /// features:
124 ///
125 /// - Wrapping of lines longer than lineWidth (word wrap)
126 /// - Justify the text, which here means "full justification", i.e., format the text to have
127 /// lines of the exact same width.
128 /// - Adding an indentation to each line with an optionally different indentation for the
129 /// first line after a \b NewLine symbol and subsequent ones.
130 ///
131 /// The paragraph starts at \p{startIdx} and all of the rest of the string is treated
132 /// as one paragraph. New-line character sequences found within the paragraph are considered
133 /// manual line ends. Hence, no block formatting for lines ending with a new line character
134 /// is performed.
135 ///
136 /// The method is static and hence can be used with arbitrary buffers.
137 /// Non-static methods #Add invoke this method after adding the given content
138 /// to the internal buffer. Furthermore, convenience functions and corresponding member
139 /// variables, simplify the use of this method, when indirectly used through an instance of
140 /// the class.
141 ///
142 /// @param text The text containing the paragraph to format.
143 /// @param startIdx The start of the paragraph.
144 /// @param lineWidth The width of the line. If \c 0 or negative, no line wrap is
145 /// performed.
146 /// @param justifyChar If this is unequal to <c>'\0'</c> it denotes the fill
147 /// character used to justify the paragraph.
148 /// Defaults to <c>'\0'</c>, which disables justification.
149 /// @param[out] maxLineWidth Provides the maximum width of all text lines written.
150 /// @param indentFirstLine The indent string of the first line. Defaults to \c nullptr.
151 /// @param indentOtherLines The indent string of subsequent lines. Defaults to \c nullptr.
152 //==============================================================================================
154 static
155 void Format( AString& text,
156 integer startIdx,
157 integer lineWidth,
158 character justifyChar,
159 integer& maxLineWidth,
160 const String& indentFirstLine = nullptr,
161 const String& indentOtherLines= nullptr );
162
163 //==============================================================================================
164 /// Appends the given objects \p{args} to the internal #Buffer with the help of member
165 /// #Formatter. Then, static method #Format is invoked, providing our public
166 /// members as parameters. Finally, a newline sequence is added to #Buffer, but only if the
167 /// buffer is not empty and if it does not already end with a newline sequence.
168 ///
169 /// @throws <b>alib::format::FMTExceptions</b><br>
170 /// Rethrows exceptions from the formatter caused by errors in provided \p{args}.
171 ///
172 /// @param args The list of arguments to add.
173 //==============================================================================================
174 template<typename TAllocatorArgs>
176
177 //==============================================================================================
178 /// Variadic template argument version of #Add.
179 ///
180 /// @param args The variadic list of arguments to add.
181 /// @return A reference to ourselves to allow concatenated calls.
182 //==============================================================================================
183 template <typename... BoxedObjects>
184 Paragraphs& Add( const BoxedObjects&... args )
185 {
186 boxes.clear();
187 boxes.Add( args... );
188 Add( boxes );
189 return *this;
190 }
191
192 //==============================================================================================
193 /// This method implements a pre-processing of the text before #Add paragraphs found in
194 /// the text.
195 ///
196 /// The pre-processing is quite simple. Its purpose is to allow longer strings (e.g., loaded
197 /// from a resource pool) with multiple paragraphs to be formatted by embedded escape
198 /// sequences to include indents and nested bullet schemes.
199 ///
200 /// The escape sequences begin with the character stored in field #MarkerChar, which defaults
201 /// to <c>'@'</c>. The following table documents the sequences:
202 ///
203 /// Sequence | Description
204 /// ---------|------------------------------------------------------------------------
205 /// \@@ | Inserts the marker character itself.
206 /// \@>> | Indent text by two spaces
207 /// \@<< | Un-indent text by two spaces
208 /// \@*> | Increases bullet level.
209 /// \@<* | Decreases bullet level
210 /// \@P | Inserts a new line (like '\n') but without ending the current and starting a new bullet point.
211 /// \@HLc | Inserts a horizontal line of width #LineWidth using \p{c} as fill character.
212 ///
213 /// The nested bullet point characters are received from vector #MarkerBullets.
214 ///
215 /// @throws <b>alib::format::FMTExceptions</b>
216 /// - \alib{format::FMTExceptions;UnknownMarker}
217 /// - \alib{format::FMTExceptions;EndmarkerWithoutStart}
218 /// - Rethrows formatter exceptions occurring due to errors in provided \p{args}.
219 ///
220 /// @param args The list of arguments to add.
221 //==============================================================================================
222 template<typename TAllocatorArgs>
224
225 //==============================================================================================
226 /// Variadic template argument version of #AddMarked.
227 ///
228 /// @throws <b>alib::format::FMTExceptions</b>
229 /// - \alib{format::FMTExceptions;UnknownMarker}
230 /// - \alib{format::FMTExceptions;EndmarkerWithoutStart}
231 ///
232 /// @param args The variadic list of arguments to add.
233 /// @return A reference to ourselves to allow concatenated calls.
234 //==============================================================================================
235 template <typename... BoxedObjects>
236 Paragraphs& AddMarked( const BoxedObjects&... args )
237 {
238 boxes.clear();
239 boxes.Add( args... );
240 AddMarked( boxes );
241 return *this;
242 }
243
244 //==============================================================================================
245 /// Removes the last new line character at the end of the #Buffer.
246 ///
247 /// @return A reference to the text object.
248 //==============================================================================================
250 {
251 if( Buffer.EndsWith( NEW_LINE ) )
252 Buffer.template DeleteEnd<NC>( NEW_LINE.Length() );
253 return Buffer;
254 }
255
256 //==============================================================================================
257 /// Clears field #Buffer.
258 ///
259 /// @return A reference to ourselves to allow concatenated calls.
260 //==============================================================================================
262 Paragraphs& Clear();
263
264
265 //==============================================================================================
266 /// Add a given number of characters (default is spaces) to the indentation strings
267 /// #IndentFirstLine and #IndentOtherLines.
268 ///
269 /// Use #PopIndent to remove the indent.
270 ///
271 /// @param qty The quantity of characters to add or remove
272 /// @param fillChar The character (used only if \p{qty} is positive).
273 /// @return A reference to ourselves to allow concatenated calls.
274 //==============================================================================================
276 Paragraphs& PushIndent( uinteger qty, character fillChar = ' ' );
277
278 //==============================================================================================
279 /// Add the given strings to members #IndentFirstLine and #IndentOtherLines.
280 ///
281 /// @param indentFirstLine The string to add to the current indentation stored in
282 /// #IndentFirstLine.
283 /// @param indentOtherLines The string to add to the current indentation stored in
284 /// #IndentOtherLines.<br>
285 /// Defaults to \b NULL_STRING, which sets it to the same value as
286 /// \p{indentFirstLine}.
287 /// @return A reference to ourselves to allow concatenated calls.
288 //==============================================================================================
290 Paragraphs& PushIndent( const String& indentFirstLine,
291 const String& indentOtherLines=nullptr);
292
293 //==============================================================================================
294 /// Removes the most recently added indent.
295 /// @return A reference to ourselves to allow concatenated calls.
296 //==============================================================================================
299}; // class Paragraphs
300
301#if !DOXYGEN
308#endif // !DOXYGEN
309
310} // namespace alib[::format]
311
312/// Type alias in namespace \b alib.
314
315} // namespace [alib]
316
317
std::stack< integer, StdDequeMono< integer > > IndentSizesFirstLine
AString markedBuffer
Buffer for processing marked text.
StdVectorMono< character > MarkerBullets
ALIB_DLL Paragraphs & PushIndent(uinteger qty, character fillChar=' ')
size_t markerBulletLevel
Buffer for processing marked text.
Paragraphs & AddMarked(const BoxedObjects &... args)
void Add(boxing::TBoxes< TAllocatorArgs > &args)
void AddMarked(boxing::TBoxes< TAllocatorArgs > &args)
std::stack< integer, StdDequeMono< integer > > IndentSizesOtherLines
Paragraphs & Add(const BoxedObjects &... args)
static ALIB_DLL void Format(AString &text, integer startIdx, integer lineWidth, character justifyChar, integer &maxLineWidth, const String &indentFirstLine=nullptr, const String &indentOtherLines=nullptr)
MonoAllocator allocator
Allocator used for internal container types.
integer LineWidth
Used as parameter lineWidth of static method invocations.
BoxesMA boxes
Internally reused list of boxes.
AString text
Internal buffer, used for field Paragraphs, if no external string object was given.
ALIB_DLL Paragraphs & Clear()
ALIB_DLL Paragraphs & PopIndent()
#define ALIB_DLL
Definition alib.inl:496
#define ALIB_EXPORT
Definition alib.inl:488
strings::TAString< character, lang::HeapAllocator > AString
Type alias in namespace alib.
std::vector< T, SCAMono< T > > StdVectorMono
Type alias in namespace alib.
constexpr CString NEW_LINE
A zero-terminated string containing the new-line character sequence.
Definition cstring.inl:644
lang::integer integer
Type alias in namespace alib.
Definition integers.inl:149
monomem::TMonoAllocator< lang::HeapAllocator > MonoAllocator
format::Paragraphs Paragraphs
Type alias in namespace alib.
boxing::TBoxes< MonoAllocator > BoxesMA
Type alias in namespace alib.
Definition boxes.inl:245
strings::TAString< character, MonoAllocator > AStringMA
Type alias in namespace alib.
containers::SharedPtr< format::Formatter > SPFormatter
Definition formatter.inl:42
strings::TString< character > String
Type alias in namespace alib.
Definition string.inl:2381
characters::character character
Type alias in namespace alib.
lang::uinteger uinteger
Type alias in namespace alib.
Definition integers.inl:152