Compare commits

...

10 Commits

Author SHA1 Message Date
029a99216d improving installation + adding variable to execute awk script 2024-10-28 22:06:49 +01:00
5234e54a81 adding index template 2024-10-28 22:04:21 +01:00
13c9615330 v0.1.0 2024-10-27 18:27:38 +01:00
88ec76dcee preping v0.1.0 2024-10-27 18:27:06 +01:00
191c3a78e5 wip 2024-10-26 16:39:45 +02:00
9257373163 adding make test 2024-10-24 14:59:39 +02:00
1f4009c2d4 cleaning test folder 2024-10-24 14:39:28 +02:00
d024465573 upgrading + draft v2 + markdown parser 2024-10-24 14:16:19 +02:00
29d0344081 erratum 2024-10-24 14:15:39 +02:00
3ffd5c19b2 Completing todo list 2019-07-28 23:20:04 +02:00
12 changed files with 523 additions and 489 deletions

3
.gitignore vendored
View File

@ -4,5 +4,4 @@ css
bash bash
posts posts
*.conf *.conf
index.html ./index.html
README.html

View File

@ -1,7 +1,16 @@
install: install:
@echo "Installing bob" @echo "Installing bob"
cp bob /usr/local/bin cp bob /usr/local/bin
mkdir -p /usr/local/lib/bob/template
cp lib/template/* /usr/local/lib/bob/template
cp lib/*.awk /usr/local/lib/bob
uninstall: uninstall:
@echo "Uninstalling bob" @echo "Uninstalling bob"
rm /usr/local/bin/bob rm /usr/local/bin/bob
rm -rf /usr/local/lib/bob
.PHONY: test # Declare 'test' as a phony target
test:
bash ./test/test.sh

View File

@ -62,3 +62,6 @@ bob help
* Consider adding configuration files for some/all posts (if they * Consider adding configuration files for some/all posts (if they
need special javascript included e.g. MathJax, AJAX, sockets ...). need special javascript included e.g. MathJax, AJAX, sockets ...).
* Add a preview function for TRUE drafts being written * Add a preview function for TRUE drafts being written
* Take into account the headers possibilities of multimarkdown, which could
replace the self header writing process and include other features such as
Mathjax

591
bob
View File

@ -1,493 +1,15 @@
#!/usr/bin/env bash #!/usr/bin/env bash
_get_blog_name() if [ -z "${BOB_LIB}" ]; then
{ BOB_LIB=/usr/local/lib/bob
# Extract the configuration file else
conf=`cat .blog.conf` BOB_LIB=./lib
name_regex="blog\:([a-zA-Z ]+)"
# Echo the name of the blog, if any was given
if [[ $conf =~ $name_regex ]]; then
echo ${BASH_REMATCH[1]}
fi
}
_get_dark_param()
{
# Extract the configuration file
conf=`cat .blog.conf`
dark_regex="dark:(y|n|N)"
if [[ $conf =~ $dark_regex ]]; then
echo ${BASH_REMATCH[1]}
fi
}
_get_blog_lang()
{
# Extract the configuration file
conf=`cat .blog.conf`
lang_regex="lang:([a-z]+)"
if [[ $conf =~ $lang_regex ]]; then
echo ${BASH_REMATCH[1]}
fi
}
_add_header()
{
post_name=$1
blog_name=$2
lang=$3
dark=$4
css="../css/poststyle.css"
if [[ $dark =~ "y" ]]; then
css="../css/poststyle.dark.css"
fi
cat > ./posts/$post_name.html << EOF
<!DOCTYPE html>
<html lang="$lang" dir="ltr">
<head>
<meta charset="utf-8">
<title>$post_name</title>
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<link href="https://fonts.googleapis.com/css?family=Cutive+Mono|IBM+Plex+Mono&display=swap" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="$css">
</head>
<body>
<article class='post'>
<header>
<h2><a href="../index.html">$blog_name</a></h2>
</header>
EOF
}
_add_footer()
{
post_name=$1
cat >> ./posts/$post_name.html << EOF
</article>
<footer>
<span>generated by <a href="https://www.github.com/SiwonP/bob">bob</a></span>
</footer>
</body>
</html>
EOF
}
_get_last_modif_date()
{
# Extract the date of the last modification of the file $1
# and echo it with format dd/mm/yyyy
date=`stat -f "%Sm" -t "%d/%m/%Y" $1`
echo $date
}
publish()
{
delete_posts
# Collect all configuration parameters so that the regex are only evaluted
# once per publication. Done to improve the speed of the publication
dark=$(_get_dark_param)
lang=$(_get_blog_lang)
blog_name=$(_get_blog_name)
# list all the drafts stored as most recently modified to
# least recently modified, as it should appear on a blog
drafts=`ls -t ./bases/`
# echo $drafts
# Tranform the string into an array
list=($(echo "$drafts" | tr ' ' '\n'))
# date=$(_get_last_modif_date "./drafts/${list[0]}")
# Regex to extract the name without the extension
name_regex="([a-zA-Z]+)\.(md|markdown)"
# Array to story only the names of the posts
posts_names=()
for (( i=0; i<${#list[@]}; i++ ));
do
if [[ ${list[i]} =~ $name_regex ]]; then
# Append the names to the array
posts_names+=(${BASH_REMATCH[1]})
fi
_create_posts "./bases/${list[i]}" "$blog_name" "$lang" "$dark"
done
# function to update the index.html
# Passing the drafts as argument since it's sorted
_update_index "$drafts" "$blog_name" "$lang" "$dark"
}
_create_posts()
{
draft=$1
blog_name=$2
lang=$3
dark=$4
# Convert the markdown file $draft into html
# and store the result in $content
content=`multimarkdown --nolabels $draft`
# Regex to extract the simple post name
md_regex="([a-zA-Z\-]+)\.(md|markdown)"
if [[ $draft =~ $md_regex ]]; then
# If the file have md or markdown extension, cut it
post_name=${BASH_REMATCH[1]}
else
# if not and it has no extension, keep it this way
post_name=$draft
fi
# Integrate the html converted content into a proper html file
_build_post "$post_name" "$blog_name" "$content" "$lang" "$dark"
}
_build_post()
{
# Create the html file of the post $post_name with the
# previsouly converted markdown to html $content
post_name=$1
blog_name=$2
content=$3
lang=$4
dark=$5
_add_header "$post_name" "$blog_name" "$lang" "$dark"
echo $content >> ./posts/$post_name.html
_add_footer "$post_name"
}
_update_index()
{
title=$2
lang=$3
dark=$4
css="./css/indexstyle.css"
if [[ $dark =~ "y" ]]; then
css="./css/indexstyle.dark.css"
fi
cat > index.html << EOF
<!DOCTYPE html>
<html lang="$lang" dir="ltr">
<head>
<meta charset="utf-8">
<title>$title</title>
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<link href="https://fonts.googleapis.com/css?family=Cutive+Mono|IBM+Plex+Mono&display=swap" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="$css">
</head>
<body>
<h1 class='title'>$title</h1>
EOF
# Retrieve the string containing all drafts names and splitting it
# into an array
drafts=$1
drafts_list=($(echo "$drafts" | tr ' ' '\n'))
# Number of posts in the draft list, needed for the for loop
nbposts=${#drafts_list[@]}
# If there are posts to post, begin the list
if [ $nbposts -gt 0 ]
then
echo "<ul class='posts_list'>" >> index.html
fi fi
# Regex to extract just the name of the post
post_regex="([a-zA-Z\-]+)\.(md|markdown)"
for (( i=0; i<${#drafts_list[@]}; i++ ));
do
# Retrieve the date of the last modification of the draft
date=$(_get_last_modif_date "./bases/${drafts_list[i]}")
# In case the next regex doesn't work, even though it's supposed to
# work everytime
post_name="unknown"
# Extract the strict name of the post in the same
# order of the drafts because they are sorted according
# to the last modification date
if [[ ${drafts_list[i]} =~ $post_regex ]]; then
post_name=${BASH_REMATCH[1]}
fi
# Function to add items to the posts list
_add_post_link "./posts/$post_name.html" "$post_name" "$date"
done
# If there are posts posted, close the list
if [ $nbposts -gt 0 ]; then
echo "</ul>" >> index.html
fi
cat >> index.html << EOF
</body>
</html>
EOF
}
_add_post_link()
{
url=$1
post_name=$2
date=$3
post_name=${post_name//\-/ }
echo "<li class='post'>" >> index.html
echo "<a href="$url">$post_name</a>" >> index.html
echo "<span class='date'>$date</span>" >> index.html
echo "</li>" >> index.html
}
init()
{
echo Name of the author of the blog :
read author
echo "author:$author" > .blog.conf
echo Name of the blog :
read blog
echo "blog:$blog" >> .blog.conf
echo "Language of the blog : (en)"
read lang
if [ -z $lang ]; then
lang=en
fi
echo "lang:$lang" >> .blog.conf
echo "Activate dark mode : (y/N)"
read dark
if [ -z $lang ]; then
dark=n
fi
echo "dark:$dark" >> .blog.conf
mkdir drafts
mkdir bases
mkdir posts
mkdir css
_init_css
_index "$blog" "$lang" "$dark"
}
_init_css()
{
# Initiate css files for both the index and the posts,
# both dark and light themes
cat > ./css/indexstyle.css << EOF
.wrap {
width: 40vw;
margin-right: auto;
margin-left: auto;
}
.title {
margin-top: 5vh;
margin-bottom: 7vh;
text-align: center;
font-family: 'IBM Plex Mono', monospace;
}
.posts_list {
text-align: center;
padding-left: 0px;
list-style: none;
}
.post {
margin-bottom: 3vh;
font-family: 'IBM Plex Mono', monospace;
}
.post a:link {
text-decoration: none;
}
.post a:hover {
text-decoration: underline;
color: #AAA;
}
.post a {
color: black;
}
.date {
color: #777;
font-family: 'Cutive Mono', monospace;
}
EOF
cat > ./css/indexstyle.dark.css << EOF
body {
background: #222;
}
.wrap {
width: 40vw;
margin-right: auto;
margin-left: auto;
}
.title {
margin-top: 5vh;
margin-bottom: 7vh;
color: #e1e1e1;
text-align: center;
font-family: 'IBM Plex Mono', monospace;
}
.posts_list {
text-align: center;
padding-left: 0px;
list-style: none;
}
.post {
margin-bottom: 3vh;
color: #e1e1e1;
font-family: 'IBM Plex Mono', monospace;
}
.post a:link {
color: #e1e1e1;
text-decoration: none;
}
.post a:hover {
text-decoration: underline;
color: #AAA;
}
.post a {
color: #e1e1e1;
}
.date {
color: #777;
font-family: 'Cutive Mono', monospace;
}
EOF
cat > ./css/poststyle.css << EOF
body {
font-family: 'IBM Plex Mono', monospace;
}
header a {
text-decoration: none;
}
header a:hover {
text-decoration: underline;
}
header {
margin-bottom: 6vh;
}
.post {
width: 70vw;
margin-right: auto;
margin-left: auto;
}
footer {
width: 70vw;
margin-top: 6vh;
margin-right: auto;
margin-left: auto;
font-size: 1.3vh;
}
footer span a {
color: #FF8608;
}
EOF
cat > ./css/poststyle.dark.css << EOF
body {
font-family: 'IBM Plex Mono', monospace;
background: #222;
color: #e1e1e1;
}
header a {
color: #777;
text-decoration: none;
}
header a:hover {
text-decoration: underline;
color: #e1e1e1;
}
header {
margin-bottom: 6vh;
}
.post {
width: 70vw;
margin-right: auto;
margin-left: auto;
}
footer {
width: 70vw;
margin-top: 6vh;
margin-right: auto;
margin-left: auto;
font-size: 1.3vh;
}
footer span a {
color: #FF8608;
}
EOF
}
_index()
{
title=$1
lang=$2
dark=$3
css="./css/indexstyle.css"
if [ $3 -eq "y" ]; then
css="./css/indexstyle.dark.css"
fi
# Create the first index file, empty of any posts
cat > index.html << EOF
<!DOCTYPE html>
<html lang="$lang" dir="ltr">
<head>
<meta charset="utf-8">
<title>$title</title>
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<link href="https://fonts.googleapis.com/css?family=Cutive+Mono|IBM+Plex+Mono&display=swap" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="./css/indexstyle.css">
</head>
<body>
<h1 class='title'>$title</h1>
</body>
</html>
EOF
}
change_mode()
{
# READ FILE LINE BY LINE SO THAT THE NEW CONF FILE IS NOT ON ONE LINE
echo "Activate dark mode : (y/N)"
read dark
if [ -z $lang ]; then
dark=N
fi
conf=`cat .blog.conf`
echo ${conf//dark:(y|n|N)/dark:$dark} > .blog.conf
}
delete_posts()
{
# posts=`ls ./posts/`
# echo $posts/
# if [ "$posts" == "/" ]; then
# echo empty
# fi
rm ./posts/*.html
}
usage() usage()
{ {
echo echo
echo "This script is made for those who want to blog and are also addicted echo "This script is made for those who want to blog and are also addicted to the command line"
to the command line"
echo echo
echo "Run the initiation for a start. After that, place all your future blog echo "Run the initiation for a start. After that, place all your future blog
posts, written in markdown (.md or .markdown), in the draft folder." posts, written in markdown (.md or .markdown), in the draft folder."
@ -499,18 +21,113 @@ usage()
your blog" your blog"
echo echo
echo "bob commands :" echo "bob commands :"
echo " help display this help" echo " help display this help"
echo " init initiate the blog" echo " init initiate a blog"
echo " publish publish the blog" echo " publish <post> publish the post"
echo " unpublish <post> unpublish the post"
} }
init()
{
echo Name of the author of the blog :
read author
echo "author=$author" > .blog.conf
echo Name of the blog :
read blog
echo "blog=$blog" >> .blog.conf
echo "Language of the blog : [en]"
read lang
if [ -z $lang ]; then
lang=en
fi
echo "lang=$lang" >> .blog.conf
echo "Activate dark mode : (y/N)"
read dark
if [ -z $dark ]; then
dark=n
fi
echo "dark=$dark" >> .blog.conf
mkdir drafts
# mkdir templates
mkdir posts
# mkdir css
# _init_css
# _index "$blog" "$lang" "$dark"
}
update_index()
{
posts=$(ls -t ./posts | awk '
BEGIN {
print "<ul>"
}
{
ref=$0
gsub(".html","",ref)
gsub(/[_-]/, " ", ref)
print "<li><a href=\"./posts/" $0 "\">" ref "</a></li>"
}
END {
print "</ul>"
}')
template="${BOB_LIB}/template/index.html"
awk -v content="$posts" '{gsub(/{{articles}}/, content); print}' "$template" > "./index.html"
}
publish()
{
post=$(awk -f ${BOB_LIB}/markdown.awk ./drafts/$1.md)
template="${BOB_LIB}/template/post.html"
awk -v content="$post" '{gsub(/{{article}}/, content); print}' "$template" > "./posts/$1.html"
mv ./drafts/$1.md ./drafts/published/$1.md
update_index
}
unpublish()
{
rm ./posts/$1.html
mv ./drafts/published/$1.md ./drafts/$1.md
update_index
}
unpublish_all()
{
rm ./posts/*
mv ./drafts/published/* ./drafts/
}
deploy()
{
echo "TODO"
}
if [[ $# -eq 0 ]]; then if [[ $# -eq 0 ]]; then
usage usage
elif [[ "$1" == "help" ]]; then
usage
elif [[ "$1" == "usage" ]]; then
usage
elif [[ "$1" == "init" ]]; then elif [[ "$1" == "init" ]]; then
init init
elif [[ "$1" == "publish" ]]; then elif [[ "$1" == "publish" ]]; then
publish if [[ $# -eq 1 ]]; then
echo "Usage : bob publish <draft_name>"
else
publish $2
fi
elif [[ "$1" == "unpublish" ]]; then
if [[ $# -eq 1 ]]; then
echo "Usage : bob unpublish <post_name>"
else
unpublish $2
fi
elif [[ "$1" == "deploy" ]]; then
deploy
elif [[ "$1" == "help" ]]; then elif [[ "$1" == "help" ]]; then
usage usage
fi fi

150
lib/markdown.awk Executable file
View File

@ -0,0 +1,150 @@
#!/usr/bin/awk
BEGIN {
env = "none"
stack_pointer = 0
push(env)
}
# Function to push a value onto the stack
function push(value) {
stack_pointer++
stack[stack_pointer] = value
}
# Function to pop a value from the stack (LIFO)
function pop() {
if (stack_pointer > 0) {
value = stack[stack_pointer]
delete stack[stack_pointer]
stack_pointer--
return value
} else {
return "empty"
}
}
# Function to get last value in LIFO
function last() {
return stack[stack_pointer]
}
function replaceEmAndStrong(line, result, start, end) {
# Replace occurrences of **...** with <strong>...</strong>
while (match(line, /\*\*([^*]+)\*\*/)) {
start = RSTART
end = RSTART + RLENGTH - 1
# Build the result: before match, <strong>, content, </strong>, after match
line = substr(line, 1, start-1) "<strong>" substr(line, start+2, RLENGTH-4) "</strong>" substr(line, end+1)
}
# Replace occurrences of *...* with <em>...</em>
while (match(line, /\*([^*]+)\*/)) {
start = RSTART
end = RSTART + RLENGTH - 1
# Build the result: before match, <em>, content, </em>, after match
line = substr(line, 1, start-1) "<em>" substr(line, start+1, RLENGTH-2) "</em>" substr(line, end+1)
}
return line
}
function closeOne() {
env = pop()
print "</" env ">"
}
# Matching headers
/^#+ / {
match($0, /#+ /);
n = RLENGTH;
print "<h" n-1 ">" substr($0, n + 1) "</h" n-1 ">"
}
# Matching blockquotes
/^> / {
env = last()
if (env == "blockquote")
{
# In a blockquote block only print the text
print substr($0, 3);
} else {
# Otherwise, init the blockquote block
push("blockquote")
print "<blockquote>\n" substr($0, 3)
}
}
# Matching unordered lists
/^[-+*] / {
env = last()
if (env == "ul" ) {
# In a unordered list block, print a new item
print "<li>" substr($0, 3) "</li>"
} else {
# Otherwise, init the unordered list block
push("ul")
print "<ul>\n<li>" substr($0, 3) "</li>"
}
}
# Matching ordered lists
/^[0-9]+\./ {
env = last()
if (env == "ol") {
# In a ordered list block, print a new item
print "<li>" substr($0, 4) "</li>"
} else {
# Otherwise, init the ordered list block
push("ol")
print "<ol>\n<li>" substr($0, 4) "</li>"
}
}
# Matching code block
/^( |\t)/ {
env = last()
match($0, /( |\t)/);
n = RLENGTH;
if (env == "code") {
# In a code block, print a new item
print substr($0, n+1)
} else {
# Otherwise, init the code block
push("pre")
push("code")
print "<pre><code>" substr($0, n+1)
}
}
# Matching a simple paragraph
!/^(#|\*|-|\+|>|`|$|\t| )/ {
env = last()
if (env == "none") {
# If no block, print a paragraph
print "<p>" replaceEmAndStrong($0) "</p>"
} else if (env == "blockquote") {
print $0
}
}
$0 == "" {
env = last()
while (env != "none") {
env = pop()
print "</" env ">"
env = last()
}
}
END {
env = last()
while (env != "none") {
env = pop()
print "</" env ">"
env = last()
}
}

17
lib/template/index.html Normal file
View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="fr" dir="ltr">
<head>
<meta charset="utf-8">
<title>simpet</title>
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<link href="https://fonts.googleapis.com/css?family=Cutive+Mono|IBM+Plex+Mono&display=swap" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="./css/indexstyle.css">
</head>
<body>
<h1 class='title'>simpet</h1>
{{articles}}
</body>
</html>

19
lib/template/post.html Normal file
View File

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="fr" dir="ltr">
<head>
<meta charset="utf-8">
<title>simpet</title>
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<link href="https://fonts.googleapis.com/css?family=Cutive+Mono|IBM+Plex+Mono&display=swap" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="../css/poststyle.css">
</head>
<body>
<h1 class='title'><a href="../index.html">simpet</a></h1>
<article>
{{article}}
</article>
</body>
</html>

0
test/bob/test_init.sh Normal file
View File

12
test/parser/test01.md Normal file
View File

@ -0,0 +1,12 @@
# Major title
## Minor title
### Subtitle
- ici
- on
- est
- là
ok

18
test/parser/test02.md Normal file
View File

@ -0,0 +1,18 @@
# test
salut à tous
- item 1
- item 2
## test1
okkk
> blockquote
> again
> again and again
code
paragraph *em* and **strong**

157
test/parser/test_md_parser.sh Executable file
View File

@ -0,0 +1,157 @@
#!/usr/bin/env bash
# Text color variables
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color (reset)
# Ensure a script is provided
if [ -z "$1" ]; then
echo "Usage: $0 <markdown_parser_script>"
exit 1
fi
PARSER="$1"
# Check if the parser script exists
if [ ! -f "$PARSER" ]; then
echo "Error: $PARSER not found!"
exit 1
fi
# Determine if it's AWK or Shell (optional second argument)
PARSER_TYPE="bash" # Default to bash script
if [ -n "$2" ]; then
PARSER_TYPE="$2"
fi
# Define test cases as an array of markdown inputs and expected outputs
declare -a tests=(
"Header 1"
"# Header 1"
"<h1>Header 1</h1>"
"Header 2"
"## Header 2"
"<h2>Header 2</h2>"
"Header 3"
"### Header 3"
"<h3>Header 3</h3>"
"Header 4"
"#### Header 4"
"<h4>Header 4</h4>"
"Header 5"
"##### Header 5"
"<h5>Header 5</h5>"
"Header 6"
"###### Header 6"
"<h6>Header 6</h6>"
"Multiple headers 1"
$'# Header 1\n## Header 2'
"<h1>Header 1</h1><h2>Header 2</h2>"
# "Multiple headers 2"
# $'### Header 3\n\n## Header 2\n\n# Header 1'
# "<h3>Header 3</h3><h2>Header 2</h2><h1>Header 1</h1>"
"Unordered List"
$'- item\n* item'
"<ul><li>item</li><li>item</li></ul>"
"Ordered List"
$'1. item1\n1. item1\n3. item3'
"<ol><li>item1</li><li>item1</li><li>item3</li></ol>"
"Blockquote 1"
"> test of blockquote"
"<blockquote>test of blockquote</blockquote>"
"Blockquote 2"
$'> line1\n> line2'
"<blockquote>line1line2</blockquote>"
"Blockquote 2"
$'> line1\nline2'
"<blockquote>line1line2</blockquote>"
"Code Block 1"
$' code1'
"<pre><code>code1</code></pre>"
"Code Block 2"
$'\tcode1'
"<pre><code>code1</code></pre>"
"Paragraph 1"
"paragraph 1"
"<p>paragraph 1</p>"
"Paragraph 2"
"paragraph *emphasis* and **strong**"
"<p>paragraph <em>emphasis</em> and <strong>strong</strong></p>"
"Mix Code blocks and paragraphs 1"
$'First paragraph\n\n code block'
"<p>First paragraph</p><pre><code>code block</code></pre>"
"Mix Code blocks and paragraphs 2"
$'First paragraph\n\n code1\n code2\n\nSecond paragraph'
"<p>First paragraph</p><pre><code>code1code2</code></pre><p>Second paragraph</p>"
# You can add more test cases following the same format...
)
input="# test"
expected="<h1>test</h1>"
# Function to run a single test case
run_test() {
local input="$1"
local expected="$2"
local actual=""
# Get the actual output from the parser
if [ "$PARSER_TYPE" == "awk" ]; then
# Run AWK script with the input
actual=$(echo "$input" | awk -f "$PARSER" | tr -d '\n')
else
# Assume it's a shell script, run it
actual=$(echo "$input" | bash "$PARSER" | tr -d '\n')
fi
# Compare the actual output with the expected output
if [ "$actual" == "$expected" ]; then
echo -e "${GREEN}Test Passed!${NC}"
return 0
else
echo -e "${RED}Test Failed!${NC}"
echo "Input:"
echo "$input"
echo "Expected:"
echo "$expected"
echo "Got:"
echo "$actual"
return 1
fi
}
STATUS=0
# Main loop to run all test cases
num_tests=$((${#tests[@]} / 3)) # Divide by 2 because each test has input/output pair
for ((i = 0; i < num_tests; i++)); do
input="${tests[i * 3 + 1]}"
expected="${tests[i * 3 + 2]}"
echo "Test $((i + 1)):" ${tests[i * 3]}
run_test "$input" "$expected"
STATUS_i=$?
STATUS=$((STATUS+STATUS_i))
done
exit $STATUS

33
test/test.sh Executable file
View File

@ -0,0 +1,33 @@
#!/usr/bin/env bash
# Text color variables
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color (reset)
echo -e "${YELLOW}Testing markown parser :${NC}\n"
./test/parser/test_md_parser.sh ./lib/markdown.awk awk
echo -e "${YELLOW}Testing bob init :${NC}\n"
author="author"
blog="blog"
lang="fr"
dark="y"
./bob2 init << EOF
$author
$blog
$lang
$dark
EOF
conf_author=$(grep "^author=" .blog.conf | cut -d '=' -f 2)
conf_blog=$(grep "^blog=" .blog.conf | cut -d '=' -f 2)
conf_lang=$(grep "^lang=" .blog.conf | cut -d '=' -f 2)
conf_dark=$(grep "^dark=" .blog.conf | cut -d '=' -f 2)
rm -r posts
rm -r drafts