ALib C++ Library
Library Version: 2511 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, StdDequeMA<integer>> IndentSizesFirstLine;
82
83 /// The stack of indent substring sizes in string #IndentOtherLines.
84 /// Used with #PushIndent and #PopIndent.
85 std::stack<integer, StdDequeMA<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 /// Formats one or more paragraphs (separated by \b NewLine symbols) with three optional
122 /// features:
123 ///
124 /// - Wrapping of lines longer than lineWidth (word wrap)
125 /// - Justify the text, which here means "full justification", i.e., format the text to have
126 /// lines of the exact same width.
127 /// - Adding an indentation to each line with an optionally different indentation for the
128 /// first line after a \b NewLine symbol and subsequent ones.
129 ///
130 /// The paragraph starts at \p{startIdx} and all of the rest of the string is treated
131 /// as one paragraph. New-line character sequences found within the paragraph are considered
132 /// manual line ends. Hence, no block formatting for lines ending with a new line character
133 /// is performed.
134 ///
135 /// The method is static and hence can be used with arbitrary buffers.
136 /// Non-static methods #Add invoke this method after adding the given content
137 /// to the internal buffer. Furthermore, convenience functions and corresponding member
138 /// variables, simplify the use of this method, when indirectly used through an instance of
139 /// the class.
140 ///
141 /// @param text The text containing the paragraph to format.
142 /// @param startIdx The start of the paragraph.
143 /// @param lineWidth The width of the line. If \c 0 or negative, no line wrap is
144 /// performed.
145 /// @param justifyChar If this is unequal to <c>'\0'</c> it denotes the fill
146 /// character used to justify the paragraph.
147 /// Defaults to <c>'\0'</c>, which disables justification.
148 /// @param[out] maxLineWidth Provides the maximum width of all text lines written.
149 /// @param indentFirstLine The indent string of the first line. Defaults to \c nullptr.
150 /// @param indentOtherLines The indent string of subsequent lines. Defaults to \c nullptr.
152 static
153 void Format( AString& text,
154 integer startIdx,
155 integer lineWidth,
156 character justifyChar,
157 integer& maxLineWidth,
158 const String& indentFirstLine = nullptr,
159 const String& indentOtherLines= nullptr );
160
161 /// Appends the given objects \p{args} to the internal #Buffer with the help of member
162 /// #Formatter. Then, static method #Format is invoked, providing our public
163 /// members as parameters. Finally, a newline sequence is added to #Buffer, but only if the
164 /// buffer is not empty and if it does not already end with a newline sequence.
165 ///
166 /// @throws <b>alib::format::FMTExceptions</b><br>
167 /// Rethrows exceptions from the formatter caused by errors in provided \p{args}.
168 ///
169 /// @param args The list of arguments to add.
170 template<typename TAllocatorArgs>
172
173 /// Variadic template argument version of #Add.
174 ///
175 /// @param args The variadic list of arguments to add.
176 /// @return A reference to ourselves to allow concatenated calls.
177 template <typename... BoxedObjects>
178 Paragraphs& Add( const BoxedObjects&... args ) {
179 boxes.clear();
180 boxes.Add( args... );
181 Add( boxes );
182 return *this;
183 }
184
185 /// This method implements a pre-processing of the text before #Add paragraphs found in
186 /// the text.
187 ///
188 /// The pre-processing is quite simple. Its purpose is to allow longer strings (e.g., loaded
189 /// from a resource pool) with multiple paragraphs to be formatted by embedded escape
190 /// sequences to include indents and nested bullet schemes.
191 ///
192 /// The escape sequences begin with the character stored in field #MarkerChar, which defaults
193 /// to <c>'@'</c>. The following table documents the sequences:
194 ///
195 /// Sequence | Description
196 /// ---------|------------------------------------------------------------------------
197 /// \@@ | Inserts the marker character itself.
198 /// \@>> | Indent text by two spaces
199 /// \@<< | Un-indent text by two spaces
200 /// \@*> | Increases bullet level.
201 /// \@<* | Decreases bullet level
202 /// \@P | Inserts a new line (like '\n') but without ending the current and starting a new bullet point.
203 /// \@HLc | Inserts a horizontal line of width #LineWidth using \p{c} as fill character.
204 ///
205 /// The nested bullet point characters are received from vector #MarkerBullets.
206 ///
207 /// @throws <b>alib::format::FMTExceptions</b>
208 /// - \alib{format::FMTExceptions;UnknownMarker}
209 /// - \alib{format::FMTExceptions;EndmarkerWithoutStart}
210 /// - Rethrows formatter exceptions occurring due to errors in provided \p{args}.
211 ///
212 /// @param args The list of arguments to add.
213 template<typename TAllocatorArgs>
215
216 /// Variadic template argument version of #AddMarked.
217 ///
218 /// @throws <b>alib::format::FMTExceptions</b>
219 /// - \alib{format::FMTExceptions;UnknownMarker}
220 /// - \alib{format::FMTExceptions;EndmarkerWithoutStart}
221 ///
222 /// @param args The variadic list of arguments to add.
223 /// @return A reference to ourselves to allow concatenated calls.
224 template <typename... BoxedObjects>
225 Paragraphs& AddMarked( const BoxedObjects&... args ) {
226 boxes.clear();
227 boxes.Add( args... );
228 AddMarked( boxes );
229 return *this;
230 }
231
232 /// Removes the last new line character at the end of the #Buffer.
233 ///
234 /// @return A reference to the text object.
236 if( Buffer.EndsWith( NEW_LINE ) )
237 Buffer.template DeleteEnd<NC>( NEW_LINE.Length() );
238 return Buffer;
239 }
240
241 /// Clears field #Buffer.
242 ///
243 /// @return A reference to ourselves to allow concatenated calls.
245 Paragraphs& Clear();
246
247
248 /// Add a given number of characters (default is spaces) to the indentation strings
249 /// #IndentFirstLine and #IndentOtherLines.
250 ///
251 /// Use #PopIndent to remove the indent.
252 ///
253 /// @param qty The quantity of characters to add or remove
254 /// @param fillChar The character (used only if \p{qty} is positive).
255 /// @return A reference to ourselves to allow concatenated calls.
257 Paragraphs& PushIndent( uinteger qty, character fillChar = ' ' );
258
259 /// Add the given strings to members #IndentFirstLine and #IndentOtherLines.
260 ///
261 /// @param indentFirstLine The string to add to the current indentation stored in
262 /// #IndentFirstLine.
263 /// @param indentOtherLines The string to add to the current indentation stored in
264 /// #IndentOtherLines.<br>
265 /// Defaults to \b NULL_STRING, which sets it to the same value as
266 /// \p{indentFirstLine}.
267 /// @return A reference to ourselves to allow concatenated calls.
269 Paragraphs& PushIndent( const String& indentFirstLine,
270 const String& indentOtherLines=nullptr);
271
272 /// Removes the most recently added indent.
273 /// @return A reference to ourselves to allow concatenated calls.
276}; // class Paragraphs
277
278#if !DOXYGEN
285#endif // !DOXYGEN
286
287} // namespace alib[::format]
288
289/// Type alias in namespace \b alib.
291
292} // namespace [alib]
AString markedBuffer
Buffer for processing marked text.
StdVectorMA< character > MarkerBullets
ALIB_DLL Paragraphs & PushIndent(uinteger qty, character fillChar=' ')
size_t markerBulletLevel
Buffer for processing marked text.
Paragraphs & AddMarked(const BoxedObjects &... args)
std::stack< integer, StdDequeMA< integer > > IndentSizesFirstLine
void Add(boxing::TBoxes< TAllocatorArgs > &args)
std::stack< integer, StdDequeMA< integer > > IndentSizesOtherLines
void AddMarked(boxing::TBoxes< TAllocatorArgs > &args)
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:503
#define ALIB_EXPORT
Definition alib.inl:497
strings::TAString< character, lang::HeapAllocator > AString
Type alias in namespace alib.
std::vector< T, StdMA< T > > StdVectorMA
Type alias in namespace alib.
constexpr CString NEW_LINE
A zero-terminated string containing the new-line character sequence.
Definition cstring.inl:616
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:193
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:2189
characters::character character
Type alias in namespace alib.
lang::uinteger uinteger
Type alias in namespace alib.
Definition integers.inl:152