Skip to content

Commit

Permalink
Merge pull request #8 from viniciusalonso/redesign
Browse files Browse the repository at this point in the history
Internal refactor
  • Loading branch information
viniciusalonso committed Oct 26, 2023
2 parents 842b412 + 687f087 commit ff312fe
Show file tree
Hide file tree
Showing 16 changed files with 213 additions and 90 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[![Latest Version](https://img.shields.io/hexpm/v/simple_blog?color=b5a3be&label=Latest+version)](https://hexdocs.pm/simple_blog)

# Simple Blog



A blog engine written in elixir to generate static blogs from markdown.

Expand Down Expand Up @@ -39,7 +39,7 @@ $ mix deps.get
### Generate new blog post

```console
$ mix simple_blog.post.new "10 tips for new developers"
$ mix simple_blog.post "10 tips for new developers"
```

The file will be created at `blog/_posts/yyyy-mm-dd-10-tips-for-new-developers.md`.
Expand All @@ -50,7 +50,7 @@ The local http server is designed to local development of your blog. To start it

```console
$ mix clean
$ mix simple_blog.server.start
$ mix simple_blog.server
```

The server will be running at `http://localhost:4000`.
Expand Down
21 changes: 0 additions & 21 deletions lib/flat_files.ex

This file was deleted.

46 changes: 27 additions & 19 deletions lib/mix/tasks/simple_blog/compile.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,45 @@ defmodule Mix.Tasks.SimpleBlog.Compile do
require Logger

@moduledoc """
Module responsible for transpile markdown into html
Command responsible for transpile markdown into html
"""

@doc """
Generates a static blog at output folder
## Examples
iex> Mix.Tasks.SimpleBlog.Compile.run([])
"""
@impl Mix.Task
def run([]) do
def run([]), do: run(["blog", "output"])

def run([root_directory, output_directory]) do
posts =
"blog"
root_directory
|> SimpleBlog.Reader.Posts.read_from_dir()
|> SimpleBlog.Converter.Posts.markdown_to_html()
|> Enum.map(&SimpleBlog.Post.parse(&1))

index_html =
File.read("blog/index.html.eex")
File.read(root_directory <> "/index.html.eex")
|> SimpleBlog.Converter.Page.exx_to_html(posts)
|> rewrite_stylesheets()
|> rewrite_images()

File.mkdir("output")
{:ok, file} = File.open("output/index.html", [:write])
File.mkdir(output_directory)
{:ok, file} = File.open(output_directory <> "/index.html", [:write])

index_html
|> String.split("\n")
|> Enum.each(fn line -> IO.binwrite(file, rewrite_post_links(line) <> "\n") end)

File.close(file)

File.cp_r("blog/css", "output/css")
File.cp_r("blog/images", "output/images")
File.cp_r(root_directory <> "/css", output_directory <> "/css")
File.cp_r(root_directory <> "/images", output_directory <> "/images")

write_html_posts(posts)
write_html_posts(root_directory, output_directory, posts)
end

defp rewrite_stylesheets(html) do
Expand Down Expand Up @@ -104,34 +113,33 @@ defmodule Mix.Tasks.SimpleBlog.Compile do
end
end

defp write_html_posts(posts) do
defp write_html_posts(root_directory, output_directory, posts) do
posts
|> Enum.map(&create_folders/1)
|> IO.inspect()
|> Enum.map(&create_folders(&1, output_directory))

posts
|> Enum.map(&create_posts_html/1)
|> Enum.map(&create_posts_html(&1, root_directory, output_directory))
end

defp create_folders(post) do
defp create_folders(post, output_directory) do
post
|> SimpleBlog.Post.generate_html_dir("output/posts/")
|> SimpleBlog.Post.generate_html_dir(output_directory <> "/posts/")
|> File.mkdir_p()
end

def create_posts_html(post) do
dir = SimpleBlog.Post.generate_html_dir(post, "output/posts/")
def create_posts_html(post, root_directory, output_directory) do
dir = SimpleBlog.Post.generate_html_dir(post, output_directory <> "/posts/")
filename = SimpleBlog.Post.generate_html_filename(post)
postname = SimpleBlog.Post.generate_filename(post)

post =
"blog"
root_directory
|> SimpleBlog.Reader.Posts.read_post(postname)
|> SimpleBlog.Converter.Posts.markdown_to_html()
|> SimpleBlog.Post.parse()

result =
File.read("blog/post.html.eex")
File.read(root_directory <> "/post.html.eex")
|> SimpleBlog.Converter.Page.exx_to_html(post)
|> rewrite_stylesheets_post()
|> rewrite_images_post()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
defmodule Mix.Tasks.SimpleBlog.Post.New do
defmodule Mix.Tasks.SimpleBlog.Post do
use Mix.Task

@moduledoc """
Module responsible for generate a new blog post.
Command responsible for generate a new blog post.
"""

@doc """
It generates a new blog post
Generates a new blog post
## Examples
# iex> Mix.Tasks.SimpleBlog.Post.New.run(["My first blog post"])
# :ok
iex> Mix.Tasks.SimpleBlog.Post.run(["My first blog post"])
"Blog post created at blog_test/_posts/yyyy-mm-dd-my-first-blog-post.md"
"""
@impl Mix.Task
def run([]), do: Mix.shell().info(usage())
Expand All @@ -35,13 +35,20 @@ defmodule Mix.Tasks.SimpleBlog.Post.New do
IO.binwrite(file, "--->" <> "\n")
File.close(file)

Mix.shell().info("""
Blog post created at #{full_file_path}
""")

{:error, :enoent} ->
Mix.shell().info("""
The directory #{root_directory} was not found
""")
end
end

@doc """
Returns instructions about command usage
"""
def usage() do
"""
To generate a new blog post you should pass a title as string:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
defmodule Mix.Tasks.SimpleBlog.Server.Start do
defmodule Mix.Tasks.SimpleBlog.Server do
use Mix.Task
require Logger

@moduledoc """
Module responsible for a simple http server to allow local working on blog
Command responsible for a simple http server to allow local working on blog
"""

@doc """
Starts a local HTTP server in the port 4000
## Examples
iex> Mix.Tasks.SimpleBlog.Server.run([])
"Server running on localhost:4000"
"""
@impl Mix.Task
def run([]) do
webserver = [
Expand Down
18 changes: 0 additions & 18 deletions lib/simple_blog.ex

This file was deleted.

17 changes: 17 additions & 0 deletions lib/simple_blog/converter/page.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,21 @@
defmodule SimpleBlog.Converter.Page do
@moduledoc """
Module responsible for convert pages from eex to html
"""

@doc """
Convert eex file to html
## Examples
iex> posts = [%SimpleBlog.Post{title: "post 1"}, %SimpleBlog.Post{title: "post 2"}]
iex> SimpleBlog.Converter.Page.exx_to_html({:ok, "<%= for post <- posts do %><%= post.title %><% end %>"}, posts)
"post 1post 2"
iex> post = %SimpleBlog.Post{title: "post 1"}
iex> SimpleBlog.Converter.Page.exx_to_html({:ok, "<%= post.title %>"}, post)
"post 1"
"""
def exx_to_html({:ok, body}, posts) when is_list(posts) do
quoted = EEx.compile_string(body)

Expand Down
18 changes: 18 additions & 0 deletions lib/simple_blog/converter/posts.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,24 @@
defmodule SimpleBlog.Converter.Posts do
require Earmark

@moduledoc """
Module responsible for convert posts from markdown to html
"""

@doc """
Convert markdown file to html
## Examples
iex> SimpleBlog.Converter.Posts.markdown_to_html(["# post1", "# post2"])
["<h1>\\npost1</h1>\\n", "<h1>\\npost2</h1>\\n"]
iex> SimpleBlog.Converter.Posts.markdown_to_html("# post1")
"<h1>\\npost1</h1>\\n"
iex> SimpleBlog.Converter.Posts.markdown_to_html([])
[]
"""
def markdown_to_html([]), do: []

def markdown_to_html(files) when is_list(files) do
Expand Down
37 changes: 33 additions & 4 deletions lib/simple_blog/post.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ defmodule SimpleBlog.Post do

@extension "md"

defstruct title: "", tags: [], body: "", date: "", filename: ""
defstruct title: "", body: "", date: "", filename: ""

@doc """
Generate filename for blog post
Generate directory name for blog post
## Examples
iex> SimpleBlog.Post.generate_filename(%SimpleBlog.Post{ title: "My first blog post", date: ~D[2023-10-04] })
"2023-10-04-my-first-blog-post.md"
iex> SimpleBlog.Post.generate_filename(%SimpleBlog.Post{ title: "My first blog post", date: ~D[2023-10-04]})
"2023-10-04-my-first-blog-post.md"
"""
def generate_filename(%SimpleBlog.Post{title: title, date: date}) do
normalized_title =
Expand All @@ -24,6 +24,18 @@ defmodule SimpleBlog.Post do
"#{date}-#{normalized_title}.#{@extension}"
end

@doc """
Parse comment with data into %SimpleBlog.Post struct
## Examples
iex> body = "<!---
...>filename: 2023-10-25-dev-onboarding.md
...>title: Dev onboarding
...>date: 2023-10-25
...> --->"
iex> SimpleBlog.Post.parse(body)
%SimpleBlog.Post{body: body, title: "Dev onboarding", date: "2023-10-25", filename: "2023-10-25-dev-onboarding.md"}
"""
def parse(body) do
[_, filename_line, title_line, date_line | _] = String.split(body, "\n")

Expand All @@ -34,14 +46,31 @@ defmodule SimpleBlog.Post do
%SimpleBlog.Post{body: body, title: title, date: date, filename: filename}
end

@doc """
Generate filename for blog post
## Examples
iex> SimpleBlog.Post.generate_html_dir(%SimpleBlog.Post{date: "2023-10-04"}, "output")
"output/2023/10/04/"
"""
def generate_html_dir(%SimpleBlog.Post{date: date}, base_dir) do
[year, month, day] = String.split(date, "-")
base_dir <> "/" <> year <> "/" <> month <> "/" <> day <> "/"
end

@doc """
Generate html filename for blog post
## Examples
iex> SimpleBlog.Post.generate_html_filename(%SimpleBlog.Post{title: "doctests with elixir"})
"doctests-with-elixir.html"
"""
def generate_html_filename(%SimpleBlog.Post{title: title}) do
title
|> String.replace(" ", "-")
|> String.downcase()
|> Kernel.<>(".html")
end
end
20 changes: 19 additions & 1 deletion lib/simple_blog/reader/posts.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
defmodule SimpleBlog.Reader.Posts do
require Logger
@moduledoc """
Module responsible for read blog posts
"""

@doc """
Reads content from markdown files located in _posts
## Examples
iex> SimpleBlog.Reader.Posts.read_from_dir("blog")
["## post title 1", "## post title 2"]
"""
def read_from_dir(root_directory) do
posts_directory = root_directory <> "/_posts/"

Expand All @@ -10,6 +20,14 @@ defmodule SimpleBlog.Reader.Posts do
end
end

@doc """
Reads content from markdown file for specific post
## Examples
iex> SimpleBlog.Reader.Posts.read_post("blog", "2023-10-25-metaprogramming-in-ruby.md")
"### Metaprogramming in ruby"
"""
def read_post(root_directory, post) do
posts_directory = root_directory <> "/_posts/"
post_path = posts_directory <> post
Expand Down
Loading

0 comments on commit ff312fe

Please sign in to comment.