Project Genesis

This commit is contained in:
mharb 2024-08-29 14:36:45 -04:00
parent 44b6ec9981
commit dc69982504
4 changed files with 458 additions and 0 deletions

87
input.md Normal file
View File

@ -0,0 +1,87 @@
# Markdown Features Example
## Headers
# This is a Heading 1
## This is a Heading 2
### This is a Heading 3
#### This is a Heading 4
##### This is a Heading 5
###### This is a Heading 6
## Emphasis
*This text will be italic*
**This text will be bold**
***This text will be both italic and bold***
## Lists
### Unordered List
- Item 1
- Item 2
- Subitem 2.1
- Subitem 2.2
- Item 3
### Ordered List
1. First item
2. Second item
3. Third item
## Links
[This is a link to Ecosia](https://www.ecosia.org)
## Images
![Alt text for an image](https://via.placeholder.com/150)
## Blockquotes
> This is a blockquote.
> It can span multiple lines.
## Code
Inline code: `print("Hello, World!")`
### Code Block
```
def hello_world(): print("Hello, World!")
```
## Horizontal Rule
---
## Tables
| Header 1 | Header 2 |
|----------|----------|
| Row 1 | Row 1 |
| Row 2 | Row 2 |
## Task Lists
- [x] Completed task
- [ ] Incomplete task
## Footnotes
Here is a sentence with a footnote.[^1]
[^1]: This is the footnote.
## Strikethrough
~~This text is crossed out.~~
## Emoji
Here is a smiley face: 😄
## HTML Elements
<div>
This is a div element in HTML.
</div>

193
markdown_to_html.c Normal file
View File

@ -0,0 +1,193 @@
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
#define BUFFER_SIZE 1024
void convert_markdown_to_html(const char *markdown, FILE *output) {
const char *start = markdown;
const char *end;
bool in_code_block = false;
bool header_row_started = false;
while (*start) {
// Find the end of the current line
end = strchr(start, '\n');
if (end == NULL) {
end = start + strlen(start);
}
size_t length = end - start;
// Ensure we do not exceed the buffer size
if (length >= BUFFER_SIZE) {
length = BUFFER_SIZE - 1;
}
char line[BUFFER_SIZE];
strncpy(line, start, length);
line[length] = '\0';
// Check for code block delimiters
if (strcmp(line, "```") == 0) {
in_code_block = !in_code_block;
if (in_code_block) {
fprintf(output, "<pre><code>\n");
} else {
fprintf(output, "</code></pre>\n");
}
} else if (in_code_block) {
// If inside a code block, output the line as-is
fprintf(output, "%s\n", line);
} else if (line[0] == '|' && strstr(line, "-") != NULL) {
// Check if it's a header row
if (!header_row_started) {
fprintf(output, "<table>\n");
header_row_started = true;
}
fprintf(output, "<tr>\n");
char *token = strtok(line, "|");
while (token != NULL) {
if (strlen(token) > 0) {
fprintf(output, "<th style=\"border: 1px solid black;\">%s</th>\n", token);
}
token = strtok(NULL, "|");
}
fprintf(output, "</tr>\n");
} else if (header_row_started && (line[0] == '|' || line[0] == '-')) {
// Regular row
fprintf(output, "<tr>\n");
char *token = strtok(line, "|");
while (token != NULL) {
if (strlen(token) > 0) {
fprintf(output, "<td style=\"border: 1px solid black;\">%s</td>\n", token);
}
token = strtok(NULL, "|");
}
fprintf(output, "</tr>\n");
} else {
// If we were in a table and now we are not, close the table
if (header_row_started) {
fprintf(output, "</table>\n");
header_row_started = false;
}
// Handle headers
if (line[0] == '#') {
int level = 0;
while (line[level] == '#') {
level++;
}
fprintf(output, "<h%d>%s</h%d>\n", level, line + level + 1, level);
}
// Handle bold text
else if (strstr(line, "**") != NULL) {
char *bold_start = strstr(line, "**");
char *bold_end = strstr(bold_start + 2, "**");
if (bold_end != NULL) {
*bold_end = '\0';
fprintf(output, "%.*s<b>%s</b>%s\n", (int)(bold_start - line), line, bold_start + 2, bold_end + 2);
}
}
// Handle italic text
else if (strstr(line, "*") != NULL) {
char *italic_start = strstr(line, "*");
char *italic_end = strstr(italic_start + 1, "*");
if (italic_end != NULL) {
*italic_end = '\0';
fprintf(output, "%.*s<i>%s</i>%s\n", (int)(italic_start - line), line, italic_start + 1, italic_end + 1);
}
}
// Handle list items
else if (line[0] == '-') {
fprintf(output, "<li>%s</li>\n", line + 2);
}
// Handle links
else if (strstr(line, "[") != NULL && strstr(line, "](") != NULL) {
char *link_start = strstr(line, "[");
char *link_end = strstr(link_start, "]");
char *url_start = strstr(link_end, "(");
char *url_end = strstr(url_start, ")");
if (url_end != NULL) {
*link_end = '\0';
*url_end = '\0';
fprintf(output, "%.*s<a href=\"%s\">%s</a>%s\n", (int)(link_start - line), line, url_start + 1, link_start + 1, url_end + 1);
}
}
// Handle inline code to monospace
else if (strstr(line, "`") != NULL) {
char *monospace_start = strstr(line, "`");
char *monospace_end = strstr(monospace_start + 1, "`");
if (monospace_end != NULL) {
*monospace_end = '\0';
fprintf(output, "%.*s<code>%s</code>%s\n", (int)(monospace_start - line), line, monospace_start + 1, monospace_end + 1);
}
}
// Default to paragraph
else {
fprintf(output, "<p>%s</p>\n", line);
}
}
start = (*end) ? end + 1 : end;
}
// Close any open table at the end
if (header_row_started) {
fprintf(output, "</table>\n");
}
}
/**
* Generates a static site from a Markdown file.
*
* @param input_file The Markdown file to read from.
* @param output_file The HTML file to write to.
*/
void generate_static_site(const char *input_file, const char *output_file) {
FILE *md_file = fopen(input_file, "r");
if (!md_file) {
perror("Failed to open markdown file");
return;
}
FILE *html_file = fopen(output_file, "w");
if (!html_file) {
perror("Failed to create HTML file");
fclose(md_file);
return;
}
// Write the basic HTML structure with CSS
fprintf(html_file,
"<!DOCTYPE html>\n"
"<html>\n"
"<head>\n"
"<title>Static Site</title>\n"
"<link rel=\"stylesheet\" type=\"text/css\" href=\"styles.css\">\n"
"</head>\n"
"<body>\n"
"<div class=\"container\">\n");
// Read from markdown file and convert to HTML
char buffer[BUFFER_SIZE];
while (fgets(buffer, sizeof(buffer), md_file)) {
convert_markdown_to_html(buffer, html_file);
}
// End container
fprintf(html_file, "</div>\n</body>\n</html>\n");
fclose(md_file);
fclose(html_file);
}
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "Usage: %s <input.md> <output.html>\n", argv[0]);
return EXIT_FAILURE;
}
generate_static_site(argv[1], argv[2]);
return EXIT_SUCCESS;
}

103
output.html Normal file
View File

@ -0,0 +1,103 @@
<!DOCTYPE html>
<html>
<head>
<title>Static Site</title>
<link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
<div class="container">
<h1>Markdown Features Example</h1>
<p></p>
<h2>Headers</h2>
<p></p>
<h1>This is a Heading 1</h1>
<h2>This is a Heading 2</h2>
<h3>This is a Heading 3</h3>
<h4>This is a Heading 4</h4>
<h5>This is a Heading 5</h5>
<h6>This is a Heading 6</h6>
<p></p>
<h2>Emphasis</h2>
<p></p>
<i>This text will be italic</i>
<b>This text will be bold</b>
<b>*This text will be both italic and bold</b>*
<p></p>
<h2>Lists</h2>
<p></p>
<h3>Unordered List</h3>
<li>Item 1</li>
<li>Item 2</li>
<p> - Subitem 2.1</p>
<p> - Subitem 2.2</p>
<li>Item 3</li>
<p></p>
<h3>Ordered List</h3>
<p>1. First item</p>
<p>2. Second item</p>
<p>3. Third item</p>
<p></p>
<h2>Links</h2>
<p></p>
<a href="https://www.ecosia.org">This is a link to Ecosia</a>
<p></p>
<h2>Images</h2>
<p></p>
!<a href="https://via.placeholder.com/150">Alt text for an image</a>
<p></p>
<h2>Blockquotes</h2>
<p></p>
<p>> This is a blockquote. </p>
<p>> It can span multiple lines.</p>
<p></p>
<h2>Code</h2>
<p></p>
Inline code: <code>print("Hello, World!")</code>
<p></p>
<h3>Code Block</h3>
<pre><code>
<p>def hello_world(): print("Hello, World!")</p>
<pre><code>
<h2>Horizontal Rule</h2>
<p></p>
<li>-</li>
<p></p>
<h2>Tables</h2>
<p></p>
<p>| Header 1 | Header 2 |</p>
<table>
<tr>
<th style="border: 1px solid black;">----------</th>
<th style="border: 1px solid black;">----------</th>
</tr>
</table>
<p>| Row 1 | Row 1 |</p>
<p>| Row 2 | Row 2 |</p>
<p></p>
<h2>Task Lists</h2>
<p></p>
<li>[x] Completed task</li>
<li>[ ] Incomplete task</li>
<p></p>
<h2>Footnotes</h2>
<p></p>
<p>Here is a sentence with a footnote.[^1]</p>
<p></p>
<p>[^1]: This is the footnote.</p>
<p></p>
<h2>Strikethrough</h2>
<p></p>
<p>~~This text is crossed out.~~</p>
<p></p>
<h2>Emoji</h2>
<p></p>
<p>Here is a smiley face: 😄</p>
<p></p>
<h2>HTML Elements</h2>
<p></p>
<p><div></p>
<p> This is a div element in HTML.</p>
<p></div></p>
</div>
</body>
</html>

75
styles.css Normal file
View File

@ -0,0 +1,75 @@
/* styles.css */
body {
font-family: 'Arial', sans-serif; /* Use a sans-serif font for clarity */
background-color: #f4f0f0; /* Soft red background for a minimal look */
color: #000000; /* Dark text color for contrast */
margin: 0;
padding: 20px;
line-height: 1.5; /* Increased line height for readability */
text-align: justify; /* Justify text for a book-like layout */
}
h1 {
text-align: center; /* Center the main title */
font-size: 2.5em; /* Larger font size for the title */
margin-bottom: 20px; /* Space below the title */
color: #005f73; /* Deep teal color for the title */
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.1); /* Subtle shadow for depth */
}
h2 {
font-size: 2em; /* Size for sub-headers */
margin-top: 20px; /* Space above sub-headers */
margin-bottom: 10px; /* Space below sub-headers */
color: #0a9396; /* Lighter teal color for sub-headers */
border-bottom: 2px solid #005f73; /* Underline effect */
padding-bottom: 5px; /* Padding below the header */
}
p {
margin: 0 0 1.5em; /* Space between paragraphs */
text-align: justify; /* Justify text in paragraphs */
}
ul {
list-style-type: none; /* Remove default bullets */
padding-left: 0; /* Remove padding */
}
li {
margin: 5px 0; /* Space between list items */
position: relative; /* Position for the icon */
padding-left: 25px; /* Space for icon */
color: #333; /* Text color for list items */
}
li::before {
content: '•'; /* Basic bullet icon */
position: absolute; /* Position the icon */
left: 0; /* Align to the left */
color: #94d2bd; /* Soft green color for the icon */
font-size: 1.5em; /* Icon size */
line-height: 0; /* Align icon with text */
}
a {
color: #ee9b00; /* Warm amber color for links */
text-decoration: none; /* Remove underline */
transition: color 0.3s; /* Smooth transition for hover effect */
}
a:hover {
color: #d00000; /* Bright red color on hover */
text-decoration: underline; /* Underline links on hover */
}
/* Add a container for the content to simulate a book page */
.container {
max-width: 800px; /* Limit the width for better readability */
margin: 0 auto; /* Center the container */
padding: 20px; /* Padding inside the container */
background: white; /* White background for the content area */
box-shadow: 0 0 15px rgba(0, 0, 0, 0.1); /* Subtle shadow for depth */
border-radius: 8px; /* Rounded corners */
border: 1px solid #ccc; /* Light border for definition */
}