2024-05-07 21:21:58 +02:00
/**
* @ file hello - world . cpp
* @ brief A simple Hello World program , demonstrating the use of docpp .
* @ details This program creates a simple HTML document with a title , a meta description , a body with a div containing a header and a paragraph , and a footer with a paragraph . It also includes a CSS stylesheet that sets the background color of the body to black and the text color to white . It then writes the document to a file called hello - world . html .
* @ license LGPL - 3.0
*
* g + + - std = c + + 11 hello - world . cpp - o hello - world - ldocpp
*/
2024-05-05 23:31:42 +02:00
# include <fstream>
# include <docpp/docpp.hpp>
int main ( ) {
/* This is your root document. It can hold *one* HTML section, and that section can hold any number of elements and/or sections.
* By default , the root document will prepend a doctype declaration . If you don ' t want that ( e . g . , if you ' re writing XML ) , you can
2024-05-13 12:00:47 +02:00
* use docpp : : HTML : : Document : : set_doctype ( ) to set the doctype to your preferred value .
2024-05-05 23:31:42 +02:00
*
* To get the document as an std : : string object , call doc . get ( ) .
*/
2024-05-12 20:18:06 +02:00
docpp : : HTML : : Document doc { } ;
2024-05-05 23:31:42 +02:00
/* This is an HTML section. It can hold any number of elements and/or sections.
2024-05-15 10:21:39 +02:00
* The first argument is the type of section , and this can either be a predefined value ( e . g . , docpp : : HTML : : ELEMENT_HTML ) or a
2024-05-05 23:31:42 +02:00
* custom value in the form of an std : : string object .
*
2024-05-12 20:18:06 +02:00
* The second argument is an HTMLProperties object , which is a collection of Property objects . Each property is a std : : pair of an
* attribute name and an attribute value . If you don ' t want to specify any attributes , you can pass an empty ElementAttributes object .
2024-05-05 23:31:42 +02:00
* If you need to change the tag and / or attributes later , you can use the set ( ) method .
*
* Note that it is very important that you do not append a section or element to a section until you have finished its construction ,
* because push_back ( ) makes a copy of the object you pass to it . If you need to make changes later , you can use methods such as find ( ) and swap ( ) ,
2024-05-13 00:57:27 +02:00
* or construct a new object . An alternative is to append using the + = operator , which does the same thing as push_back ( ) .
2024-05-05 23:31:42 +02:00
*
* To get the section as an std : : string object , call section . get ( ) .
*/
2024-05-15 10:21:39 +02:00
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>
2024-05-05 23:31:42 +02:00
/* 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 . ) .
*
2024-05-12 20:18:06 +02:00
* The second argument is an HTMLProperties object , which is a collection of Property objects . Each property is a std : : pair of an
* attribute name and an attribute value . If you don ' t want to specify any attributes , you can pass an empty ElementAttributes object .
2024-05-05 23:31:42 +02:00
* If you need to change the element ' s tag , attributes , type or text later , you can use the set ( ) method .
*
* The third argument is the text content of the element . If you don ' t want to specify any text , you can pass an empty std : : string object .
*
* 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 .
* Example : < img src = " example.jpg " >
* - docpp : : HTML : : TYPE_NON_SELF_CLOSING : A closing tag will be appended .
* Example : < p > Hello world < / p >
* - docpp : : HTML : : TYPE_SELF_CLOSING : A self - closing tag will be appended .
* Example : < img src = " example.jpg " >
*
* To get the element as an std : : string object , call element . get ( ) .
*/
2024-05-12 20:18:06 +02:00
docpp : : HTML : : Element titleElement ( " title " , { } , " Hello world document " ) ; // <title>Hello world document</title>
2024-05-05 23:31:42 +02:00
/* Add the title and meta elements to the head section. */
headSection . push_back ( titleElement ) ;
2024-05-12 20:18:06 +02:00
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 ) ) ;
2024-05-05 23:31:42 +02:00
/* This is a CSS document. It is essentially the CSS equivalent of an HTML section.
2024-05-12 20:18:06 +02:00
* It is essentially a collection of Element objects , which is a collection of Property objects .
2024-05-05 23:31:42 +02:00
*
* In other words , a CSS document is a collection of CSS elements , which are collections of CSS properties .
*/
2024-05-12 20:18:06 +02:00
docpp : : CSS : : Stylesheet stylesheet { } ;
2024-05-05 23:31:42 +02:00
/* This is a CSS element. It is essentially a collection of CSS properties.
* The first argument is the type of element , and this should simply be the tag name ( e . g . , " body " , " p " , " h1 " , etc . ) .
*
2024-05-12 20:18:06 +02:00
* The second argument is a CSSProperties object , which is a collection of Property objects . Each property is a std : : pair of a
2024-05-05 23:31:42 +02:00
* property name and a property value . If you don ' t want to specify any properties , you can pass an empty CSSProperties object , but . . . of course , that ' s not very useful .
*
* To get the element as an std : : string object , call element . get ( ) .
*/
2024-05-12 20:18:06 +02:00
docpp : : CSS : : Element bodyStyling ( " body " , { { docpp : : CSS : : Property ( " background-color " , " black " ) , docpp : : CSS : : Property ( " color " , " white " ) } } ) ; // body { background-color: black; color: white; }
2024-05-05 23:31:42 +02:00
/* Now, let's add the body style to the stylesheet. */
stylesheet . push_back ( bodyStyling ) ;
2024-05-12 20:18:06 +02:00
/* To get the stylesheet as an std::string object, call stylesheet.get(). It can then be used in an Element object. */
2024-05-07 21:21:58 +02:00
const std : : string & css = stylesheet . get ( docpp : : CSS : : FORMATTING_PRETTY ) ; // body { background-color: black; color: white; }
2024-05-05 23:31:42 +02:00
2024-05-12 20:18:06 +02:00
headSection . push_back ( docpp : : HTML : : Element ( " style " , { } , css ) ) ; // <style>body { background-color: black; color: white; }</style>
2024-05-05 23:31:42 +02:00
2024-05-07 17:26:11 +02:00
/* Add a paragraph element to the footer section. */
2024-05-12 20:18:06 +02:00
footerSection . push_back ( docpp : : HTML : : Element ( " p " , { } , " This is the footer. " ) ) ; // <p>This is the footer.</p>
2024-05-05 23:31:42 +02:00
2024-05-15 10:21:39 +02:00
docpp : : HTML : : Section divSection ( docpp : : HTML : : ELEMENT_DIV , { { docpp : : HTML : : Property ( " id " , " main " ) } } ) ; // <div id="main"></div>
2024-05-07 17:26:11 +02:00
/* Add a header element and a paragraph element to the div section. */
2024-05-12 20:18:06 +02:00
divSection . push_back ( docpp : : HTML : : Element ( " h1 " , { } , " Hello world! " ) ) ; // <h1>Hello world!</h1>
divSection . push_back ( docpp : : HTML : : Element ( " p " , { } , " This is a paragraph. " ) ) ; // <p>This is a paragraph.</p>
2024-05-07 17:26:11 +02:00
/* Add the div section to the body section. */
bodySection . push_back ( divSection ) ;
2024-05-05 23:31:42 +02:00
/* Now, let's add the header, body and footer section to the html section.
* The order does matter , because an identifier is used internally . You can get this identifier by e . g . using find ( ) .
*/
htmlSection . push_back ( headSection ) ; // <html><head>...</head></html>
htmlSection . push_back ( bodySection ) ; // <html><head>...</head><body>...</body></html>
htmlSection . push_back ( footerSection ) ; // <html><head>...</head><body>...</body><footer>...</footer></html>
/* Now, let's add the html section to the document. */
doc . set ( htmlSection ) ;
/* 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.
2024-05-07 17:26:11 +02:00
* The same goes for the CSS document . Or , you can use docpp : : HTML : : FORMATTING_NEWLINE to get a document with elements separated by newlines .
2024-05-05 23:31:42 +02:00
*/
file < < doc . get ( docpp : : HTML : : FORMATTING_PRETTY ) ;
file . close ( ) ;
/* And we're done! */
return 0 ;
}