ALib C++ Framework
by
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 #"mainpage_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(const BoxedObjects)", member #".Formatter" is used to append the given parameters and
19/// then the new paragraph is formatted using the static method #".Format".<br>
20/// This way, a longer text might be built by repetitive calls.
21//==================================================================================================
23 //################################################################################################
24 // Fields
25 //################################################################################################
26 protected:
27 /// Allocator used for internal container types.
29
30 /// Internal buffer, used for field #"Paragraphs", if no external string object was given.
32
33 public:
34 /// A reference to the text buffer. Either refers to otherwise protected field #"text" or to
35 /// what was given in alternative construction.
37
38 /// The formatter to use.
39 /// In the constructor, this shared pointer is initialized with to share the
40 /// alib{format;Formatter::DEFAULT;ALib Default Formatter}.
42
43 /// Used as parameter \p{lineWidth} of static method invocations.
45
46 /// Used as parameter \p{justifyChar} of static method invocations.
47 /// Usually set to <c>' '</c> to enable paragraph width justification.<br>
48 /// Defaults to <c>'\\0'</c> which disables it.
50
51 /// Used to detect special commands given with format strings.
52 /// \see Method #".AddMarked(const BoxedObjects)" for more information.
53 ///
54 /// Defaults to <c>'@'</c>.
56
57 /// The bullet used with increasing bullet depths.
58 /// Defaults to <c>'*'</c>, <c>'-'</c>, <c>'*'</c>, <c>'-'</c>, <c>'*'</c>, <c>'-'</c>.
60
61 /// Used as parameter \p{indent} of static method invocations.<br>
62 /// The indent string of the first line.
63 ///
64 /// This field can either be manipulated by direct access or preferably with
65 /// overloaded methods #".PushIndent(uint)" and #"PopIndent".
67
68 /// Used as the parameter \p{indent} of static method invocations.<br>
69 /// The indent string of text lines, excluding the first line.
70 ///
71 /// This field can either be manipulated by direct access or preferably with
72 /// overloaded methods #".PushIndent(uint)" and #"PopIndent".
74
75 /// The stack of indent substring sizes in string #"IndentFirstLine".
76 /// Used with #".PushIndent(uint)" and #"PopIndent".
77 std::stack<integer, StdDequeMA<integer>> IndentSizesFirstLine;
78
79 /// The stack of indent substring sizes in string #"IndentOtherLines".
80 /// Used with #".PushIndent(uint)" and #"PopIndent".
81 std::stack<integer, StdDequeMA<integer>> IndentSizesOtherLines;
82
83 /// This field is increased whenever a line of text added is longer than its current
84 /// value.
85 /// Might be used by to detect the maximum line width when field #".LineWidth" is set to \c 0
86 /// and hence no auto wrap is done.
88
89
90 protected:
91 /// Internally reused list of boxes.
93
94 /// Buffer for processing marked text.
96
97 /// Buffer for processing marked text.
99
100 //################################################################################################
101 // Constructor/Destructor
102 //################################################################################################
103 public:
104 /// Parameterless constructor.
105 /// Internal buffer #"text" will be used with reference #"Buffer".
106 /// For field #".Formatter", #"Formatter::DEFAULT;*" will be used.
108
109 /// Constructor that accepts an external buffer to use.
110 /// @param externalBuffer The external buffer to use and fill.
111 ALIB_DLL Paragraphs( AString& externalBuffer );
112
113 //################################################################################################
114 // Interface
115 //################################################################################################
116 public:
117
118 /// Formats one or more paragraphs (separated by \b NewLine symbols) with three optional
119 /// features:
120 ///
121 /// - Wrapping of lines longer than lineWidth (word wrap)
122 /// - Justify the text, which here means "full justification", i.e., format the text to have
123 /// lines of the exact same width.
124 /// - Adding an indentation to each line with an optionally different indentation for the
125 /// first line after a \b NewLine symbol and subsequent ones.
126 ///
127 /// The paragraph starts at \p{startIdx} and all of the rest of the string is treated
128 /// as one paragraph. New-line character sequences found within the paragraph are considered
129 /// manual line ends. Hence, no block formatting for lines ending with a new line character
130 /// is performed.
131 ///
132 /// The method is static and hence can be used with arbitrary buffers.
133 /// Non-static methods #".Add(const BoxedObjects)" invoke this method after adding the given
134 /// content to the internal buffer. Furthermore, convenience functions and corresponding member
135 /// variables simplify the use of this method when indirectly used through an instance of
136 /// the class.
137 ///
138 /// @param text The text containing the paragraph to format.
139 /// @param startIdx The start of the paragraph.
140 /// @param lineWidth The width of the line. If \c 0 or negative, no line wrap is
141 /// performed.
142 /// @param justifyChar If this is unequal to <c>'\0'</c> it denotes the fill
143 /// character used to justify the paragraph.
144 /// Defaults to <c>'\0'</c>, which disables justification.
145 /// @param[out] maxLineWidth Provides the maximum width of all text lines written.
146 /// @param indentFirstLine The indent string of the first line. Defaults to \c nullptr.
147 /// @param indentOtherLines The indent string of subsequent lines. Defaults to \c nullptr.
149 static
150 void Format( AString& text,
151 integer startIdx,
152 integer lineWidth,
153 character justifyChar,
154 integer& maxLineWidth,
155 const String& indentFirstLine = nullptr,
156 const String& indentOtherLines= nullptr );
157
158 /// Appends the given objects \p{args} to the internal #Buffer with the help of member
159 /// #Formatter. Then, the static method #Format is invoked, providing our public
160 /// members as parameters. Finally, a newline sequence is added to #Buffer, but only if the
161 /// buffer is not empty and if it does not already end with a newline sequence.
162 ///
163 /// @throws <b>alib::format::FMTExceptions</b><br>
164 /// Rethrows exceptions from the formatter caused by errors in provided \p{args}.
165 ///
166 /// @param args The list of arguments to add.
167 template<typename TAllocatorArgs>
169
170 /// Variadic template argument version of #Add.
171 ///
172 /// @param args The variadic list of arguments to add.
173 /// @return A reference to ourselves to allow concatenated calls.
174 template <typename... BoxedObjects>
175 Paragraphs& Add( const BoxedObjects&... args ) {
176 boxes.clear();
177 boxes.Add( args... );
178 Add( boxes );
179 return *this;
180 }
181
182 /// This method implements a pre-processing of the text before #Add paragraphs found in
183 /// the text.
184 ///
185 /// The pre-processing is quite simple. Its purpose is to allow longer strings (e.g., loaded
186 /// from a resource pool) with multiple paragraphs to be formatted by embedded escape
187 /// sequences to include indents and nested bullet schemes.
188 ///
189 /// The escape sequences begin with the character stored in field #MarkerChar, which defaults
190 /// to <c>'@'</c>. The following table documents the sequences:
191 ///
192 /// Sequence | Description
193 /// ---------|------------------------------------------------------------------------
194 /// \@@ | Inserts the marker character itself.
195 /// \@>> | Indent text by two spaces
196 /// \@<< | Un-indent text by two spaces
197 /// \@*> | Increases bullet level.
198 /// \@<* | Decreases bullet level
199 /// \@P | Inserts a new line (like '\n') but without ending the current and starting a new bullet point.
200 /// \@HLc | Inserts a horizontal line of width #LineWidth using \p{c} as fill character.
201 ///
202 /// The nested bullet point characters are received from vector #MarkerBullets.
203 ///
204 /// @throws <b>alib::format::FMTExceptions</b>
205 /// - #"FMTExceptions::UnknownMarker"
206 /// - #"FMTExceptions::EndmarkerWithoutStart"
207 /// - Rethrows formatter exceptions occurring due to errors in provided \p{args}.
208 ///
209 /// @param args The list of arguments to add.
210 template<typename TAllocatorArgs>
212
213 /// Variadic template argument version of #AddMarked.
214 ///
215 /// @throws <b>alib::format::FMTExceptions</b>
216 /// - #"FMTExceptions::UnknownMarker"
217 /// - #"FMTExceptions::EndmarkerWithoutStart"
218 ///
219 /// @param args The variadic list of arguments to add.
220 /// @return A reference to ourselves to allow concatenated calls.
221 template <typename... BoxedObjects>
222 Paragraphs& AddMarked( const BoxedObjects&... args ) {
223 boxes.clear();
224 boxes.Add( args... );
225 AddMarked( boxes );
226 return *this;
227 }
228
229 /// Removes the last new line character at the end of the #Buffer.
230 ///
231 /// @return A reference to the text object.
233 if( Buffer.EndsWith( NEW_LINE ) )
234 Buffer.template DeleteEnd<NC>( NEW_LINE.Length() );
235 return Buffer;
236 }
237
238 /// Clears field #Buffer.
239 ///
240 /// @return A reference to ourselves to allow concatenated calls.
242 Paragraphs& Clear();
243
244
245 /// Add a given number of characters (default is spaces) to the indentation strings
246 /// #IndentFirstLine and #IndentOtherLines.
247 ///
248 /// Use #PopIndent to remove the indent.
249 ///
250 /// @param qty The quantity of characters to add or remove
251 /// @param fillChar The character (used only if \p{qty} is positive).
252 /// @return A reference to ourselves to allow concatenated calls.
254 Paragraphs& PushIndent( uinteger qty, character fillChar = ' ' );
255
256 /// Add the given strings to members #IndentFirstLine and #IndentOtherLines.
257 ///
258 /// @param indentFirstLine The string to add to the current indentation stored in
259 /// #IndentFirstLine.
260 /// @param indentOtherLines The string to add to the current indentation stored in
261 /// #IndentOtherLines.<br>
262 /// Defaults to \b NULL_STRING, which sets it to the same value as
263 /// \p{indentFirstLine}.
264 /// @return A reference to ourselves to allow concatenated calls.
266 Paragraphs& PushIndent( const String& indentFirstLine,
267 const String& indentOtherLines=nullptr);
268
269 /// Removes the most recently added indent.
270 /// @return A reference to ourselves to allow concatenated calls.
273}; // class Paragraphs
274
275#if !DOXYGEN
282#endif // !DOXYGEN
283
284} // namespace alib[::format]
285
286/// Type alias in namespace \b alib.
288
289} // namespace [alib]
#define ALIB_DLL
Definition alib.inl:573
#define ALIB_EXPORT
Definition alib.inl:562
AString markedBuffer
Buffer for processing marked text.
StdVectorMA< character > MarkerBullets
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 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.
Paragraphs & PopIndent()
strings::TAString< character, MonoAllocator > AStringMA
Type alias in namespace alib.
monomem::TMonoAllocator< lang::HeapAllocator > MonoAllocator
containers::SharedPtr< format::Formatter > SPFormatter
Definition formatter.inl:42
constexpr CString NEW_LINE
A zero-terminated string containing the new-line character sequence.
Definition cstring.inl:540
lang::integer integer
Type alias in namespace alib.
Definition integers.inl:149
strings::TString< character > String
Type alias in namespace alib.
Definition string.inl:2172
boxing::TBoxes< MonoAllocator > BoxesMA
Type alias in namespace alib.
Definition boxes.inl:193
strings::TAString< character, lang::HeapAllocator > AString
Type alias in namespace alib.
format::Paragraphs Paragraphs
Type alias in namespace alib.
characters::character character
Type alias in namespace alib.
lang::uinteger uinteger
Type alias in namespace alib.
Definition integers.inl:152
std::vector< T, StdMA< T > > StdVectorMA
Type alias in namespace alib.