aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2023-05-26 13:18:46 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2023-05-30 11:26:50 +0300
commit651c01a92dbbec65674fe3c73a6c82a936e73d91 (patch)
tree6a9c62f2d4756b4547c1a742a57d546db9e81b62
parent9d3853cef802cb25ccc5c6749293d76990a3030c (diff)
Add support for package-description, package-description-type, and changes-type package manifest values
-rw-r--r--libbrep/package.cxx20
-rw-r--r--libbrep/package.hxx41
-rw-r--r--libbrep/package.xml7
-rw-r--r--load/load.cxx91
-rw-r--r--mod/mod-package-details.cxx6
-rw-r--r--mod/mod-package-version-details.cxx26
-rw-r--r--mod/page.cxx14
-rw-r--r--mod/page.hxx13
-rw-r--r--tests/load/1/math/libfoo-1.2.4+1.tar.gzbin1437 -> 1496 bytes
-rw-r--r--tests/load/1/math/packages.manifest20
-rw-r--r--tests/load/1/misc/packages.manifest1
-rw-r--r--tests/load/1/stable/packages.manifest1
-rw-r--r--tests/load/1/stable/signature.manifest20
-rw-r--r--tests/load/driver.cxx51
-rw-r--r--www/package-version-details-body.css44
15 files changed, 249 insertions, 106 deletions
diff --git a/libbrep/package.cxx b/libbrep/package.cxx
index 152d1d8..e5e7767 100644
--- a/libbrep/package.cxx
+++ b/libbrep/package.cxx
@@ -60,9 +60,9 @@ namespace brep
license_alternatives_type la,
small_vector<string, 5> tp,
small_vector<string, 5> kw,
- optional<string> ds,
- optional<text_type> dt,
- string ch,
+ optional<typed_text> ds,
+ optional<typed_text> pds,
+ optional<typed_text> ch,
optional<manifest_url> ur,
optional<manifest_url> du,
optional<manifest_url> su,
@@ -94,7 +94,7 @@ namespace brep
topics (move (tp)),
keywords (move (kw)),
description (move (ds)),
- description_type (move (dt)),
+ package_description (move (pds)),
changes (move (ch)),
url (move (ur)),
doc_url (move (du)),
@@ -216,7 +216,17 @@ namespace brep
for (const auto& k: keywords)
k2 += ' ' + k;
- return {move (k), move (k2), description ? *description : "", changes};
+ string d (description ? description->text : "");
+
+ if (package_description)
+ {
+ if (description)
+ d += ' ';
+
+ d += package_description->text;
+ }
+
+ return {move (k), move (k2), move (d), changes ? changes->text : ""};
}
// repository
diff --git a/libbrep/package.hxx b/libbrep/package.hxx
index bba38b7..4cbdded 100644
--- a/libbrep/package.hxx
+++ b/libbrep/package.hxx
@@ -18,9 +18,9 @@
// Used by the data migration entries.
//
-#define LIBBREP_PACKAGE_SCHEMA_VERSION_BASE 26
+#define LIBBREP_PACKAGE_SCHEMA_VERSION_BASE 27
-#pragma db model version(LIBBREP_PACKAGE_SCHEMA_VERSION_BASE, 26, closed)
+#pragma db model version(LIBBREP_PACKAGE_SCHEMA_VERSION_BASE, 27, closed)
namespace brep
{
@@ -49,9 +49,12 @@ namespace brep
using bpkg::text_type;
using bpkg::to_text_type;
+ // Note that here we assume that the saved string representation of a type
+ // is always recognized later.
+ //
#pragma db map type(text_type) as(string) \
to(to_string (?)) \
- from(brep::to_text_type (?))
+ from(*brep::to_text_type (?))
using optional_text_type = optional<text_type>;
@@ -396,6 +399,15 @@ namespace brep
string d;
};
+ #pragma db value
+ struct typed_text
+ {
+ string text;
+ text_type type;
+
+ #pragma db member(text) column("")
+ };
+
// Tweak package_id mapping to include a constraint (this only affects the
// database schema).
//
@@ -429,9 +441,9 @@ namespace brep
license_alternatives_type,
small_vector<string, 5> topics,
small_vector<string, 5> keywords,
- optional<string> description,
- optional<text_type> description_type,
- string changes,
+ optional<typed_text> description,
+ optional<typed_text> package_description,
+ optional<typed_text> changes,
optional<manifest_url> url,
optional<manifest_url> doc_url,
optional<manifest_url> src_url,
@@ -501,9 +513,14 @@ namespace brep
license_alternatives_type license_alternatives;
small_vector<string, 5> topics;
small_vector<string, 5> keywords;
- optional<string> description; // Absent if type is unknown.
- optional<text_type> description_type; // Present if description is present.
- string changes;
+
+ // Note that the descriptions and changes are absent if the respective
+ // type is unknown.
+ //
+ optional<typed_text> description;
+ optional<typed_text> package_description;
+ optional<typed_text> changes;
+
optional<manifest_url> url;
optional<manifest_url> doc_url;
optional<manifest_url> src_url;
@@ -723,9 +740,9 @@ namespace brep
friend class odb::access;
package (): tenant (id.tenant), name (id.name) {}
- // Save keywords, summary, description, and changes to weighted_text
- // a, b, c, d members, respectively. So a word found in keywords will
- // have a higher weight than if it's found in the summary.
+ // Save keywords, summary, descriptions, and changes to weighted_text a,
+ // b, c, d members, respectively. So a word found in keywords will have a
+ // higher weight than if it's found in the summary.
//
weighted_text
search_text () const;
diff --git a/libbrep/package.xml b/libbrep/package.xml
index 8f32284..98c9055 100644
--- a/libbrep/package.xml
+++ b/libbrep/package.xml
@@ -1,5 +1,5 @@
<changelog xmlns="http://www.codesynthesis.com/xmlns/odb/changelog" database="pgsql" schema-name="package" version="1">
- <model version="26">
+ <model version="27">
<table name="tenant" kind="object">
<column name="id" type="TEXT" null="false"/>
<column name="private" type="BOOLEAN" null="false"/>
@@ -144,7 +144,10 @@
<column name="summary" type="TEXT" null="false"/>
<column name="description" type="TEXT" null="true"/>
<column name="description_type" type="TEXT" null="true"/>
- <column name="changes" type="TEXT" null="false"/>
+ <column name="package_description" type="TEXT" null="true"/>
+ <column name="package_description_type" type="TEXT" null="true"/>
+ <column name="changes" type="TEXT" null="true"/>
+ <column name="changes_type" type="TEXT" null="true"/>
<column name="url" type="TEXT" null="true"/>
<column name="url_comment" type="TEXT" null="true"/>
<column name="doc_url" type="TEXT" null="true"/>
diff --git a/load/load.cxx b/load/load.cxx
index a201785..0468565 100644
--- a/load/load.cxx
+++ b/load/load.cxx
@@ -450,50 +450,87 @@ load_packages (const shared_ptr<repository>& rp,
// Create internal package object.
//
- optional<string> dsc;
- optional<text_type> dst;
-
- if (pm.description)
+ // Return nullopt if the text is in a file (can happen if the
+ // repository is of a type other than pkg) or if the type is not
+ // recognized (can only happen in the "ignore unknown" mode).
+ //
+ auto to_typed_text = [&cl, &p, ignore_unknown] (typed_text_file&& v)
{
+ optional<typed_text> r;
+
// The description value should not be of the file type if the
// package manifest comes from the pkg repository.
//
- assert (!pm.description->file || cl.type () != repository_type::pkg);
+ assert (!v.file || cl.type () != repository_type::pkg);
- if (!pm.description->file)
+ if (!v.file)
{
- dst = pm.effective_description_type (ignore_unknown);
+ // Cannot throw since the manifest parser has already verified the
+ // effective type in the same "ignore unknown" mode.
+ //
+ optional<text_type> t (v.effective_type (ignore_unknown));
// If the description type is unknown (which may be the case for
// some "transitional" period and only if --ignore-unknown is
// specified) we just silently drop the description.
//
- assert (dst || ignore_unknown);
+ assert (t || ignore_unknown);
- if (dst)
- dsc = move (pm.description->text);
+ if (t)
+ r = typed_text {move (v.text), *t};
}
- }
- string chn;
+ return r;
+ };
+
+ // Convert descriptions.
+ //
+ optional<typed_text> ds (
+ pm.description
+ ? to_typed_text (move (*pm.description))
+ : optional<typed_text> ());
+
+ optional<typed_text> pds (
+ pm.package_description
+ ? to_typed_text (move (*pm.package_description))
+ : optional<typed_text> ());
+
+ // Merge changes into a single typed text object.
+ //
+ // If the text type is not recognized for any changes entry or some
+ // entry refers to a file, then assume that no changes are specified.
+ //
+ optional<typed_text> chn;
+
for (auto& c: pm.changes)
{
- // The changes value should not be of the file type if the package
- // manifest comes from the pkg repository.
- //
- assert (!c.file || cl.type () != repository_type::pkg);
+ optional<typed_text> tc (to_typed_text (move (c)));
- if (!c.file)
+ if (!tc)
{
- if (chn.empty ())
- chn = move (c.text);
- else
- {
- if (chn.back () != '\n')
- chn += '\n'; // Always have a blank line as a separator.
+ chn = nullopt;
+ break;
+ }
- chn += "\n" + c.text;
- }
+ if (!chn)
+ {
+ chn = move (*tc);
+ }
+ else
+ {
+ // Should have failed while parsing the manifest otherwise.
+ //
+ assert (tc->type == chn->type);
+
+ string& v (chn->text);
+
+ assert (!v.empty ()); // Changes manifest value cannot be empty.
+
+ if (v.back () != '\n')
+ v += '\n'; // Always have a blank line as a separator.
+
+ v += '\n';
+ v += tc->text;
}
}
@@ -566,8 +603,8 @@ load_packages (const shared_ptr<repository>& rp,
move (pm.license_alternatives),
move (pm.topics),
move (pm.keywords),
- move (dsc),
- move (dst),
+ move (ds),
+ move (pds),
move (chn),
move (pm.url),
move (pm.doc_url),
diff --git a/mod/mod-package-details.cxx b/mod/mod-package-details.cxx
index 13e6422..5cf0759 100644
--- a/mod/mod-package-details.cxx
+++ b/mod/mod-package-details.cxx
@@ -183,20 +183,20 @@ handle (request& rq, response& rs)
//
s << H2 << pkg->summary << ~H2;
- if (const optional<string>& d = pkg->description)
+ if (const optional<typed_text>& d = pkg->package_description
+ ? pkg->package_description
+ : pkg->description)
{
const string id ("description");
const string what (name.string () + " description");
s << (full
? DIV_TEXT (*d,
- *pkg->description_type,
true /* strip_title */,
id,
what,
error)
: DIV_TEXT (*d,
- *pkg->description_type,
true /* strip_title */,
options_->package_description (),
url (!full, squery, page, id),
diff --git a/mod/mod-package-version-details.cxx b/mod/mod-package-version-details.cxx
index e47d9b4..3a8d8f4 100644
--- a/mod/mod-package-version-details.cxx
+++ b/mod/mod-package-version-details.cxx
@@ -189,20 +189,20 @@ handle (request& rq, response& rs)
s << H2 << pkg->summary << ~H2;
- if (const optional<string>& d = pkg->description)
+ if (const optional<typed_text>& d = pkg->package_description
+ ? pkg->package_description
+ : pkg->description)
{
const string id ("description");
const string what (title + " description");
s << (full
? DIV_TEXT (*d,
- *pkg->description_type,
true /* strip_title */,
id,
what,
error)
: DIV_TEXT (*d,
- *pkg->description_type,
true /* strip_title */,
options_->package_description (),
url (!full, id),
@@ -886,19 +886,25 @@ handle (request& rq, response& rs)
s << ~DIV;
}
- const string& ch (pkg->changes);
-
- if (!ch.empty ())
+ if (const optional<typed_text>& c = pkg->changes)
{
const string id ("changes");
+ const string what (title + " changes");
s << H3 << "Changes" << ~H3
<< (full
- ? PRE_TEXT (ch, id)
- : PRE_TEXT (ch,
+ ? DIV_TEXT (*c,
+ false /* strip_title */,
+ id,
+ what,
+ error)
+ : DIV_TEXT (*c,
+ false /* strip_title */,
options_->package_changes (),
- url (!full, "changes"),
- id));
+ url (!full, id),
+ id,
+ what,
+ error));
}
s << ~DIV
diff --git a/mod/page.cxx b/mod/page.cxx
index a671346..331f919 100644
--- a/mod/page.cxx
+++ b/mod/page.cxx
@@ -953,14 +953,16 @@ namespace brep
void DIV_TEXT::
operator() (serializer& s) const
{
- switch (type_)
+ const string& t (text_.text);
+
+ switch (text_.type)
{
case text_type::plain:
{
// To keep things regular we wrap the preformatted text into <div>.
//
s << DIV(ID=id_, CLASS="plain");
- serialize_pre_text (s, text_, length_, url_, "" /* id */);
+ serialize_pre_text (s, t, length_, url_, "" /* id */);
s << ~DIV;
break;
}
@@ -980,9 +982,9 @@ namespace brep
// calls to fail is the inability to allocate memory. Unfortunately,
// instead of reporting the failure to the caller, the API issues
// diagnostics to stderr and aborts the process. Let's decrease the
- // probability of such an event by limiting the text size to 64K.
+ // probability of such an event by limiting the text size to 1M.
//
- if (text_.size () > 64 * 1024)
+ if (t.size () > 1024 * 1024)
{
print_error (what_ + " is too long");
return;
@@ -1006,7 +1008,7 @@ namespace brep
// Enable GitHub extensions in the parser, if requested.
//
- if (type_ == text_type::github_mark)
+ if (text_.type == text_type::github_mark)
{
auto add = [&parser] (const char* ext)
{
@@ -1025,7 +1027,7 @@ namespace brep
add ("autolink");
}
- cmark_parser_feed (parser.get (), text_.c_str (), text_.size ());
+ cmark_parser_feed (parser.get (), t.c_str (), t.size ());
unique_ptr<cmark_node, void (*)(cmark_node*)> doc (
cmark_parser_finish (parser.get ()),
diff --git a/mod/page.hxx b/mod/page.hxx
index 0a5d359..dc85230 100644
--- a/mod/page.hxx
+++ b/mod/page.hxx
@@ -591,16 +591,14 @@ namespace brep
public:
// Generate a full text element.
//
- DIV_TEXT (const string& t,
- text_type tp,
+ DIV_TEXT (const typed_text& t,
bool st,
const string& id,
const string& what,
const basic_mark& diag)
: text_ (t),
- type_ (tp),
strip_title_ (st),
- length_ (t.size ()),
+ length_ (t.text.size ()),
url_ (nullptr),
id_ (id),
what_ (what),
@@ -610,8 +608,7 @@ namespace brep
// Generate a brief text element.
//
- DIV_TEXT (const string& t,
- text_type tp,
+ DIV_TEXT (const typed_text& t,
bool st,
size_t l,
const string& u,
@@ -619,7 +616,6 @@ namespace brep
const string& what,
const basic_mark& diag)
: text_ (t),
- type_ (tp),
strip_title_ (st),
length_ (l),
url_ (&u),
@@ -633,8 +629,7 @@ namespace brep
operator() (xml::serializer&) const;
private:
- const string& text_;
- text_type type_;
+ const typed_text& text_;
bool strip_title_;
size_t length_;
const string* url_; // Full page url.
diff --git a/tests/load/1/math/libfoo-1.2.4+1.tar.gz b/tests/load/1/math/libfoo-1.2.4+1.tar.gz
index 2dde730..d3e7a0d 100644
--- a/tests/load/1/math/libfoo-1.2.4+1.tar.gz
+++ b/tests/load/1/math/libfoo-1.2.4+1.tar.gz
Binary files differ
diff --git a/tests/load/1/math/packages.manifest b/tests/load/1/math/packages.manifest
index 8e66ddf..9be4033 100644
--- a/tests/load/1/math/packages.manifest
+++ b/tests/load/1/math/packages.manifest
@@ -71,14 +71,28 @@ Useful for conversion of research code into production environments.
[^mathlab]: MATLAB Capabilities: TODO
\
description-type: text/markdown
+package-description:\
+This project builds and defines the build2 package for the libfoo library.
+
+A modern C++ library with easy to use linear algebra and lot of optimization
+tools.
+
+There are over 100 functions in total with an extensive test suite. The API is
+similar to ~~mathlab~~ **MATLAB**.[^mathlab]
+
+Useful for conversion of research code into production environments.
+[^mathlab]: MATLAB Capabilities: TODO
+\
+package-description-type: text/markdown
changes:\
-1.2.4+1
+**1.2.4+1**
* applied patch for critical bug-219
* regenerated documentation
-1.2.4
+**1.2.4**
* test suite extended significantly
\
+changes-type: text/markdown
url: http://www.example.com/foo/; Project home page.
doc-url: http://www.example.org/projects/libfoo/man.xhtml; Documentation page.
src-url: http://scm.example.com/?p=odb/libodb.git\;a=tree; Source tree url.
@@ -126,7 +140,7 @@ config [uint64] config.libfoo.buffer ?= 1024
\
location: libfoo-1.2.4+1.tar.gz
-sha256sum: fe07978d72ab65c2ad72b0325aa56944cf093248d39edcb472a2fe5835defa3d
+sha256sum: 072386bc75b026889d2992374609a2b4fa18ee59c00f664d5bb21fb86a090671
:
name: libfoo-benchmarks
version: 1.2.4
diff --git a/tests/load/1/misc/packages.manifest b/tests/load/1/misc/packages.manifest
index b019920..86620dd 100644
--- a/tests/load/1/misc/packages.manifest
+++ b/tests/load/1/misc/packages.manifest
@@ -15,6 +15,7 @@ depends: libfoo
depends: libmath >= 2.0.0
requires: linux | windows | macosx
changes: some changes
+changes-type: text/plain
location: libbar-2.4.0+3.tar.gz
sha256sum: 70ccba3da34dd0296866027a26b6bacf08cacc80f54516d3b8d8eeccbe31ab93
:
diff --git a/tests/load/1/stable/packages.manifest b/tests/load/1/stable/packages.manifest
index 8d51838..f15ab90 100644
--- a/tests/load/1/stable/packages.manifest
+++ b/tests/load/1/stable/packages.manifest
@@ -75,6 +75,7 @@ description: Very good foo library.
description-type: text/plain
changes: some changes 1
changes: some changes 2
+changes-type: text/plain
url: http://www.example.com/foo/
email: foo-users@example.com
depends: libmisc >= 2.0.0
diff --git a/tests/load/1/stable/signature.manifest b/tests/load/1/stable/signature.manifest
index 9d3b944..bb18e13 100644
--- a/tests/load/1/stable/signature.manifest
+++ b/tests/load/1/stable/signature.manifest
@@ -1,13 +1,13 @@
: 1
-sha256sum: 300aaa95b27809ca4bccf4b6eeb5f81701117457bd9e6018964004d4bbedbfb8
+sha256sum: defa57373e20beb8f22a391b1e97ec7f5e50469e050c2551e8522fab74f304e1
signature:\
-kBjhtZKRx9FJmJmm+Bh8gUmvK99kQCWmA9qlyLWLfOiapvtliGn65eCh1uCbrjKWGri8SHPD1ABZ
-aYcfPE5Cg6L40FltFqYF5qliZo2V8Um3JPd56Bm1S8/yBTftojEBNS4RYBLcLLmd6Blmb9/igTAQ
-OOTep/zb3IGZuFzbiLHbfhP7VA4m7PUxV7AlZwSY8IhxzGurQWfBIpGskqkGk57mO+rQy3sq6bWH
-IzbgA4hvfkiXyXzcuDIlfcSQaIAfzClqybNaEFgkqKeoZgUkPLbZiYCGasyVCSmCE0gthgOZL7gJ
-sJU3iyQMeawCKuQhCr2wz1xhJjLdT41eQ1b4YbtKKneVKOhZDRXosw86xk0Ghi7SeNmWVa2y0UIg
-fLIU8um23Gh5Tf37C4pyWjSLVJ4TwAvUGPhxBxd1E2Khuvak/x/+vo983tEikI14InLkdt/KdVpd
-lprE9YEACNFaSJ1cwI6aX8exL4a7kku3YG65Mgg+JD5E1HGAOIfCZ/4FJxBF5Mq6cXDT0fIcVR7b
-ioAJVa9q+EdRrMXlovCCDvmFUvwggTTL1N1/8o0gZrgJW76BTZrNA+MJ2pkwlsJDrNi6JhqbcbOn
-ldZG1n5IwCEt4SvL2LV5iR/iH7iWrIPnkqJJu8rGKWWywz+mmOsl/TBpQylKKXmYLAnWA31htC4=
+f9b/Q+mBos6MwwFPIiIBqSEidqO+rMsktQ1ESWEkO48uHN+hjNCog0gp3Vf4QHj0p2KKU5Uz4exj
+8h7R3RB0F4B10/lDyHw4XlvAyP1uE+YS76rEXHXuGBEnGvBK9818WkCJ5yfFJYg3AuGt2Cyd3QHF
+Uxv+fDkI05KrZNGzLo9euDr6yhHOMTjwSntu/lt6ytfyzTFHcs0xOM03qEtszD5QrNdC32z7kmDE
+8ISUlMUyqOjsz8h25F04NyiojccGTpfUTgqA2zXqMAwRn+fG9wU5Vwnau/oIcAO+nUruR4i1VrDd
+D5q/gjbOpcBTt7bmbVInR5glbgdPZ7r7gpqfOVwybxeTrArj72jA/XmmYyZlaTTW1RXcJuRIWAcP
+2Z61O+cwP9CqW8ktQDNGkgDxxXJR7aEG64G8q7uZeb6v1FaQCwo2JEe/Tv0JDp+DBVKwBm7ZDZi/
+TVtltbADgISCU8bTVz/r4Q0qwHeiQo2GV+Di4h7KvWS8H2Q7sjpyWrI3/UzujOp+zB/BP+6dNZTr
+6Mf8CJ+9L5YY4lzX9jeVQLOuKOqLLZWD2VQiyaYZp79X5OtSHuNvCWcaWUa9Rpu/goLCPrk6QHD+
+wUTYcIdsEbX2jDN3YQwe53WklytPbMxy7taRF1obpGOpDDju3InD3IRXS7ch4G9XzqtsylzMIeE=
\
diff --git a/tests/load/driver.cxx b/tests/load/driver.cxx
index ae3d03d..f61ab25 100644
--- a/tests/load/driver.cxx
+++ b/tests/load/driver.cxx
@@ -57,7 +57,7 @@ check_external (const package& p)
!p.internal () &&
p.other_repositories.size () > 0 &&
p.priority == priority () &&
- p.changes.empty () &&
+ !p.changes &&
p.license_alternatives.empty () &&
p.dependencies.empty () &&
p.requirements.empty () &&
@@ -384,7 +384,7 @@ test_pkg_repos (const cstrings& loader_args,
assert (fpvxy->other_repositories.empty ());
assert (fpvxy->priority == priority::low);
- assert (fpvxy->changes.empty ());
+ assert (!fpvxy->changes);
assert (fpvxy->license_alternatives.size () == 1);
assert (fpvxy->license_alternatives[0].size () == 1);
@@ -420,7 +420,7 @@ test_pkg_repos (const cstrings& loader_args,
assert (fpv1->other_repositories[1].load () == cr);
assert (fpv1->priority == priority::low);
- assert (fpv1->changes.empty ());
+ assert (!fpv1->changes);
assert (fpv1->license_alternatives.size () == 1);
assert (fpv1->license_alternatives[0].size () == 1);
@@ -454,7 +454,7 @@ test_pkg_repos (const cstrings& loader_args,
assert (fpv2->internal_repository.load () == sr);
assert (fpv2->other_repositories.empty ());
assert (fpv2->priority == priority::low);
- assert (fpv2->changes.empty ());
+ assert (!fpv2->changes);
assert (fpv2->license_alternatives.size () == 1);
assert (fpv2->license_alternatives[0].size () == 1);
@@ -500,7 +500,7 @@ test_pkg_repos (const cstrings& loader_args,
assert (fpv2a->internal_repository.load () == sr);
assert (fpv2a->other_repositories.empty ());
assert (fpv2a->priority == priority::security);
- assert (fpv2a->changes.empty ());
+ assert (!fpv2a->changes);
assert (fpv2a->license_alternatives.size () == 1);
assert (fpv2a->license_alternatives[0].size () == 1);
@@ -563,7 +563,7 @@ test_pkg_repos (const cstrings& loader_args,
assert (fpv3->other_repositories.empty ());
assert (fpv3->priority == priority::medium);
- assert (fpv3->changes.empty ());
+ assert (!fpv3->changes);
assert (fpv3->license_alternatives.size () == 1);
assert (fpv3->license_alternatives[0].size () == 1);
@@ -591,7 +591,7 @@ test_pkg_repos (const cstrings& loader_args,
assert (fpv4->summary == "The Foo Library");
assert (fpv4->keywords == labels ({"c++", "foo"}));
- assert (*fpv4->description == "Very good foo library.");
+ assert (fpv4->description->text == "Very good foo library.");
assert (fpv4->url && fpv4->url->string () == "http://www.example.com/foo/");
assert (!fpv4->package_url);
assert (fpv4->email && *fpv4->email == "foo-users@example.com");
@@ -600,7 +600,10 @@ test_pkg_repos (const cstrings& loader_args,
assert (fpv4->internal_repository.load () == sr);
assert (fpv4->other_repositories.empty ());
assert (fpv4->priority == priority::low);
- assert (fpv4->changes == "some changes 1\n\nsome changes 2");
+
+ assert (fpv4->changes &&
+ fpv4->changes->text == "some changes 1\n\nsome changes 2" &&
+ fpv4->changes->type == text_type::plain);
assert (fpv4->license_alternatives.size () == 1);
assert (fpv4->license_alternatives[0].comment ==
@@ -686,7 +689,7 @@ test_pkg_repos (const cstrings& loader_args,
assert (xpv->internal_repository.load () == mr);
assert (xpv->other_repositories.empty ());
assert (xpv->priority == priority::low);
- assert (xpv->changes.empty ());
+ assert (!xpv->changes);
assert (xpv->license_alternatives.size () == 1);
assert (xpv->license_alternatives[0].size () == 1);
@@ -724,7 +727,19 @@ test_pkg_repos (const cstrings& loader_args,
labels ({"math library", "math API", "libbaz fork"}));
assert (fpv5->keywords == labels ({"c++", "foo", "math", "best"}));
- assert (*fpv5->description ==
+ assert (fpv5->description->text ==
+ "A modern C++ library with easy to use linear algebra and lot "
+ "of optimization\ntools.\n\nThere are over 100 functions in "
+ "total with an extensive test suite. The API is\nsimilar to "
+ "~~mathlab~~ **MATLAB**.[^mathlab]\n\nUseful for conversion of "
+ "research code into production environments.\n"
+ "[^mathlab]: MATLAB Capabilities: TODO");
+
+ assert (fpv5->description->type == text_type::github_mark);
+
+ assert (fpv5->package_description->text ==
+ "This project builds and defines the build2 package for the "
+ "libfoo library.\n\n"
"A modern C++ library with easy to use linear algebra and lot "
"of optimization\ntools.\n\nThere are over 100 functions in "
"total with an extensive test suite. The API is\nsimilar to "
@@ -732,6 +747,8 @@ test_pkg_repos (const cstrings& loader_args,
"research code into production environments.\n"
"[^mathlab]: MATLAB Capabilities: TODO");
+ assert (fpv5->package_description->type == text_type::github_mark);
+
assert (fpv5->url && fpv5->url->string () == "http://www.example.com/foo/");
assert (fpv5->doc_url && fpv5->doc_url->string () ==
@@ -756,14 +773,16 @@ test_pkg_repos (const cstrings& loader_args,
assert (fpv5->priority.comment ==
"Critical bug fixes, performance improvement.");
- const char ch[] = R"DLM(1.2.4+1
+ const char ch[] = R"DLM(**1.2.4+1**
* applied patch for critical bug-219
* regenerated documentation
-1.2.4
+**1.2.4**
* test suite extended significantly)DLM";
- assert (fpv5->changes == ch);
+ assert (fpv5->changes &&
+ fpv5->changes->text == ch &&
+ fpv5->changes->type == text_type::github_mark);
assert (fpv5->license_alternatives.size () == 2);
assert (fpv5->license_alternatives[0].comment ==
@@ -843,7 +862,7 @@ test_pkg_repos (const cstrings& loader_args,
assert (check_location (fpv5));
assert (fpv5->sha256sum && *fpv5->sha256sum ==
- "fe07978d72ab65c2ad72b0325aa56944cf093248d39edcb472a2fe5835defa3d");
+ "072386bc75b026889d2992374609a2b4fa18ee59c00f664d5bb21fb86a090671");
assert (fpv5->buildable);
@@ -859,7 +878,7 @@ test_pkg_repos (const cstrings& loader_args,
assert (epv->project == "mathLab");
assert (epv->summary == "The exponent");
assert (epv->keywords == labels ({"mathlab", "c++", "exponent"}));
- assert (epv->description && *epv->description ==
+ assert (epv->description && epv->description->text ==
"The exponent math function.");
assert (epv->url && epv->url->string () == "http://exp.example.com");
assert (!epv->package_url);
@@ -870,7 +889,7 @@ test_pkg_repos (const cstrings& loader_args,
assert (epv->internal_repository.load () == mr);
assert (epv->other_repositories.empty ());
assert (epv->priority == priority (priority::low));
- assert (epv->changes.empty ());
+ assert (!epv->changes);
assert (epv->license_alternatives.size () == 1);
assert (epv->license_alternatives[0].size () == 1);
diff --git a/www/package-version-details-body.css b/www/package-version-details-body.css
index 7ef4486..1c41ed5 100644
--- a/www/package-version-details-body.css
+++ b/www/package-version-details-body.css
@@ -378,13 +378,51 @@ h1, h2, h3
.build .abnormal {color: #ff0000;}
/*
- * Changes.
+ * Changes (plain text).
*
* This is a <pre> block that fits lines up to 80 characters long and
* wraps longer ones.
*/
-#changes
+#changes.plain pre
{
font-size: 0.85em;
- margin: .5em 0 .5em 0;
}
+
+/*
+ * Changes (Markdown).
+ *
+ * These are descendants of the <div> block containing the result of
+ * Markdown-to-HTML translation.
+ *
+ * Note that the Markdown code blocks are translated into the
+ * <pre><code>...<code/></pre> element construct.
+ */
+#changes.markdown h1,
+#changes.markdown h2
+{
+ white-space: normal;
+}
+
+/* code-box.css */
+#changes.markdown :not(pre) > code
+{
+ background-color: rgba(0, 0, 0, 0.05);
+ border-radius: 0.2em;
+ padding: .2em .32em .18em .32em;
+}
+
+/* pre-box.css */
+#changes.markdown pre
+{
+ background-color: rgba(0, 0, 0, 0.05);
+ border-radius: 0.2em;
+ padding: .8em .4em .8em .4em;
+ margin: 2em -.4em 2em -.4em; /* Use paddings of #content. */
+}
+
+#changes.markdown pre > code
+{
+ font-size: inherit;
+}
+
+#changes.markdown .error {color: #ff0000;}