Skip to content

Commit 044a18c

Browse files
authored
Merge pull request #280 from eseiler/feat/multi_cite
[FEATURE] Handle multiple citations
2 parents cb13c0c + 875b93b commit 044a18c

File tree

6 files changed

+80
-9
lines changed

6 files changed

+80
-9
lines changed

include/sharg/auxiliary.hpp

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,45 @@ enum class update_notifications : uint8_t
2828
off //!< Automatic update notifications should be disabled.
2929
};
3030

31+
/*!\brief A `std::vector<std::string>` that can also be constructed from `std::string`.
32+
* \ingroup misc
33+
* \details
34+
* \experimentalapi{Experimental since version 1.2.0.}
35+
*/
36+
class vector_of_string : public std::vector<std::string>
37+
{
38+
private:
39+
//!\brief The base type.
40+
using base_t = std::vector<std::string>;
41+
42+
public:
43+
using base_t::base_t;
44+
45+
vector_of_string() = default; //!< Defaulted.
46+
vector_of_string(vector_of_string const &) = default; //!< Defaulted.
47+
vector_of_string & operator=(vector_of_string const &) = default; //!< Defaulted.
48+
vector_of_string(vector_of_string &&) = default; //!< Defaulted.
49+
vector_of_string & operator=(vector_of_string &&) = default; //!< Defaulted.
50+
~vector_of_string() = default; //!< Defaulted.
51+
52+
//!\brief Delegate to `std::string` constructor if possible.
53+
template <typename... t>
54+
requires std::constructible_from<std::string, t...>
55+
constexpr vector_of_string(t &&... str) : base_t{std::string(std::forward<t>(str)...)}
56+
{}
57+
58+
//!\brief Construct from iterator pair.
59+
template <typename Iter>
60+
requires std::constructible_from<std::string, Iter, Iter>
61+
&& std::same_as<std::decay_t<Iter>, std::string::value_type *>
62+
constexpr vector_of_string(Iter begin, Iter end) : base_t{std::string(begin, end)}
63+
{}
64+
65+
//!\brief Construct from an initializer list.
66+
constexpr vector_of_string(std::initializer_list<std::string::value_type> il) : base_t{{il}}
67+
{}
68+
};
69+
3170
/*!\brief Stores all parser related meta information of the sharg::parser.
3271
* \ingroup parser
3372
* \details
@@ -78,8 +117,8 @@ struct parser_meta_data // holds all meta information
78117
*/
79118
std::string long_copyright;
80119

81-
//!\brief How users shall cite your application.
82-
std::string citation;
120+
//!\brief How users shall cite your application.
121+
vector_of_string citation;
83122

84123
/*!\brief The title of your man page when exported by specifying
85124
* "--export-help man" on the common line.

include/sharg/detail/format_base.hpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -595,8 +595,17 @@ class format_help_base : public format_base
595595

596596
if (!empty(meta.citation))
597597
{
598-
derived_t().print_line(derived_t().in_bold("In your academic works please cite: ") + meta.citation,
599-
false);
598+
derived_t().print_line(derived_t().in_bold("In your academic works please cite: "), false);
599+
for (size_t i = 0; i < meta.citation.size(); ++i)
600+
{
601+
// Using `\\fB` and `\\fP` instead of `derived_t().in_bold()` here.
602+
// `format_help::print_list_item` uses `format_help::text_width` to determine whether
603+
// there should be a new line after the key ("[i]").
604+
// `format_help::text_width` ignores special sequences such as `\\fB` and `\\fP`,
605+
// but not the actual control sequences produced by `derived_t().in_bold()`.
606+
// All formats support `\\fB` and `\\fP`.
607+
derived_t().print_list_item("\\fB[" + std::to_string(i + 1u) + "]\\fP", meta.citation[i]);
608+
}
600609
}
601610

602611
if (!empty(meta.long_copyright))

include/sharg/detail/format_help.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ class format_help : public format_help_base<format_help>
196196
// Print term.
197197
std::fill_n(out, layout.leftPadding, ' ');
198198
std::cout << to_text(term);
199-
unsigned pos = layout.leftPadding + term.size();
199+
unsigned pos = layout.leftPadding + text_width(term);
200200
if (pos + layout.centerPadding > layout.rightColumnTab)
201201
{
202202
std::cout << '\n';

test/unit/detail/format_help_test.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,23 @@ TEST_F(format_help_test, with_citation)
192192
+ "LEGAL\n"
193193
" SeqAn Copyright: 2006-2025 Knut Reinert, FU-Berlin; released under the\n"
194194
" 3-clause BSDL.\n"
195-
" In your academic works please cite: citation\n";
195+
" In your academic works please cite:\n [1] citation\n";
196+
EXPECT_EQ(get_parse_cout_on_exit(parser), expected);
197+
}
198+
199+
TEST_F(format_help_test, with_multiple_citation)
200+
{
201+
auto parser = get_parser("-h");
202+
parser.info.citation = {"citation1", "citation2"};
203+
204+
expected = "test_parser\n"
205+
"===========\n"
206+
"\nOPTIONS\n\n"
207+
+ basic_options_str + "\n" + version_str() + "\n"
208+
+ "LEGAL\n"
209+
" SeqAn Copyright: 2006-2025 Knut Reinert, FU-Berlin; released under the\n"
210+
" 3-clause BSDL.\n"
211+
" In your academic works please cite:\n [1] citation1\n [2] citation2\n";
196212
EXPECT_EQ(get_parse_cout_on_exit(parser), expected);
197213
}
198214

test/unit/detail/format_html_test.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,9 @@ TEST_F(format_html_test, full_information_information)
192192
"<br>\n"
193193
"<strong>SeqAn Copyright: </strong>2006-2025 Knut Reinert, FU-Berlin; released under the 3-clause BSDL.\n"
194194
"<br>\n"
195-
"<strong>In your academic works please cite: </strong>citation\n"
195+
"<strong>In your academic works please cite: </strong>\n"
196196
"<br>\n"
197+
"</p>\n<dl>\n<dt><strong>[1]</strong></dt>\n<dd>citation</dd>\n</dl>\n<p>\n"
197198
"For full copyright and/or warranty information see <strong>--copyright</strong>.\n"
198199
"<br>\n"
199200
"</p>\n"

test/unit/detail/format_man_test.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,10 @@ TEST_F(format_man_test, full_info_short_and_citation)
298298
.br
299299
\fBSeqAn Copyright: \fR2006-2025 Knut Reinert, FU-Berlin; released under the 3-clause BSDL.
300300
.br
301-
\fBIn your academic works please cite: \fRcitation
301+
\fBIn your academic works please cite: \fR
302+
.TP
303+
\fB[1]\fP
304+
citation
302305
)";
303306
EXPECT_EQ(get_parse_cout_on_exit(parser), expected);
304307
}
@@ -321,7 +324,10 @@ TEST_F(format_man_test, full_info_short_long_and_citation)
321324
.br
322325
\fBSeqAn Copyright: \fR2006-2025 Knut Reinert, FU-Berlin; released under the 3-clause BSDL.
323326
.br
324-
\fBIn your academic works please cite: \fRcitation
327+
\fBIn your academic works please cite: \fR
328+
.TP
329+
\fB[1]\fP
330+
citation
325331
.br
326332
For full copyright and/or warranty information see \fB--copyright\fR.
327333
)";

0 commit comments

Comments
 (0)