Compare commits

...

18 commits

Author SHA1 Message Date
Jacob 0e42e80f92 Define aliases for certain types globally instead of in classes, and expand it to other ones, such as std::string. Primarily useful for testing. 2024-08-23 17:26:23 +02:00
Jacob 33f793d395 Include algorithm header in docpp.cpp
This change is apparently necessary for any_of and all_of to function on at least Windows and Linux.
2024-08-23 14:21:36 +02:00
Jacob dfc99c1854 This commit makes many breaking changes to the library. They're far too many to list, but all of them are syntactical - no major behavior will be altered with this commit. However, C++17 is now required in order to make use of docpp. It will **no longer build** with a C++11 or C++14 compiler. Thus, please update your projects to make use of C++17, or stick with the last commit. 2024-08-23 14:11:46 +02:00
Jacob 9172b69a36 Fix linking on macOS. God this operating system is a pain to use sometimes. 2024-07-22 02:27:12 +02:00
Jacob 9479ff7834 Add methods, allowing you to get elements from a section by reference
and make changes to them.
2024-06-18 04:04:37 +02:00
Jacob c29d29d592 Some minor changes to constructors, fix Tag::Style 2024-06-17 22:44:09 +02:00
Jacob d9f24ecd53 Remove some more useless methods and overloaded operators. 2024-06-17 21:16:00 +02:00
Jacob 71ceaa517c Simplify HTML::Properties class 2024-06-17 21:08:50 +02:00
Jacob 8dc3c47f12 Version bump: 0.1.0 2024-06-08 01:15:03 +02:00
Jacob 5da029f533 Add std::string and Tag index for Section operator[]. 2024-06-08 01:11:38 +02:00
Jacob d072eb1536 Remove instances of return std::move() 2024-06-05 21:06:43 +02:00
Jacob d13c2d02fe Implement docpp::version() function, which returns the library version. 2024-05-30 15:56:38 +02:00
Jacob 9d30189d31 Add Non_Opened to Type enum. It can be used if you want an element that
is only closed.
2024-05-25 21:48:13 +02:00
Jacob 2067aaace3 Remove inline qualifier from namespaces. 2024-05-23 20:07:12 +02:00
Jacob 8adb6575a1 Add tests for CSS, add some missing methods. 2024-05-21 20:06:04 +02:00
Jacob f416639461 Oops, wrong file name. 2024-05-20 01:53:34 +02:00
Jacob 65491ee2ac Add CONTRIBUTIONS.md file, with guidelines for contributors. 2024-05-20 01:52:01 +02:00
Jacob 14cd8c4122 Remove/replace some "C with classes" junk. The C++ core guidelines state
that you must not use ALL_CAPS for enum members. enum class is now used
as well, to further reinforce the idea that this is a C++ library. While
neither of these changes are necessary, it leads to a better and more
intuitive API design.

More operator overloading has also been added for many of the classes,
particularly the [] index operator, which can now be used in place of
the at() method. More methods have also been added, particularly for
Section and Document.

Some methods have also been fixed, or have had their behavior altered
slightly, but this should now be covered under the new tests, which have
also been (for the most part) rewritten, both because they were
previously both primitive and rather ugly and because new functionality
was added.

Examples have also been updated to reflect the changes made in this
commit, so that they build successfully.

Of course, these changes mean that the new API is incompatible with any
applications written with the 0.0.1 version. Hopefully most of these
changes are dealt with before the 1.0 release, because I would prefer
not making API-breaking changes by that point.
2024-05-20 01:32:49 +02:00
10 changed files with 3543 additions and 1213 deletions

View file

@ -1,12 +1,18 @@
# docpp CMakeLists.txt
cmake_minimum_required(VERSION 3.1...3.29)
project(docpp VERSION 0.0.1
project(docpp VERSION 0.1.0
DESCRIPTION "C++ library for generating XML, HTML and CSS."
HOMEPAGE_URL "https://speedie.site/docpp"
LANGUAGES CXX
)
option(GENERATE_PKGBUILD "Generate PKGBUILD" OFF)
option(GENERATE_EBUILD "Generate ebuild" OFF)
option(BUILD_TARBALL "Build tarball" OFF)
add_compile_definitions(DOCPP_VERSION="${PROJECT_VERSION}")
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
@ -18,7 +24,11 @@ if (MSVC AND CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
endif()
set(CMAKE_CXX_STANDARD 11)
if (APPLE)
set(INSTALL_RPATH_USE_LINK_PATH ON)
endif()
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

9
CONTRIBUTING.md Normal file
View file

@ -0,0 +1,9 @@
# Contribution notes
This project is primarily hosted [here](https://git.speedie.site/speedie/docpp). It is also mirrored to GitHub,
[here](https://github.com/speedie1337/docpp), both for visibility and for CI purposes. You may file issues and
pull requests on both platforms. Commits made on GitHub *may* be squashed into a single commit and merged into
the main repository on the primary host. If you do not want your commits squashed, please make them on the primary
host. You still retain authorship of your commits.
Happy hacking!

View file

@ -2,7 +2,7 @@
![action](https://github.com/speediegq/docpp/actions/workflows/cmake-multi-platform.yml/badge.svg)
C++11 library for generating HTML, CSS and SGML-like documents.
C++17 library for generating HTML, CSS and SGML-like documents.
## Features
@ -44,6 +44,10 @@ If you use Gentoo Linux, you can specify -DGENERATE_EBUILD=ON to generate an ebu
Just include docpp.hpp in your project and link against the library. Examples can be found in the examples directory.
## Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute to this project.
## License
This project is licensed under the GNU Lesser General Public License v3.0 - see the [LICENSE](LICENSE) file for details.

View file

@ -48,7 +48,7 @@ PROJECT_NAME = docpp
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = 0.0.1
PROJECT_NUMBER = 0.1.0
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a

View file

@ -11,7 +11,7 @@
#include <docpp/docpp.hpp>
int main() {
docpp::HTML::Section html(docpp::HTML::ELEMENT_HTML, {});
docpp::HTML::Section html(docpp::HTML::Tag::Html, {});
html.push_back({"title", {}, "Google"});
@ -30,9 +30,9 @@ int main() {
}},
}};
html.push_back({"style", {}, sheet.get(docpp::CSS::FORMATTING_PRETTY)});
html.push_back({"style", {}, sheet.get(docpp::CSS::Formatting::Pretty)});
docpp::HTML::Section div{docpp::HTML::ELEMENT_DIV, {docpp::HTML::Property("class", "center")}};
docpp::HTML::Section div{docpp::HTML::Tag::Div, {docpp::HTML::Property("class", "center")}};
div.push_back({"font", {docpp::HTML::Property("color", "blue")}, "G"});
div.push_back({"font", {docpp::HTML::Property("color", "red")}, "o"});
@ -43,11 +43,11 @@ int main() {
html.push_back(div);
docpp::HTML::Section div2{docpp::HTML::ELEMENT_DIV, {docpp::HTML::Property("align", "center")}};
docpp::HTML::Section div2{docpp::HTML::Tag::Div, {docpp::HTML::Property("align", "center")}};
docpp::HTML::Section form{"form", {{docpp::HTML::Property("action", "https://google.com/search"), docpp::HTML::Property("method", "get")}}};
form.push_back({"input", docpp::HTML::Properties({docpp::HTML::Property("type", "text"), docpp::HTML::Property("name", "q")}), "", docpp::HTML::TYPE_SELF_CLOSING});
form.push_back({"input", docpp::HTML::Properties({docpp::HTML::Property("type", "submit"), docpp::HTML::Property("value", "Search!")}), "", docpp::HTML::TYPE_SELF_CLOSING});
form.push_back({"input", docpp::HTML::Properties({docpp::HTML::Property("type", "text"), docpp::HTML::Property("name", "q")}), "", docpp::HTML::Type::Self_Closing});
form.push_back({"input", docpp::HTML::Properties({docpp::HTML::Property("type", "submit"), docpp::HTML::Property("value", "Search!")}), "", docpp::HTML::Type::Self_Closing});
div2.push_back(form);
html.push_back(div2);
@ -56,7 +56,7 @@ int main() {
std::ofstream file("biteme.lol.html");
file << doc.get(docpp::HTML::FORMATTING_PRETTY);
file << doc.get(docpp::HTML::Formatting::Pretty);
file.close();

View file

@ -19,7 +19,7 @@ int main() {
docpp::HTML::Document doc{};
/* This is an HTML section. It can hold any number of elements and/or sections.
* The first argument is the type of section, and this can either be a predefined value (e.g., docpp::HTML::ELEMENT_HTML) or a
* The first argument is the type of section, and this can either be a predefined value (e.g., docpp::HTML::Tag::Html) or a
* custom value in the form of an std::string object.
*
* The second argument is an HTMLProperties object, which is a collection of Property objects. Each property is a std::pair of an
@ -32,10 +32,10 @@ int main() {
*
* To get the section as an std::string object, call section.get().
*/
docpp::HTML::Section htmlSection(docpp::HTML::ELEMENT_HTML, {}); // <html></html>
docpp::HTML::Section headSection(docpp::HTML::ELEMENT_HEAD, {}); // <head></head>
docpp::HTML::Section bodySection(docpp::HTML::ELEMENT_BODY, {}); // <body></body>
docpp::HTML::Section footerSection(docpp::HTML::ELEMENT_FOOTER, {}); // <footer></footer>
docpp::HTML::Section htmlSection(docpp::HTML::Tag::Html, {}); // <html></html>
docpp::HTML::Section headSection(docpp::HTML::Tag::Head, {}); // <head></head>
docpp::HTML::Section bodySection(docpp::HTML::Tag::Body, {}); // <body></body>
docpp::HTML::Section footerSection(docpp::HTML::Tag::Footer, {}); // <footer></footer>
/* This is an HTML element. Unlike a section, an element cannot hold any other elements or sections, rather it holds text and/or attributes.
* The first argument is the type of element, and this should simply be the tag name (e.g., "p", "h1", "a", etc.).
@ -48,7 +48,7 @@ int main() {
*
* The fourth argument is an integer representing the closing tag type. This can be one of the following:
*
* - docpp::HTML::TYPE_NON_CLOSED: No closing tag will be appended.
* - docpp::HTML::Type::Non_Closed: No closing tag will be appended.
* Example: <img src="example.jpg">
* - docpp::HTML::TYPE_NON_SELF_CLOSING: A closing tag will be appended.
* Example: <p>Hello world</p>
@ -61,7 +61,7 @@ int main() {
/* Add the title and meta elements to the head section. */
headSection.push_back(titleElement);
headSection.push_back(docpp::HTML::Element("meta", {{docpp::HTML::Property("name", "description"), docpp::HTML::Property("content", "Hello world document description!")}}, "", docpp::HTML::TYPE_NON_CLOSED));
headSection.push_back(docpp::HTML::Element("meta", {{docpp::HTML::Property("name", "description"), docpp::HTML::Property("content", "Hello world document description!")}}, "", docpp::HTML::Type::Non_Closed));
/* This is a CSS document. It is essentially the CSS equivalent of an HTML section.
* It is essentially a collection of Element objects, which is a collection of Property objects.
@ -84,14 +84,14 @@ int main() {
stylesheet.push_back(bodyStyling);
/* To get the stylesheet as an std::string object, call stylesheet.get(). It can then be used in an Element object. */
const std::string& css = stylesheet.get(docpp::CSS::FORMATTING_PRETTY); // body { background-color: black; color: white; }
const std::string& css = stylesheet.get(docpp::CSS::Formatting::Pretty); // body { background-color: black; color: white; }
headSection.push_back(docpp::HTML::Element("style", {}, css)); // <style>body { background-color: black; color: white; }</style>
/* Add a paragraph element to the footer section. */
footerSection.push_back(docpp::HTML::Element("p", {}, "This is the footer.")); // <p>This is the footer.</p>
docpp::HTML::Section divSection(docpp::HTML::ELEMENT_DIV, {{docpp::HTML::Property("id", "main")}}); // <div id="main"></div>
docpp::HTML::Section divSection(docpp::HTML::Tag::Div, {{docpp::HTML::Property("id", "main")}}); // <div id="main"></div>
/* Add a header element and a paragraph element to the div section. */
divSection.push_back(docpp::HTML::Element("h1", {}, "Hello world!")); // <h1>Hello world!</h1>
@ -113,10 +113,10 @@ int main() {
/* Finally, let's output the document to a file and print it to standard output. */
std::ofstream file("hello-world.html");
/* Optionally, you can use the get() method with the docpp::HTML::FORMATTING_PRETTY argument to get a *slightly* more readable document.
/* Optionally, you can use the get() method with the docpp::HTML::Formatting::Pretty argument to get a *slightly* more readable document.
* The same goes for the CSS document. Or, you can use docpp::HTML::FORMATTING_NEWLINE to get a document with elements separated by newlines.
*/
file << doc.get(docpp::HTML::FORMATTING_PRETTY);
file << doc.get(docpp::HTML::Formatting::Pretty);
file.close();

View file

@ -3,7 +3,7 @@
#include <docpp/docpp.hpp>
docpp::HTML::Section getCSS() {
docpp::HTML::Section css{docpp::HTML::ELEMENT_STYLE};
docpp::HTML::Section css{docpp::HTML::Tag::Style};
docpp::CSS::Stylesheet stylesheet{};
@ -180,20 +180,20 @@ docpp::HTML::Section getCSS() {
}
});
css.push_back({docpp::HTML::ELEMENT_EMPTY_NO_FORMAT, {}, stylesheet.get<std::string>(docpp::CSS::FORMATTING_PRETTY, 4)});
css.push_back({docpp::HTML::Tag::Empty_No_Formatting, {}, stylesheet.get<std::string>(docpp::CSS::Formatting::Pretty, 4)});
return css;
}
docpp::HTML::Section getNavbar(docpp::HTML::Section& e) {
docpp::HTML::Section navbar(docpp::HTML::ELEMENT_DIV, {{docpp::HTML::Property{{"class", "navbar"}}}});
docpp::HTML::Section span(docpp::HTML::ELEMENT_SPAN, {});
docpp::HTML::Section navbar(docpp::HTML::Tag::Div, {{docpp::HTML::Property{"class", "navbar"}}});
docpp::HTML::Section span(docpp::HTML::Tag::Span, {});
span.push_back({docpp::HTML::ELEMENT_EMPTY, {}, "speedie.site\n"});
span.push_back({docpp::HTML::Tag::Empty, {}, "speedie.site\n"});
const auto append_to_span = [&](const std::string& img, const std::string& url, const std::string& text) {
span.push_back({docpp::HTML::ELEMENT_IMG, {{docpp::HTML::Property{{"src", img}}, docpp::HTML::Property{{"width", "16"}}, docpp::HTML::Property{{"height", "16"}}}}, ""});
span.push_back({docpp::HTML::ELEMENT_A, {{docpp::HTML::Property{{"href", url}}}}, text});
span.push_back({docpp::HTML::Tag::Img, {{docpp::HTML::Property{"src", img}, docpp::HTML::Property{"width", "16"}, docpp::HTML::Property{"height", "16"}}}, ""});
span.push_back({docpp::HTML::Tag::A, {{docpp::HTML::Property{"href", url}}}, text});
};
append_to_span("img/home.png", "/", "Home");
@ -208,15 +208,15 @@ docpp::HTML::Section getNavbar(docpp::HTML::Section& e) {
}
docpp::HTML::Section getHead() {
docpp::HTML::Section e{docpp::HTML::ELEMENT_HEAD};
docpp::HTML::Section e{docpp::HTML::Tag::Head};
docpp::HTML::Element content_type{docpp::HTML::ELEMENT_META, {{docpp::HTML::Property{{"http-equiv", "content-type"}}, docpp::HTML::Property{{"content", "text/html; charset=utf-8"}}}}};
docpp::HTML::Element charset{docpp::HTML::ELEMENT_META, {{docpp::HTML::Property{{"charset", "UTF-8"}}}}};
docpp::HTML::Element favicon(docpp::HTML::ELEMENT_LINK, {{docpp::HTML::Property{{"rel", "icon"}}, docpp::HTML::Property{{"type", "image/x-icon"}}, docpp::HTML::Property{{"href", "/img/favicon.svg"}}}});
docpp::HTML::Element description(docpp::HTML::ELEMENT_META, {{docpp::HTML::Property{{"name", "description"}}, docpp::HTML::Property{{"content", "Welcome to my personal website."}}}});
docpp::HTML::Element author(docpp::HTML::ELEMENT_META, {{docpp::HTML::Property{{"name", "author"}}, docpp::HTML::Property{{"content", "speedie"}}}});
docpp::HTML::Element title(docpp::HTML::ELEMENT_TITLE, {}, "speedie's site");
docpp::HTML::Section css{docpp::HTML::ELEMENT_STYLE};
docpp::HTML::Element content_type{docpp::HTML::Tag::Meta, {{docpp::HTML::Property{"http-equiv", "content-type"}, docpp::HTML::Property{"content", "text/html; charset=utf-8"}}}};
docpp::HTML::Element charset{docpp::HTML::Tag::Meta, {{docpp::HTML::Property{"charset", "UTF-8"}}}};
docpp::HTML::Element favicon(docpp::HTML::Tag::Link, {{docpp::HTML::Property{"rel", "icon"}, docpp::HTML::Property{"type", "image/x-icon"}, docpp::HTML::Property{"href", "/img/favicon.svg"}}});
docpp::HTML::Element description(docpp::HTML::Tag::Meta, {{docpp::HTML::Property{"name", "description"}, docpp::HTML::Property{"content", "Welcome to my personal website."}}});
docpp::HTML::Element author(docpp::HTML::Tag::Meta, {{docpp::HTML::Property{"name", "author"}, docpp::HTML::Property{"content", "speedie"}}});
docpp::HTML::Element title(docpp::HTML::Tag::Title, {}, "speedie's site");
docpp::HTML::Section css{docpp::HTML::Tag::Style};
e.push_back(content_type);
e.push_back(favicon);
@ -229,23 +229,23 @@ docpp::HTML::Section getHead() {
}
docpp::HTML::Section getMain() {
docpp::HTML::Section content(docpp::HTML::ELEMENT_DIV, {{docpp::HTML::Property{{"class", "content"}}}});
docpp::HTML::Section content(docpp::HTML::Tag::Div, {{docpp::HTML::Property{"class", "content"}}});
content.push_back({docpp::HTML::ELEMENT_H2, {}, "Hello world!"});
content.push_back({docpp::HTML::ELEMENT_P, {}, "Hello there! This is a replica of my old website, using docpp to generate the HTML. With that said. This only provides the index page, so many links are not functional. This is more to show off that docpp can be used to generate a proper website."});
content.push_back({docpp::HTML::ELEMENT_H3, {}, "Links"});
content.push_back({docpp::HTML::Tag::H2, {}, "Hello world!"});
content.push_back({docpp::HTML::Tag::P, {}, "Hello there! This is a replica of my old website, using docpp to generate the HTML. With that said. This only provides the index page, so many links are not functional. This is more to show off that docpp can be used to generate a proper website."});
content.push_back({docpp::HTML::Tag::H3, {}, "Links"});
docpp::HTML::Section links(docpp::HTML::ELEMENT_DIV, {{docpp::HTML::Property{{"class", "links"}}}});
docpp::HTML::Section table(docpp::HTML::ELEMENT_TABLE);
docpp::HTML::Section links(docpp::HTML::Tag::Div, {{docpp::HTML::Property{"class", "links"}}});
docpp::HTML::Section table(docpp::HTML::Tag::Table);
static const auto append_to_table = [&](const std::string& img, const std::string& url, const std::string& short_text, const std::string& long_text) {
docpp::HTML::Section tr{docpp::HTML::ELEMENT_TR};
docpp::HTML::Section td{docpp::HTML::ELEMENT_TD};
docpp::HTML::Section td2{docpp::HTML::ELEMENT_TD};
docpp::HTML::Section tr{docpp::HTML::Tag::Tr};
docpp::HTML::Section td{docpp::HTML::Tag::Td};
docpp::HTML::Section td2{docpp::HTML::Tag::Td};
td.push_back({docpp::HTML::ELEMENT_IMG, {{docpp::HTML::Property{{"src", img}}, docpp::HTML::Property{{"width", "16"}}, docpp::HTML::Property{{"height", "16"}}}}, ""});
td.push_back({docpp::HTML::ELEMENT_A, {{docpp::HTML::Property{{"href", url}}}}, short_text});
td2.push_back({docpp::HTML::ELEMENT_EMPTY, {}, long_text + "\n"});
td.push_back({docpp::HTML::Tag::Img, {{docpp::HTML::Property{"src", img}, docpp::HTML::Property{"width", "16"}, docpp::HTML::Property{"height", "16"}}}, ""});
td.push_back({docpp::HTML::Tag::A, {{docpp::HTML::Property{"href", url}}}, short_text});
td2.push_back({docpp::HTML::Tag::Empty, {}, long_text + "\n"});
tr.push_back(td);
tr.push_back(td2);
@ -265,25 +265,25 @@ docpp::HTML::Section getMain() {
}
docpp::HTML::Section getFooter() {
docpp::HTML::Section footer(docpp::HTML::ELEMENT_FOOTER);
docpp::HTML::Section div(docpp::HTML::ELEMENT_DIV, {{docpp::HTML::Property("class", "column")}});
docpp::HTML::Section span(docpp::HTML::ELEMENT_SPAN, {{docpp::HTML::Property("class", "links")}});
docpp::HTML::Section footer(docpp::HTML::Tag::Footer);
docpp::HTML::Section div(docpp::HTML::Tag::Div, {{docpp::HTML::Property("class", "column")}});
docpp::HTML::Section span(docpp::HTML::Tag::Span, {{docpp::HTML::Property("class", "links")}});
span.push_back({docpp::HTML::ELEMENT_A, {{docpp::HTML::Property("class", "links"), docpp::HTML::Property("href", "https://git.speedie.site")}}, "Git"});
span.push_back({docpp::HTML::ELEMENT_A, {{docpp::HTML::Property("class", "links"), docpp::HTML::Property("href", "https://ls.speedie.site")}}, "Downloads"});
span.push_back({docpp::HTML::ELEMENT_A, {{docpp::HTML::Property("class", "links"), docpp::HTML::Property("href", "privacy.html")}}, "Licensing"});
span.push_back({docpp::HTML::Tag::A, {{docpp::HTML::Property("class", "links"), docpp::HTML::Property("href", "https://git.speedie.site")}}, "Git"});
span.push_back({docpp::HTML::Tag::A, {{docpp::HTML::Property("class", "links"), docpp::HTML::Property("href", "https://ls.speedie.site")}}, "Downloads"});
span.push_back({docpp::HTML::Tag::A, {{docpp::HTML::Property("class", "links"), docpp::HTML::Property("href", "privacy.html")}}, "Licensing"});
div.push_back(span);
div.push_back({docpp::HTML::ELEMENT_P, {{docpp::HTML::Property("style", "padding-top: 0px;")}}, "Made in Sweden"});
div.push_back({docpp::HTML::Tag::P, {{docpp::HTML::Property("style", "padding-top: 0px;")}}, "Made in Sweden"});
footer.push_back(div);
return footer;
}
int main() {
docpp::HTML::Section html_section = docpp::HTML::Section(docpp::HTML::ELEMENT_HTML);
docpp::HTML::Section html_section = docpp::HTML::Section(docpp::HTML::Tag::Html);
docpp::HTML::Section head{getHead()};
docpp::HTML::Section body(docpp::HTML::ELEMENT_BODY);
docpp::HTML::Section body(docpp::HTML::Tag::Body);
body.push_back(getMain());
@ -295,8 +295,8 @@ int main() {
docpp::HTML::Document html_doc(html_section);
std::cout << html_doc.get<std::string>(docpp::HTML::FORMATTING_PRETTY) << "\n";
std::cout << html_doc.get<std::string>(docpp::HTML::Formatting::Pretty) << "\n";
std::ofstream fs{"speedie-page.html"};
fs << html_doc.get<std::string>(docpp::HTML::FORMATTING_PRETTY);
fs << html_doc.get<std::string>(docpp::HTML::Formatting::Pretty);
fs.close();
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff