1
0
mirror of https://github.com/avinal/avinal.github.io.git synced 2026-07-04 07:40:09 +05:30

add metadata parsing

Signed-off-by: Avinal Kumar <avinal.xlvii@gmail.com>
This commit is contained in:
2022-09-13 23:26:04 +05:30
parent d71d020d85
commit abe8d6ee20
5 changed files with 193 additions and 93 deletions
+4 -3
View File
@@ -6,18 +6,19 @@
"elm-version": "0.19.1", "elm-version": "0.19.1",
"dependencies": { "dependencies": {
"direct": { "direct": {
"MaybeJustJames/yaml": "2.1.2",
"elm/browser": "1.0.2", "elm/browser": "1.0.2",
"elm/core": "1.0.5", "elm/core": "1.0.5",
"elm/html": "1.0.0", "elm/html": "1.0.0",
"elm/http": "2.0.0", "elm/http": "2.0.0",
"elm/url": "1.0.0", "elm/parser": "1.1.0",
"hecrj/html-parser": "2.4.0" "elm/url": "1.0.0"
}, },
"indirect": { "indirect": {
"elm/bytes": "1.0.8", "elm/bytes": "1.0.8",
"elm/file": "1.0.5", "elm/file": "1.0.5",
"elm/json": "1.1.3", "elm/json": "1.1.3",
"elm/parser": "1.1.0", "elm/regex": "1.0.0",
"elm/time": "1.0.0", "elm/time": "1.0.0",
"elm/virtual-dom": "1.0.3", "elm/virtual-dom": "1.0.3",
"rtfeldman/elm-hex": "1.0.0" "rtfeldman/elm-hex": "1.0.0"
+21 -21
View File
@@ -16,9 +16,9 @@
<div id="app"></div> <div id="app"></div>
<script src="/website/app.js"></script> <script src="/website/app.js"></script>
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" crossorigin="anonymous"></script> --> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" crossorigin="anonymous"></script>
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.7/clipboard.min.js" <script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.7/clipboard.min.js"
crossorigin="anonymous"></script> --> crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<script src="/website/prism.js"></script> <script src="/website/prism.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/plugins/autoloader/prism-autoloader.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
@@ -73,25 +73,25 @@
} }
}) })
document.getElementById("insert-here").innerHTML = marked.parse(markdowndata); document.getElementById("insert-here").innerHTML = marked.parse(markdowndata);
document.getElementById("toc-entries").innerHTML = toc; // document.getElementById("toc-entries").innerHTML = toc;
});
$(function () {
// copy-btn HTML
var btn = "<span class=\"btn-copy tooltipped tooltipped-sw\" aria-label=\"Copy to clipboard!\">";
btn += '<i class="far fa-clone"></i>';
btn += '</span>';
// mount it!
$(".highlight table").before(btn);
var clip = new ClipboardJS('.btn-copy', {
text: function (trigger) {
return Array.from(trigger.nextElementSibling.querySelectorAll('.code')).reduce((str, it) => str + it.innerText + '\n', '')
}
});
clip.on('success', function (e) {
e.trigger.setAttribute('aria-label', "Copied!");
e.clearSelection();
})
}); });
// $(function () {
// // copy-btn HTML
// var btn = "<span class=\"btn-copy tooltipped tooltipped-sw\" aria-label=\"Copy to clipboard!\">";
// btn += '<i class="far fa-clone"></i>';
// btn += '</span>';
// // mount it!
// $(".highlight table").before(btn);
// var clip = new ClipboardJS('.btn-copy', {
// text: function (trigger) {
// return Array.from(trigger.nextElementSibling.querySelectorAll('.code')).reduce((str, it) => str + it.innerText + '\n', '')
// }
// });
// clip.on('success', function (e) {
// e.trigger.setAttribute('aria-label', "Copied!");
// e.clearSelection();
// })
// });
</script> </script>
+25 -1
View File
@@ -1,5 +1,29 @@
module Base exposing (urlPrefix) module Base exposing (urlPrefix, contentUrlPrefix)
{-| The base URL for accessing the content for the site
Using Github CDN for now, but this could be changed to a custom domain
-}
contentBase : String
contentBase =
"https://raw.githubusercontent.com"
{-| The Github user name for the site
-}
user : String
user =
"avinal"
urlPrefix : String urlPrefix : String
urlPrefix = urlPrefix =
"website" "website"
contentUrlPrefix : String
contentUrlPrefix =
contentBase ++ "/" ++ user ++ "/" ++ urlPrefix ++ "/main/content/"
+115 -55
View File
@@ -3,10 +3,9 @@ port module Blog exposing (..)
import Base exposing (urlPrefix) import Base exposing (urlPrefix)
import Html exposing (..) import Html exposing (..)
import Html.Attributes exposing (class, href, id, style) import Html.Attributes exposing (class, href, id, style)
import Html.Parser
import Html.Parser.Util
import Http exposing (Error(..)) import Http exposing (Error(..))
import Url exposing (Protocol(..)) import Url exposing (Protocol(..))
import Yaml.Decode as Yaml exposing (Decoder, field, list, string)
@@ -14,10 +13,10 @@ import Url exposing (Protocol(..))
type alias Model = type alias Model =
{ blog : Blog { blog : Maybe Blog
, markDownUrl : String , markdownUrl : String
, markDown : String
, success : Bool , success : Bool
, fragment : String
} }
@@ -26,13 +25,17 @@ type alias Model =
type alias Blog = type alias Blog =
{ title : String { meta : YamlMeta
, url : String
, description : String
, content : String , content : String
, category : String }
, tags : List String
, date : String
initialModel : Model
initialModel =
{ blog = Nothing
, markdownUrl = ""
, success = False
, fragment = ""
} }
@@ -48,8 +51,7 @@ view model =
div [ class "foo-interface" ] div [ class "foo-interface" ]
[ div [ class "foo-console foo-terminal foo-active" ] [ div [ class "foo-console foo-terminal foo-active" ]
[ div [ class "main-wrapper" ] [ div [ class "main-wrapper" ]
[ viewToc model.success [ main_ [ class "main-content", id "content" ]
, main_ [ class "main-content", id "content" ]
[ viewArticle model.success ] [ viewArticle model.success ]
] ]
] ]
@@ -61,17 +63,16 @@ viewToc show =
if show then if show then
div div
[ class "toc" [ class "toc"
, style "display"
(if show then
"block"
else
"none"
)
] ]
[ aside [ class "document-toc-container" ] [ aside [ class "document-toc-container" ]
[ section [ class "document-toc" ] [ section [ class "document-toc" ]
[ h2 [ class "document-toc-heading" ] [ text "In this page" ] [ h2 [ class "document-toc-heading" ]
[ if show then
text "In this page"
else
text ""
]
, ul , ul
[ class "document-toc-list", id "toc-entries" ] [ class "document-toc-list", id "toc-entries" ]
[] []
@@ -125,18 +126,44 @@ viewMetadata show =
type Msg type Msg
= GetMarkdown = GetMarkdown
| DataReceived (Result Http.Error String) | DataReceived (Result Http.Error String)
| NoSuchPage
init : Maybe String -> ( Model, Cmd Msg ) init : List String -> ( Model, Cmd Msg )
init slug = init pathList =
( { blog = initBlog case pathList of
, markDownUrl = finalUrl slug [ category, slug, fragment ] ->
, markDown = "" ( { initialModel
, success = False | markdownUrl = Base.contentUrlPrefix ++ "posts/" ++ category ++ "/" ++ slug ++ ".md"
, fragment = fragment
} }
, getMarkdown <| finalUrl slug , getMarkdown (Base.contentUrlPrefix ++ "posts/" ++ category ++ "/" ++ slug ++ ".md")
) )
[ category, slug ] ->
( { initialModel
| markdownUrl = Base.contentUrlPrefix ++ "posts/" ++ category ++ "/" ++ slug ++ ".md"
}
, getMarkdown (Base.contentUrlPrefix ++ "posts/" ++ category ++ "/" ++ slug ++ ".md")
)
-- [ "categories" ] ->
-- ( { blog = Nothing
-- , markdownUrl = urlPrefix ++ "/categories" ++ ".md"
-- , markDown = ""
-- , success = False
-- , fragment = ""
-- }
-- , getMarkdown (urlPrefix ++ "/categories" ++ ".md")
-- )
[] ->
( initialModel
, Cmd.none
)
_ ->
( initialModel, Cmd.none )
getMarkdown : String -> Cmd Msg getMarkdown : String -> Cmd Msg
getMarkdown url = getMarkdown url =
@@ -164,29 +191,25 @@ finalUrl slug =
++ ".md" ++ ".md"
initBlog : Blog
initBlog =
{ title = ""
, url = ""
, description = ""
, content = ""
, category = ""
, tags = []
, date = ""
}
update : Msg -> Model -> ( Model, Cmd Msg ) update : Msg -> Model -> ( Model, Cmd Msg )
update msg model = update msg model =
case msg of case msg of
GetMarkdown -> GetMarkdown ->
( model, Http.get { url = model.markDownUrl, expect = Http.expectString DataReceived } ) ( model, Http.get { url = model.markdownUrl, expect = Http.expectString DataReceived } )
DataReceived (Ok data) -> DataReceived (Ok data) ->
( { model | markDown = data, success = True }, sendString data ) case splitMetaContent data of
Ok blog ->
( { model | blog = Just blog, success = True }, sendString blog.content )
DataReceived (Err err) -> Err _ ->
( { model | success = False, markDown = errorToString err }, Cmd.none ) ( { model | success = False }, Cmd.none )
DataReceived (Err _) ->
( { model | success = False }, Cmd.none )
NoSuchPage ->
( { model | success = False }, Cmd.none )
errorToString : Http.Error -> String errorToString : Http.Error -> String
@@ -214,16 +237,6 @@ errorToString error =
errorMessage errorMessage
textToHtml : String -> List (Html.Html msg)
textToHtml text =
case Html.Parser.run text of
Ok nodes ->
Html.Parser.Util.toVirtualDom nodes
Err _ ->
[]
-- main : Program (String, String) Model Msg -- main : Program (String, String) Model Msg
-- main = -- main =
@@ -237,7 +250,7 @@ textToHtml text =
-- [ class "foo-term-story section-content" ] -- [ class "foo-term-story section-content" ]
-- [ input -- [ input
-- [ placeholder "Enter URL to a markdown file" -- [ placeholder "Enter URL to a markdown file"
-- , value model.markDownUrl -- , value model.markdownUrl
-- , onInput StoreInput -- , onInput StoreInput
-- ] -- ]
-- [] -- []
@@ -247,3 +260,50 @@ textToHtml text =
-- else -- else
-- div [ class "foo-error" ] [ text model.markDown ] -- div [ class "foo-error" ] [ text model.markDown ]
-- ] -- ]
-- YAML Stuff
type alias YamlMeta =
{ title : String
, date : String
, description : Maybe String
, tags : List String
, category : String
, image : Maybe String
, modified : Maybe String
}
splitMetaContent : String -> Result String Blog
splitMetaContent data =
let
headIndices : List Int
headIndices =
String.indices "---" data |> List.take 2
metadata =
String.slice ((Maybe.withDefault 0 <| List.head headIndices) + 3)
((Maybe.withDefault 0 <| List.head <| List.reverse headIndices) - 1)
data
content =
String.dropLeft ((Maybe.withDefault 0 <| List.head <| List.reverse headIndices) + 3) data
in
case Yaml.fromString metaDecoder metadata of
Ok meta ->
Ok { meta = meta, content = content }
Err _ ->
Err "YAML front matter parsing failed"
metaDecoder : Decoder YamlMeta
metaDecoder =
Yaml.map7 YamlMeta
(field "title" string)
(field "date" string)
(field "description" (Yaml.maybe string))
(field "tags" (list string))
(field "category" string)
(field "image" (Yaml.maybe string))
(field "modified" (Yaml.maybe string))
+23 -8
View File
@@ -149,12 +149,21 @@ update msg model =
GotBlogMsg blogMsg -> GotBlogMsg blogMsg ->
case model.page of case model.page of
BlogPage blog -> BlogPage blogModel ->
let
title =
case blogModel.blog of
Just blog ->
blog.meta.title
Nothing ->
"Blog"
in
toBlog toBlog
{ model { model
| title = blog.blog.title ++ " | " ++ model.title | title = title ++ " | " ++ model.title
} }
(Blog.update blogMsg blog) (Blog.update blogMsg blogModel)
_ -> _ ->
( model, Cmd.none ) ( model, Cmd.none )
@@ -219,9 +228,9 @@ init _ url key =
type Route type Route
= Splash = Splash
| Blog | Blog
| BlogPost String String (Maybe String)
| Terminal | Terminal
| Static | Static
| BlogPost String String
@@ -234,7 +243,7 @@ parser =
[ Parser.map Splash Parser.top [ Parser.map Splash Parser.top
, Parser.map Splash (s urlPrefix) , Parser.map Splash (s urlPrefix)
, Parser.map Blog (s urlPrefix </> s "posts") , Parser.map Blog (s urlPrefix </> s "posts")
, Parser.map BlogPost (s urlPrefix </> s "posts" </> Parser.string </> Parser.string) , Parser.map BlogPost (s urlPrefix </> s "posts" </> Parser.string </> Parser.string </> Parser.fragment identity)
, Parser.map Static (s urlPrefix </> s "pages") , Parser.map Static (s urlPrefix </> s "pages")
, Parser.map Terminal (s urlPrefix </> s "terminal") , Parser.map Terminal (s urlPrefix </> s "terminal")
] ]
@@ -248,11 +257,17 @@ updateUrl model =
|> toSplash model |> toSplash model
Just Blog -> Just Blog ->
Blog.init Nothing Blog.init []
|> toBlog model |> toBlog model
Just (BlogPost category slug) -> Just (BlogPost category title fragment) ->
Blog.init (Just (category ++ "/" ++ slug)) case fragment of
Just something ->
Blog.init [ category, title, something ]
|> toBlog model
Nothing ->
Blog.init [ category, title ]
|> toBlog model |> toBlog model
Just Terminal -> Just Terminal ->