diff --git a/input.md b/input.md deleted file mode 100644 index cd608b8..0000000 --- a/input.md +++ /dev/null @@ -1,47 +0,0 @@ -hello `world` - - -This `is also a code block` - -hi `mom -hello` - -hi `mom - -this is too far` - - -*this is **words*** - -## **Hello world** - -### hello *world* - -# ***This is both!*** - -###### This is neither - -- Hello world -- This is a list - - -* this is also a list -* this is still a list - - -1. This list is ordered -2. This is **number two** - -- hello -world - -- hello - -world number two - -``` -int x = 5; -int y = 10; - -console.log(x + y); // '15' -``` diff --git a/lib/commandLineParser.cpp b/lib/commandLineParser.cpp index 779e90c..2a1c4fc 100644 --- a/lib/commandLineParser.cpp +++ b/lib/commandLineParser.cpp @@ -2,66 +2,68 @@ #include #include // for std::invalid_argument -//implement hashmap for the code -CLI::CLI(int argc, char** argv){ - try{ - if (arc < 2) { - throw std::invalid_argument("Error: No input file provided.\n - Usage: "); - } - //sets program info - programName = argv[0]; - inputFile = argv[1] +// implement hashmap for the code +CLI::CLI(int argc, char **argv) { + try { + if (argc < 2) { + throw std::invalid_argument( + "Error: No input file provided.\nUsage: "); + } + // sets program info + program_name = argv[0]; + input_file = argv[1]; - //checks that file has correct file extension - if(!(CLI::IsMarkupFile(inputFile))) { - throw std::invalid_argument("Error: Invalid file extension. Expected a '.md' (Markdown) file."); - } - //stores remaining arguments - for (int i = 1; i < argc; i++){ - args.push_back(argv[i]); - } - } - catch (const std::invalid_argument& e) { - std::cerr << e.what() << "\n"; - PrintHelp(); - std::exit(EXIT_FAILURE); + // checks that file has correct file extension + if (!(CLI::IsMarkupFile(input_file))) { + throw std::invalid_argument( + "Error: Invalid file extension. Expected a '.md' (Markdown) file."); } + // stores remaining arguments + for (int i = 1; i < argc; i++) { + args.push_back(argv[i]); } - -bool CLI::IsMarkupFile(const std::string& filename) { - //markdown file extension - const std::string requiredExtension = ".md"; - //checks to see if it can even include extension - if (filename.size() <= requiredExtension.size()) { - return false; - } - // Extracts the last N characters of the filename (where N is the length of the required extension) - // and checks if they match the required file extension (e.g., ".md"). - // - // Example: - // filename = "notes.md" - // requiredExtension = ".md" - // filename.substr(filename.size() - requiredExtension.size()) == ".md" → true - // - // Reference: https://en.cppreference.com/w/cpp/string/basic_string/substr - return filename.substr(filename.size() - requiredExtension.size()) == requiredExtension; + } catch (const std::invalid_argument &e) { + std::cerr << e.what() << "\n"; + PrintHelp(); + std::exit(EXIT_FAILURE); + } } - -//place to run commands but IDK IF WE SHOULD USE A HASMAP or how we are going to get each method to run -void CLI::RunCommands(){ - for (int i = 0; i < args.size(); i++){ - - } +bool CLI::IsMarkupFile(const std::string &filename) { + // markdown file extension + const std::string requiredExtension = ".md"; + // checks to see if it can even include extension + if (filename.size() <= requiredExtension.size()) { + return false; + } + // Extracts the last N characters of the filename (where N is the length of + // the required extension) and checks if they match the required file + // extension (e.g., ".md"). + // + // Example: + // filename = "notes.md" + // requiredExtension = ".md" + // filename.substr(filename.size() - requiredExtension.size()) == ".md" → + // true + // + // Reference: https://en.cppreference.com/w/cpp/string/basic_string/substr + return filename.substr(filename.size() - requiredExtension.size()) == + requiredExtension; } -void CLI::PrintHelp() const{ - std::cout << "Usage:\n" - << " " << programName << " REQUIRED\n" - << "Flags:\n" - << " --o, --output , optional output filename\n" - << " --w, --watch, enables watchdog\n" - << " --s, --stop, stops watchdog\n"; +// place to run commands but IDK IF WE SHOULD USE A HASMAP or how we are going +// to get each method to run +void CLI::RunCommands() { + for (size_t i = 0; i < args.size(); i++) { + } } +void CLI::PrintHelp() const { + std::cout << "Usage:\n" + << "\t" << program_name << " \n" + << "Flags:\n" + << "\t-o, --output , optional output filename\n" + << "\t-w, --watch, enables watchdog\n"; +} + +// ./parser input_file -w dhuahdakhk -o output diff --git a/lib/commandLineParser.h b/lib/commandLineParser.h index 88c9a09..55ad1fd 100644 --- a/lib/commandLineParser.h +++ b/lib/commandLineParser.h @@ -1,9 +1,9 @@ -/** +/** * @file commandLineParser.h * @brief Parses command line * @author Preston Shultz - * Sources: - * + * Sources: + * */ #ifndef COMMAND_LINE_PARSER_H @@ -17,64 +17,63 @@ * * Parse input arguments, sets input and output files * Lets user use commands with program - * + * * @author Preston Shultz (shultzp1@my.erau.edu) */ -class CLI{ +class CLI { public: - /** - * @brief Takes in argc and argv and converts it to vector - * - * CLI constructor - * - * @author Preston Shultz (shultzp1@my.erau.edu) - */ - CLI(int argc, char **argv); + /** + * @brief Takes in argc and argv and converts it to vector + * + * CLI constructor + * + * @author Preston Shultz (shultzp1@my.erau.edu) + */ + CLI(int argc, char **argv); - /** - * @brief Runs Commands - * - * @author Preston Shultz (shultzp1@my.erau.edu) - */ - void RunCommands(); + /** + * @brief Runs Commands + * + * @author Preston Shultz (shultzp1@my.erau.edu) + */ + void RunCommands(); - /** - * @brief Prints a list of commands that can be used - * - * @author Preston Shultz (shultzp1@my.erau.edu) - */ - void PrintHelp() const; + /** + * @brief Prints a list of commands that can be used + * + * @author Preston Shultz (shultzp1@my.erau.edu) + */ + void PrintHelp() const; - /** - * @brief Returns input file - * - * @author Preston Shultz (shultzp1@my.erau.edu) - */ - std::string GetInputFile() const {return inputFile;} + /** + * @brief Returns input file + * + * @author Preston Shultz (shultzp1@my.erau.edu) + */ + std::string GetInputFile() const { return input_file; } - /** - * @brief Returns output file - * - * @author Preston Shultz (shultzp1@my.erau.edu) - */ - std::string GetOutputFile() const {return outputFile;} + /** + * @brief Returns output file + * + * @author Preston Shultz (shultzp1@my.erau.edu) + */ + std::string GetOutputFile() const { return output_file; } private: + /** + * @brief Ensures the provided filename has a .markup extension + * + * @param filename The file name to validate + * @return true if file ends with .markup + * @return false otherwise + * @author Preston Shultz (shultzp1@my.erau.edu) + */ + static bool IsMarkupFile(const std::string &filename); - /** - * @brief Ensures the provided filename has a .markup extension - * - * @param filename The file name to validate - * @return true if file ends with .markup - * @return false otherwise - * @author Preston Shultz (shultzp1@my.erau.edu) - */ - static bool IsMarkupFile(const std::string& filename); - - std::string programName; - std::vector args; - std::string inputFile; - std::string outputFile; + std::string program_name; + std::vector args; + std::string input_file; + std::string output_file; }; -#endif \ No newline at end of file +#endif diff --git a/lib/documentConverter.h b/lib/documentConverter.h new file mode 100644 index 0000000..29ce2f4 --- /dev/null +++ b/lib/documentConverter.h @@ -0,0 +1,33 @@ +#ifndef DOCUMENT_CONVERTER_H +#define DOCUMENT_CONVERTER_H + +#include "parser.h" +#include "watchdog.h" +#include + +class DocumentConverter { +private: + Parser parser; + Watchdog watchdog; + +public: + DocumentConverter(std::string input, std::string output = "") + : parser(input, output), watchdog(input) {}; + + void Convert() { + this->parser.ParseDocument(); + this->parser.WriteOutput(); + } + + void ConvertWatcher() { + // This is a lambda, which can be passed into the start function of + // watchdog. + std::function callback = [this]() { + this->parser.ParseDocument(); + this->parser.WriteOutput(); + }; + this->watchdog.Start(callback); + } +}; + +#endif diff --git a/lib/fileSystem.cpp b/lib/fileSystem.cpp index 3742b7a..87f2ebe 100644 --- a/lib/fileSystem.cpp +++ b/lib/fileSystem.cpp @@ -2,6 +2,7 @@ #include "util.h" #include +#include #include #include #include diff --git a/lib/parser.cpp b/lib/parser.cpp index f01c505..32f5deb 100644 --- a/lib/parser.cpp +++ b/lib/parser.cpp @@ -12,7 +12,8 @@ using std::string; using std::vector; void Parser::Inspect() { - std::cerr << "Parser::Inspect() is not yet implemented." << std::endl; + std::cout << this->position << std::endl; + std::cout << this->content.size() << std::endl; } void Parser::NormalizeInputStream() { @@ -41,6 +42,9 @@ void Parser::WriteOutput() { } void Parser::ParseDocument() { + // NOTE:This needs to be set so the parsing can continue + this->position = 0; + try { this->content = this->filesystem.ReadInputFile(); } catch (const std::runtime_error &e) { diff --git a/lib/watchDog.cpp b/lib/watchDog.cpp deleted file mode 100644 index 8f7d9f0..0000000 --- a/lib/watchDog.cpp +++ /dev/null @@ -1,123 +0,0 @@ -#include "watchdog.h" - -namespace fs = std::filesystem; //makes it easier to read -void WatchDog::start() -{ - //checks if file exist - if(!fs::exists(path)) - { - //returns and sets parameters to false if file doesnt exist - watching = false; - hasInitialTime = false; - std::cout << "WatchDog: File does not exists: " << path << std::endl; - return; - } - //grabs intial write time - lastWriteTime = fs::last_write_time(path); - watching = true; - hasInitialTime = true; - std::cout << "WatchDog: Started" << std::endl; -} -void WatchDog::stop(){ - watching = false; -} -bool WatchDog::checkFile(){ - //If not watching returns false - if (!watching) return false; - - //Checking if file was deleted - if(!fs::exists(path)) - { - if (hasInitialTime) { - std::cout << "WatchDog: File was delete: " << path << std::endl; - hasInitialTime = false; - return true; - } - return false; - } - - //Built in function with file system to check last write tim - fs::file_time_type currentWriteTime = fs::last_write_time(path); - - //File was just created - if(!hasInitialTime) - { - lastWriteTime = currentWriteTime; - hasInitialTime = true; - std::cout << "WatchDog: File created: " << path << std::endl; - return true; - } - - //File modified - if (currentWriteTime != lastWriteTime) - { - lastWriteTime = currentWriteTime; - std::cout << "WatchDog: File modifed at " - << timePointToString(lastWriteTime) << std::endl; - return true; - } - - } catch (const fs::filesystem_error& e) { - // File deleted, inaccessible, or path invalid - if (hasInitialTime) { - std::cout << "WatchDog: File deleted or inaccessible: " << path << std::endl; - hasInitialTime = false; - return true; - } - return false; - - } catch (const std::exception& e) { - std::cerr << "WatchDog: Unexpected error checking file: " << e.what() << std::endl; - return false; - } - - // No change - return false; -} - -std::string Watchdog::TimePointToString(const fs::file_time_type& timePoint){ - /** - * Step 1: timePoint - * - This is the last write time of the file, returned by std::filesystem. - * - Its clock is platform-dependent (filesystem clock). - * - * Step 2: fs::file_time_type::clock::now() - * - Current time according to the filesystem clock. - * - * Step 3: std::chrono::system_clock::now() - * - Current time according to the system clock (standard C++ clock). - * - * Conversion formula: - * timePoint - fs::file_time_type::clock::now() + std::chrono::system_clock::now() - * - * Explanation: - * a) timePoint - fs::file_time_type::clock::now() - * - Calculates the duration between the file's last write time and "now" - * according to the filesystem clock. - * b) + std::chrono::system_clock::now() - * - Shifts that duration to align with the system clock timeline. - * c) std::chrono::time_point_cast(...) - * - Ensures the resulting time_point uses the correct duration type - * for std::chrono::system_clock. - * - * Result: - * - systemTime is a std::chrono::system_clock::time_point representing - * the same instant as timePoint, but compatible with system_clock. - */ - std::chrono::system_clock::time_point systemTimePoint = - std::chrono::time_point_cast( - timePoint - fs::file_time_type::clock::now() + std::chrono::system_clock::now() - ); - - //Converts to seconds - std::time_t timeInSeconds = std::chrono::system_clock::to_time_t(systemTimePoint); - - //Converts to local time, built in function - std::tm localTime = *std::localtime(&timeInSeconds); - - // Format the time into a string using strftime - char buffer[20]; - std::strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &localTime); - - return std::string(buffer); -} diff --git a/lib/watchDog.h b/lib/watchDog.h deleted file mode 100644 index 3164ac1..0000000 --- a/lib/watchDog.h +++ /dev/null @@ -1,96 +0,0 @@ -/** - * @file watchdog.h - * @brief file watcher - * @author Preston Shultz - * Sources: - * https://en.cppreference.com/w/cpp/filesystem.html - * https://en.cppreference.com/w/cpp/chrono.html - * Format the time into a string using strftime - * https://en.cppreference.com/w/cpp/chrono/c/strftime.html - */ - -#ifndef WATCHDOG_H -#define WATCHDOG_H - -#include -#include -#include //allow access to files platform independent -#include //makes timestamps easier -#include //Convert time_t to std::tm for local time -#include //Formats std::tim into "YYYY-MM-DD HH-MM-SS" - - -/** - * @brief watchdog class. - * - * Checks if a file is modified and displays date modified - * - * @author Preston Shultz (shultzp1@my.erau.edu) - */ -class Watchdog{ -public: - Watchdog(const std::string& path) : - path(path), watching(false), has_initial_time(false) {} - - /** - * @brief watchdog class. - * - * Starts the watchdog to check of a file is modified - * - * @author Preston Shultz (shultzp1@my.erau.edu) - */ - void Start(); - /** - * @brief watchdog class. - * - * Stops the watchdog - * - * @author Preston Shultz (shultzp1@my.erau.edu) - */ - void Stop() {watching = false;} //Disable - - /** - * @brief watchdog class. - * - * Checks if a file has been modified - * - * @author Preston Shultz (shultzp1@my.erau.edu) - */ - bool CheckFile(); - - /** - * @brief watchdog class. - * - * Returns files last modified date - * - * @author Preston Shultz (shultzp1@my.erau.edu) - */ - std::filesystem::file_time_type GetLastWriteTime() - const {return last_write_time;} - - /** - * @brief watchdog class. - * - * Converts time point into a string - * - * @author Preston Shultz (shultzp1@my.erau.edu) - */ - static std::string TimePointToString(const std::filesystem::file_time_type& timePoint); - - /** - * @brief watchdog class. - * - * Returns if the watchDog is on - * - * @author Preston Shultz (shultzp1@my.erau.edu) - */ - bool IsWatching() const{return watching;} - -private: - std::string path; //file path - bool watching; //Is watchdog on? - std::filesystem::file_time_type last_write_time; - bool has_initial_time; //checks if initial time is given -}; - -#endif \ No newline at end of file diff --git a/lib/watchdog.cpp b/lib/watchdog.cpp new file mode 100644 index 0000000..700edc5 --- /dev/null +++ b/lib/watchdog.cpp @@ -0,0 +1,87 @@ +#include "watchdog.h" +#include +#include +#include + +namespace fs = std::filesystem; +using namespace std::chrono; + +void Watchdog::Start(std::function callback) { + // checks if file exist + if (!fs::exists(this->path)) + throw std::runtime_error("File does not exist."); + + // Loop forever and check the file. + while (true) { + CheckFile(callback); + std::this_thread::sleep_for(this->POLLING_INTERVAL); + } +} + +void Watchdog::CheckFile(std::function callback) { + // LONG STORY SHORT: + // When a file is written to, it aquires an OS lock, which means our program + // cannot access it. So when we request, it fails. So we should basically just + // keep trying until we get access. + // + // After implementing some retry logic, I was unable to replicate the error. + + for (int attempt = 0; attempt < this->MAX_RETRIES; ++attempt) { + try { + // Checking if file was deleted + if (!fs::exists(this->path)) + throw std::runtime_error( + "File could not be found. Maybe it was deleted?"); + + // Built in function with file system to check last write time + fs::file_time_type currentWriteTime = fs::last_write_time(path); + + // File modified + if (currentWriteTime != this->last_write_time) { + this->last_write_time = currentWriteTime; + + time_point before = high_resolution_clock::now(); + callback(); + time_point after = high_resolution_clock::now(); + + duration dur = after - before; + long ms = std::chrono::duration_cast(dur).count(); + long us = std::chrono::duration_cast(dur).count(); + + if (ms > 0) { + std::cout << std::endl + << "Recompiled in \033[36m" << ms << "ms\033[0m" << std::endl; + } else { + std::cout << std::endl + << "Recompiled in \033[36m" << us << "μs\033[0m" << std::endl; + } + } + } catch (const std::exception &ex) { + // On last attempt, bubble the error outward + if (attempt == this->MAX_RETRIES - 1) + throw std::runtime_error("Watchdog failed after multiple retries: " + + std::string(ex.what())); + + // Wait and then try again + std::this_thread::sleep_for(this->RETRY_DELAY); + } + } +} + +std::string Watchdog::TimePointToString(const fs::file_time_type &timePoint) { + system_clock::time_point systemTimePoint = + time_point_cast( + timePoint - fs::file_time_type::clock::now() + system_clock::now()); + + // Converts to seconds + std::time_t timeInSeconds = system_clock::to_time_t(systemTimePoint); + + // Converts to local time, built in function + std::tm localTime = *std::localtime(&timeInSeconds); + + // Format the time into a string using strftime + char buffer[20]; + std::strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &localTime); + + return std::string(buffer); +} diff --git a/lib/watchdog.h b/lib/watchdog.h new file mode 100644 index 0000000..dd34483 --- /dev/null +++ b/lib/watchdog.h @@ -0,0 +1,111 @@ +/** + * @file watchdog.h + * @brief file watcher + * @author Preston Shultz + * Sources: + * https://en.cppreference.com/w/cpp/filesystem.html + * https://en.cppreference.com/w/cpp/chrono.html + * Format the time into a string using strftime + * https://en.cppreference.com/w/cpp/chrono/c/strftime.html + */ + +#ifndef WATCHDOG_H +#define WATCHDOG_H + +#include //makes timestamps easier +#include //Convert time_t to std::tm for local time +#include //allow access to files platform independent +#include +#include //Formats std::tim into "YYYY-MM-DD HH-MM-SS" +#include +#include + +/** + * @brief watchdog class. + * + * Checks if a file is modified and displays date modified + * + * @author Preston Shultz (shultzp1@my.erau.edu) + */ +class Watchdog { +protected: + /** + * @brief watchdog class. + * + * Checks if a file has been modified + * + * @param callback Callback function to execute when the watchdog notices a + * change. + * + * @author Preston Shultz (shultzp1@my.erau.edu) + * @author Hayden Hargreaves (hhargreaves2006@gmail.com) + */ + void CheckFile(std::function callback); + +public: + Watchdog(const std::string &path) : path(path) {} + + /** + * @brief watchdog class. + * + * Starts the watchdog to check of a file is modified + * + * @param callback Callback function to execute when the watchdog notices a + * change. + * + * @author Preston Shultz (shultzp1@my.erau.edu) + */ + void Start(std::function callback); + + /** + * @brief watchdog class. + * + * Converts time point into a string + * + * Details below: + * + * Step 1: timePoint + * - This is the last write time of the file, returned by std::filesystem. + * - Its clock is platform-dependent (filesystem clock). + * + * Step 2: fs::file_time_type::clock::now() + * - Current time according to the filesystem clock. + * + * Step 3: std::chrono::system_clock::now() + * - Current time according to the system clock (standard C++ clock). + * + * Conversion formula: + * timePoint - fs::file_time_type::clock::now() + + * std::chrono::system_clock::now() + * + * Explanation: + * a) timePoint - fs::file_time_type::clock::now() + * - Calculates the duration between the file's last write time and "now" + * according to the filesystem clock. + * b) + std::chrono::system_clock::now() + * - Shifts that duration to align with the system clock timeline. + * c) std::chrono::time_point_cast(...) + * - Ensures the resulting time_point uses the correct duration type + * for std::chrono::system_clock. + * + * Result: + * - systemTime is a std::chrono::system_clock::time_point representing + * the same instant as timePoint, but compatible with system_clock. + * + * @author Preston Shultz (shultzp1@my.erau.edu) + */ + static std::string + TimePointToString(const std::filesystem::file_time_type &timePoint); + +private: + std::string path; + std::filesystem::file_time_type last_write_time; + + // Timing values for the watchdog + const std::chrono::milliseconds POLLING_INTERVAL = + std::chrono::milliseconds(100); + const int MAX_RETRIES = 20; + const std::chrono::milliseconds RETRY_DELAY = std::chrono::milliseconds(20); +}; + +#endif diff --git a/src/main.cpp b/src/main.cpp index ceeef67..81ee88a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,8 @@ +#include "../lib/documentConverter.h" #include "../lib/inlineNode.h" #include "../lib/parser.h" #include "../lib/structureNode.h" -#include "../lib/watchDog.h" +#include "../lib/watchdog.h" #include #include @@ -40,19 +41,7 @@ void test_nodes() { */ void test_watchdog() { Watchdog wd("test/input.md"); - wd.Start(); - - std::cout << "Initial check (should do nothing if file unchanged):\n"; - wd.CheckFile(); - - std::cout << "Now, modify or create the file 'example.txt' manually and " - "press Enter:\n"; - std::cin.get(); // Wait for user to press Enter - - // Check again after manual change - wd.CheckFile(); - - std::cout << "Done testing.\n"; + wd.Start(nullptr); } void test_input(int argc, char **argv) { @@ -78,4 +67,10 @@ void test_input(int argc, char **argv) { std::cout << std::endl; } -int main(int argc, char **argv) { test_watchdog(); } +void test_document_converter() { + DocumentConverter dc("test/input.md"); + dc.ConvertWatcher(); +} + +int main(int argc, char **argv) { + test_document_converter(); } diff --git a/syntax.md b/syntax.md deleted file mode 100644 index bd80e12..0000000 --- a/syntax.md +++ /dev/null @@ -1,45 +0,0 @@ - -Reference [here](https://www.markdownguide.org/basic-syntax/) - -Headings, h# tags - - -# Header Level 1 ->

Content

-## Header Level 2 ->

Content

-### Header Level 3 ->

Content

-#### Header Level 4 ->

Content

-##### Header Level 5 ->
Content
-###### Header Level 6 ->
Content
- - -Alternate syntax (n number of =/-) - -Header Level 1 ->

Content

-================ - - -Header Level 2 ->

Content

----------------- - - -Paragraph tags - -Hello world ->

Hello world

- -This is also -a paragraph ->

this is also a paragraph regardless

-regardless - -However -this is a break, because it ends with two spaces ->

However
this is a break, because it ends with two spaces

- -Double returns also - -yields new paragraphs ->

Double returns also

yields new paragraphs

- - -*italic* -> italic -**bold** -> bold -***italic bold*** -> italic bold - -hello **world** -> [TextClass: hello, BoldClass: world] diff --git a/test/input.html b/test/input.html new file mode 100644 index 0000000..d5b4d49 --- /dev/null +++ b/test/input.html @@ -0,0 +1,25 @@ + + + + + + Document + + +

Reference [here](https://www.markdownguide.org/basic-syntax/)

+

Headings, h# tags

+

Header Level 1 ->

Content

## Header Level 2 ->

Content

### Header Level 3 ->

Content

#### Header Level 4 ->

Content

##### Header Level 5 ->
Content
###### Header Level 6 ->
Content
+

Alternate syntax (n number of =/-)

+

Header Level 1 ->

Content

================

+

Header Level 2 ->

Content

----------------

+

Paragraph tags

+

Hello world ->

Hello world

+

This is also a paragraph ->

this is also a paragraph regardless

regardless

+

However this is a break, because it ends with two spaces ->

However
this is a break, because it ends with two spaces

+

Double returns also

+

yields new paragraphs ->

Double returns also

yields new paragraphs

+

italic -> italic bold -> bold italic bold -> italic bold

+

hello world -> [TextClass: hello, BoldClass: world]

+ + + \ No newline at end of file diff --git a/test/input.md b/test/input.md index 54ed126..2ba0eb3 100644 --- a/test/input.md +++ b/test/input.md @@ -1,17 +1,44 @@ +Reference [here](https://www.markdownguide.org/basic-syntax/) + +Headings, h# tags -# Hello world in an h1 tag +# Header Level 1 ->

Content

+## Header Level 2 ->

Content

+### Header Level 3 ->

Content

+#### Header Level 4 ->

Content

+##### Header Level 5 ->
Content
+###### Header Level 6 ->
Content
-## This is a h2 tag +Alternate syntax (n number of =/-) + +Header Level 1 ->

Content

+================ -### h3 +Header Level 2 ->

Content

+---------------- -#### h4 +Paragraph tags -##### h5 +Hello world ->

Hello world

-###### h6 +This is also +a paragraph ->

this is also a paragraph regardless

+regardless +However +this is a break, because it ends with two spaces ->

However
this is a break, because it ends with two spaces

+ +Double returns also + +yields new paragraphs ->

Double returns also

yields new paragraphs

+ + +*italic* -> italic +**bold** -> bold +***italic bold*** -> italic bold + +hello **world** -> [TextClass: hello, BoldClass: world]