mirror of
https://github.com/avinal/avinal.github.io.git
synced 2026-07-03 23:30:09 +05:30
remove blogs from elm, switch to hugo
Signed-off-by: Avinal Kumar <avinal.xlvii@gmail.com> rh-pre-commit.version: 2.2.0 rh-pre-commit.check-secrets: ENABLED
This commit is contained in:
@@ -1,86 +0,0 @@
|
||||
module Layouts.Blog exposing (Model, Msg, Props, layout)
|
||||
|
||||
import Components.Footer exposing (footerLinksToSide)
|
||||
import Effect exposing (Effect)
|
||||
import Html
|
||||
import Html.Attributes exposing (class, id)
|
||||
import Layout exposing (Layout)
|
||||
import Route exposing (Route)
|
||||
import Shared
|
||||
import Utils.Constants exposing (..)
|
||||
import View exposing (View)
|
||||
|
||||
|
||||
type alias Props =
|
||||
{}
|
||||
|
||||
|
||||
layout : Props -> Shared.Model -> Route () -> Layout () Model Msg contentMsg
|
||||
layout props shared route =
|
||||
Layout.new
|
||||
{ init = init
|
||||
, update = update
|
||||
, view = view
|
||||
, subscriptions = subscriptions
|
||||
}
|
||||
|
||||
|
||||
|
||||
-- MODEL
|
||||
|
||||
|
||||
type alias Model =
|
||||
{}
|
||||
|
||||
|
||||
init : () -> ( Model, Effect Msg )
|
||||
init _ =
|
||||
( {}
|
||||
, Effect.none
|
||||
)
|
||||
|
||||
|
||||
|
||||
-- UPDATE
|
||||
|
||||
|
||||
type Msg
|
||||
= ReplaceMe
|
||||
|
||||
|
||||
update : Msg -> Model -> ( Model, Effect Msg )
|
||||
update msg model =
|
||||
case msg of
|
||||
ReplaceMe ->
|
||||
( model
|
||||
, Effect.none
|
||||
)
|
||||
|
||||
|
||||
subscriptions : Model -> Sub Msg
|
||||
subscriptions model =
|
||||
Sub.none
|
||||
|
||||
|
||||
|
||||
-- VIEW
|
||||
|
||||
blogTheme : String
|
||||
blogTheme =
|
||||
"prose prose-invert mx-auto lg:prose-lg prose-a:decoration-cyan-500 hover:prose-a:decoration-pink-500"
|
||||
|
||||
|
||||
view : { toContentMsg : Msg -> contentMsg, content : View contentMsg, model : Model } -> View contentMsg
|
||||
view { toContentMsg, model, content } =
|
||||
{ title = content.title
|
||||
, body =
|
||||
[ Html.div [ class "min-h-screen flex flex-col justify-center relative overflow-hidden" ]
|
||||
[ Html.div [ class "relative w-full bg-neutral md:max-w-3xl md:mx-auto lg:max-w-4xl lg:pb-28" ]
|
||||
[ Html.article [ class blogTheme ]
|
||||
content.body
|
||||
, Html.div [ id "remark42", class "md:px-4 mb-16" ] []
|
||||
]
|
||||
]
|
||||
, footerLinksToSide
|
||||
]
|
||||
}
|
||||
@@ -1,168 +0,0 @@
|
||||
module Pages.Posts exposing (Model, Msg, page)
|
||||
|
||||
import Components.Footer exposing (footerLinksToSide)
|
||||
import Effect exposing (Effect)
|
||||
import Html exposing (Html)
|
||||
import Html.Attributes exposing (alt, class, datetime, href, src, target)
|
||||
import Http
|
||||
import Json.Decode as Json
|
||||
import Page exposing (Page)
|
||||
import Route exposing (Route)
|
||||
import Shared
|
||||
import Url exposing (Protocol(..))
|
||||
import Utils.Constants exposing (..)
|
||||
import Utils.Utils as UU
|
||||
import View exposing (View)
|
||||
|
||||
|
||||
page : Shared.Model -> Route () -> Page Model Msg
|
||||
page _ _ =
|
||||
Page.new
|
||||
{ init = init
|
||||
, update = update
|
||||
, subscriptions = subscriptions
|
||||
, view = view
|
||||
}
|
||||
|
||||
|
||||
|
||||
-- INIT
|
||||
|
||||
|
||||
type alias JsonMeta =
|
||||
{ title : String
|
||||
, date : String
|
||||
, description : String
|
||||
, category : String
|
||||
, slug : String
|
||||
, image : String
|
||||
}
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ error : Maybe String
|
||||
, blogList : Maybe (List JsonMeta)
|
||||
}
|
||||
|
||||
|
||||
init : () -> ( Model, Effect Msg )
|
||||
init () =
|
||||
let
|
||||
cmd : Cmd Msg
|
||||
cmd =
|
||||
Http.get
|
||||
{ url = "/content/posts/posts.json"
|
||||
, expect = Http.expectJson BloglistReceived (Json.list jsonMetaDecoder)
|
||||
}
|
||||
in
|
||||
( { error = Nothing
|
||||
, blogList = Nothing
|
||||
}
|
||||
, Effect.sendCmd cmd
|
||||
)
|
||||
|
||||
|
||||
|
||||
-- UPDATE
|
||||
|
||||
|
||||
type Msg
|
||||
= BloglistReceived (Result Http.Error (List JsonMeta))
|
||||
|
||||
|
||||
update : Msg -> Model -> ( Model, Effect Msg )
|
||||
update msg model =
|
||||
case msg of
|
||||
BloglistReceived (Ok data) ->
|
||||
( { model | blogList = Just data }
|
||||
, Effect.none
|
||||
)
|
||||
|
||||
BloglistReceived (Err err) ->
|
||||
( { model | error = Just (UU.errorToString err) }, Effect.none )
|
||||
|
||||
|
||||
|
||||
-- SUBSCRIPTIONS
|
||||
|
||||
|
||||
subscriptions : Model -> Sub Msg
|
||||
subscriptions _ =
|
||||
Sub.none
|
||||
|
||||
|
||||
|
||||
-- VIEW
|
||||
|
||||
|
||||
view : Model -> View Msg
|
||||
view model =
|
||||
let
|
||||
maincard : List JsonMeta -> Html msg
|
||||
maincard bloglist =
|
||||
case bloglist of
|
||||
first :: rest ->
|
||||
Html.div [ class "max-w-6xl p-6 mx-auto space-y-6 sm:space-y-12 mb-16" ]
|
||||
[ Html.div [ class "block max-w-sm gap-3 mx-auto sm:max-w-full group hover:no-underline focus:no-underline lg:grid lg:grid-cols-12 bg-neutral-900" ]
|
||||
[ Html.a [ class "lg:col-span-7", href <| "/posts/" ++ first.category ++ "/" ++ first.slug ] [ Html.img [ class "object-cover w-full h-64 rounded sm:h-96 lg:col-span-7", src first.image, alt first.title ] [] ]
|
||||
, Html.div [ class "p-6 space-y-2 lg:col-span-5" ]
|
||||
[ Html.a [ href <| "/posts/" ++ first.category ++ "/" ++ first.slug ]
|
||||
[ Html.h3 [ class "text-2xl font-semibold sm:text-4xl group-hover:underline group-focus:underline" ]
|
||||
[ Html.text first.title ]
|
||||
, Html.time [ class "text-gray-400", datetime first.date ] [ Html.text <| UU.getFormattedDate first.date False ]
|
||||
, Html.p [] [ Html.text <| String.left 200 first.description ]
|
||||
]
|
||||
, Html.a [ href <| "/posts/" ++ first.category, target "_blank" ] [ UU.categoryNtags first.category [] ]
|
||||
]
|
||||
]
|
||||
, Html.div [ class "grid justify-center grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3" ] <| List.map card rest
|
||||
]
|
||||
|
||||
[] ->
|
||||
Html.div [] []
|
||||
|
||||
card : JsonMeta -> Html msg
|
||||
card blog =
|
||||
Html.div [ class "max-w-sm mx-auto group hover:no-underline focus:no-underline bg-neutral-900", href ("/posts/" ++ blog.category ++ "/" ++ blog.slug) ]
|
||||
[ Html.a [ href <| "/posts/" ++ blog.category ++ "/" ++ blog.slug ] [ Html.img [ class "object-cover w-full h-44 rounded", src blog.image, alt blog.title ] [] ]
|
||||
, Html.div [ class "p-6 space-y-2" ]
|
||||
[ Html.a [ href <| "/posts/" ++ blog.category ++ "/" ++ blog.slug ]
|
||||
[ Html.h3 [ class "text-2xl font-semibold group-hover:underline group-focus:underline" ] [ Html.text blog.title ]
|
||||
, Html.time [ class " text-gray-400", datetime blog.date ] [ Html.text <| UU.getFormattedDate blog.date False ]
|
||||
, Html.p [] [ Html.text <| String.left 200 blog.description ]
|
||||
]
|
||||
, Html.a [ href <| "/posts/" ++ blog.category, target "_blank" ] [ UU.categoryNtags blog.category [] ]
|
||||
]
|
||||
]
|
||||
in
|
||||
case model.blogList of
|
||||
Just blogList ->
|
||||
{ title = "Blog"
|
||||
, body =
|
||||
[ Html.section [ class "text-gray-100" ]
|
||||
[ Html.h1 [ class "text-5xl font-bold mb-6 mt-12 text-center text-white" ] [ Html.text <| "Welcome to my blog" ]
|
||||
, maincard blogList
|
||||
, footerLinksToSide
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
Nothing ->
|
||||
{ title = "Something went wrong"
|
||||
, body = [ Html.text <| Maybe.withDefault "" model.error ]
|
||||
}
|
||||
|
||||
|
||||
|
||||
-- UTILS
|
||||
|
||||
|
||||
jsonMetaDecoder : Json.Decoder JsonMeta
|
||||
jsonMetaDecoder =
|
||||
Json.map6 JsonMeta
|
||||
(Json.field "title" Json.string)
|
||||
(Json.field "date" Json.string)
|
||||
(Json.field "description" Json.string)
|
||||
(Json.field "category" Json.string)
|
||||
(Json.field "slug" Json.string)
|
||||
(Json.field "image" Json.string)
|
||||
@@ -1,164 +0,0 @@
|
||||
module Pages.Posts.Category_ exposing (Model, Msg, page)
|
||||
|
||||
import Components.Footer exposing (footerLinksToSide)
|
||||
import Effect exposing (Effect)
|
||||
import Html exposing (Html)
|
||||
import Html.Attributes exposing (alt, class, datetime, href, src)
|
||||
import Http
|
||||
import Json.Decode as Json
|
||||
import Page exposing (Page)
|
||||
import Route exposing (Route)
|
||||
import Shared
|
||||
import Utils.Constants exposing (..)
|
||||
import Utils.Utils as UU
|
||||
import View exposing (View)
|
||||
|
||||
|
||||
page : Shared.Model -> Route { category : String } -> Page Model Msg
|
||||
page _ route =
|
||||
Page.new
|
||||
{ init = init route
|
||||
, update = update
|
||||
, subscriptions = subscriptions
|
||||
, view = view
|
||||
}
|
||||
|
||||
|
||||
|
||||
-- INIT
|
||||
|
||||
|
||||
type alias JsonMeta =
|
||||
{ title : String
|
||||
, date : String
|
||||
, description : String
|
||||
, category : String
|
||||
, slug : String
|
||||
, image : String
|
||||
}
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ error : Maybe String
|
||||
, blogList : Maybe (List JsonMeta)
|
||||
, category : String
|
||||
}
|
||||
|
||||
|
||||
init : Route { category : String } -> () -> ( Model, Effect Msg )
|
||||
init route () =
|
||||
let
|
||||
cmd : Cmd Msg
|
||||
cmd =
|
||||
Http.get
|
||||
{ url = "/content/posts/posts.json"
|
||||
, expect = Http.expectJson BloglistReceived (Json.list jsonMetaDecoder)
|
||||
}
|
||||
in
|
||||
( { error = Nothing
|
||||
, blogList = Nothing
|
||||
, category = route.params.category
|
||||
}
|
||||
, Effect.sendCmd cmd
|
||||
)
|
||||
|
||||
|
||||
|
||||
-- UPDATE
|
||||
|
||||
|
||||
type Msg
|
||||
= BloglistReceived (Result Http.Error (List JsonMeta))
|
||||
|
||||
|
||||
update : Msg -> Model -> ( Model, Effect Msg )
|
||||
update msg model =
|
||||
case msg of
|
||||
BloglistReceived (Ok data) ->
|
||||
( { model | blogList = Just data }
|
||||
, Effect.none
|
||||
)
|
||||
|
||||
BloglistReceived (Err err) ->
|
||||
( { model | error = Just (UU.errorToString err) }, Effect.none )
|
||||
|
||||
|
||||
|
||||
-- SUBSCRIPTIONS
|
||||
|
||||
|
||||
subscriptions : Model -> Sub Msg
|
||||
subscriptions _ =
|
||||
Sub.none
|
||||
|
||||
|
||||
|
||||
-- VIEW
|
||||
|
||||
|
||||
view : Model -> View Msg
|
||||
view model =
|
||||
let
|
||||
card : JsonMeta -> Html msg
|
||||
card blog =
|
||||
Html.a [ class "flex flex-wrap mb-6 ", href <| "/posts/" ++ blog.category ++ "/" ++ blog.slug ]
|
||||
[ Html.div [ class "grow-0 shrink-0 basis-auto w-full md:w-3/12 md:mb-0 ml-auto" ]
|
||||
[ Html.div [ class "overflow-hidden relative bg-no-repeat bg-cover ripple" ]
|
||||
[ Html.img [ src blog.image, class "w-full h-44 object-cover rounded", alt blog.title ] []
|
||||
]
|
||||
]
|
||||
, Html.div [ class "grow-0 shrink-0 basis-auto w-full md:w-9/12 xl:w-7/12 p-3 md:mb-0 mr-auto bg-neutral-900" ]
|
||||
[ Html.h5 [ class "text-2xl font-bold mb-2" ] [ Html.text blog.title ]
|
||||
, Html.time [ class "text-gray-400 text-sm", datetime blog.date ] [ Html.text <| UU.getFormattedDate blog.date True ]
|
||||
, Html.p [ class "text-gray-500 mt-4 text-md" ] [ Html.text <| String.left 200 blog.description ]
|
||||
]
|
||||
]
|
||||
in
|
||||
case model.blogList of
|
||||
Just blogList ->
|
||||
let
|
||||
filteredList =
|
||||
filterBlogListByCategory blogList model.category
|
||||
in
|
||||
case filteredList of
|
||||
[] ->
|
||||
{ title = "No posts in this category"
|
||||
, body = []
|
||||
}
|
||||
|
||||
clist ->
|
||||
{ title = "Posts in " ++ model.category ++ " category"
|
||||
, body =
|
||||
[ Html.div []
|
||||
[ Html.section [ class "mb-32 text-gray-200 text-center md:text-left" ] <|
|
||||
Html.h1 [ class "text-5xl font-bold mb-12 mt-12 text-center text-white" ] [ Html.text "Posts in ", Html.i [ class "text-pink-600" ] [ Html.text model.category ], Html.text " category" ]
|
||||
:: List.map card clist
|
||||
, footerLinksToSide
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
Nothing ->
|
||||
{ title = "There is no such category"
|
||||
, body = []
|
||||
}
|
||||
|
||||
|
||||
|
||||
-- UTILS
|
||||
|
||||
|
||||
jsonMetaDecoder : Json.Decoder JsonMeta
|
||||
jsonMetaDecoder =
|
||||
Json.map6 JsonMeta
|
||||
(Json.field "title" Json.string)
|
||||
(Json.field "date" Json.string)
|
||||
(Json.field "description" Json.string)
|
||||
(Json.field "category" Json.string)
|
||||
(Json.field "slug" Json.string)
|
||||
(Json.field "image" Json.string)
|
||||
|
||||
|
||||
filterBlogListByCategory : List JsonMeta -> String -> List JsonMeta
|
||||
filterBlogListByCategory blogList category =
|
||||
List.filter (\meta -> meta.category == category) blogList
|
||||
@@ -1,239 +0,0 @@
|
||||
module Pages.Posts.Category_.Post_ exposing (Model, Msg, page)
|
||||
|
||||
import Effect exposing (Effect)
|
||||
import Html exposing (Html)
|
||||
import Html.Attributes exposing (alt, class, datetime, href, src, title)
|
||||
import Http
|
||||
import Layouts
|
||||
import Page exposing (Page)
|
||||
import Route exposing (Route)
|
||||
import Shared
|
||||
import String exposing (words)
|
||||
import Url exposing (Protocol(..))
|
||||
import Utils.Utils as UU
|
||||
import View exposing (View)
|
||||
import Yaml.Decode as Yaml
|
||||
|
||||
|
||||
page : Shared.Model -> Route { category : String, post : String } -> Page Model Msg
|
||||
page _ route =
|
||||
Page.new
|
||||
{ init = init route
|
||||
, update = update
|
||||
, subscriptions = subscriptions
|
||||
, view = view
|
||||
}
|
||||
|> Page.withLayout layout
|
||||
|
||||
|
||||
|
||||
-- LAYOUT
|
||||
|
||||
|
||||
layout : Model -> Layouts.Layout Msg
|
||||
layout _ =
|
||||
Layouts.Blog
|
||||
{}
|
||||
|
||||
|
||||
|
||||
-- INIT
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ blog : Maybe Blog
|
||||
, requestUrl : String
|
||||
, success : Bool
|
||||
, fragment : String
|
||||
, error : Maybe String
|
||||
}
|
||||
|
||||
|
||||
type alias Blog =
|
||||
{ meta : YamlMeta
|
||||
, content : String
|
||||
, words : Int
|
||||
}
|
||||
|
||||
|
||||
init : Route { category : String, post : String } -> () -> ( Model, Effect Msg )
|
||||
init route () =
|
||||
let
|
||||
requestUrl =
|
||||
UU.contentUrl
|
||||
{ category = route.params.category
|
||||
, post = route.params.post
|
||||
}
|
||||
|
||||
cmd : Cmd Msg
|
||||
cmd =
|
||||
Http.get
|
||||
{ url = requestUrl
|
||||
, expect = Http.expectString RawMarkdownReceived
|
||||
}
|
||||
in
|
||||
( { blog = Nothing
|
||||
, requestUrl = requestUrl
|
||||
, success = False
|
||||
, fragment = Maybe.withDefault "" route.hash
|
||||
, error = Nothing
|
||||
}
|
||||
, Effect.sendCmd cmd
|
||||
)
|
||||
|
||||
|
||||
|
||||
-- UPDATE
|
||||
|
||||
|
||||
type Msg
|
||||
= RawMarkdownReceived (Result Http.Error String)
|
||||
|
||||
|
||||
update : Msg -> Model -> ( Model, Effect Msg )
|
||||
update msg model =
|
||||
case msg of
|
||||
RawMarkdownReceived (Ok data) ->
|
||||
case splitMetaContent data of
|
||||
Ok blog ->
|
||||
( { model | blog = Just blog, success = True }, Effect.none )
|
||||
|
||||
Err err ->
|
||||
( { model | success = False, error = Just err }, Effect.none )
|
||||
|
||||
RawMarkdownReceived (Err err) ->
|
||||
( { model | success = False, error = Just (UU.errorToString err) }, Effect.none )
|
||||
|
||||
|
||||
|
||||
-- SUBSCRIPTIONS
|
||||
|
||||
|
||||
subscriptions : Model -> Sub Msg
|
||||
subscriptions _ =
|
||||
Sub.none
|
||||
|
||||
|
||||
|
||||
-- VIEW
|
||||
|
||||
|
||||
view : Model -> View Msg
|
||||
view model =
|
||||
case model.blog of
|
||||
Just blog ->
|
||||
{ title = blog.meta.title ++ " | Blog"
|
||||
, body =
|
||||
[ Html.div [ class "bg-neutral-900 md:-mx-8 lg:-mx-16 px-8 py-1" ]
|
||||
[ Html.header [ class "relative" ]
|
||||
[ Html.img
|
||||
[ class "object-cover w-full h-60 sm:h-96 brightness-50 "
|
||||
, src blog.meta.image
|
||||
, alt blog.meta.title
|
||||
]
|
||||
[]
|
||||
, Html.h1 [ class "absolute top-3/4 left-1/2 -translate-x-1/2 -translate-y-1/2 text-center w-full" ]
|
||||
[ Html.text blog.meta.title ]
|
||||
]
|
||||
, Html.span [ class "text-base font-light font-sans oldstyle-nums" ]
|
||||
[ Html.a [ href "/pages/about-me", class "font-bold no-underline hover:text-pink-500" ]
|
||||
[ Html.text "Avinal Kumar" ]
|
||||
, Html.text " | "
|
||||
, Html.time [ datetime blog.meta.date ] [ Html.text <| UU.getFormattedDate blog.meta.date False ]
|
||||
, Html.text <|
|
||||
" | "
|
||||
++ String.fromInt blog.words
|
||||
++ " words | ~"
|
||||
++ String.fromInt (blog.words // 200)
|
||||
++ " mins read"
|
||||
]
|
||||
, Html.span [ class "text-base font-light float-right" ]
|
||||
[ Html.a
|
||||
[ String.dropLeft 8 model.requestUrl
|
||||
|> String.dropRight 3
|
||||
|> String.append "https://null.avinal.space"
|
||||
|> href
|
||||
, class "hover:text-pink-500"
|
||||
]
|
||||
[ Html.abbr [ class "fa-solid fa-terminal no-underline", title "See a basic version of this page." ] [] ]
|
||||
]
|
||||
, articleNode blog.content model.fragment blog.meta.title blog.meta.description
|
||||
]
|
||||
, UU.categoryNtags blog.meta.category blog.meta.tags
|
||||
]
|
||||
}
|
||||
|
||||
Nothing ->
|
||||
{ title = "Avinal Kumar | Something went wrong"
|
||||
, body =
|
||||
[ case model.error of
|
||||
Just err ->
|
||||
UU.errorView err
|
||||
|
||||
Nothing ->
|
||||
Html.div [ class "flex items-center justify-center flex-col object-cover object-center " ]
|
||||
[]
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
articleNode : String -> String -> String -> String -> Html Msg
|
||||
articleNode data fragment title description =
|
||||
Html.node "rendered-md"
|
||||
[ Html.Attributes.attribute "markdowndata" data
|
||||
, Html.Attributes.attribute "fragment" fragment
|
||||
, Html.Attributes.attribute "title" title
|
||||
, Html.Attributes.attribute "description" description
|
||||
, class "line-numbers"
|
||||
]
|
||||
[]
|
||||
|
||||
|
||||
|
||||
-- UTILITIES
|
||||
|
||||
|
||||
type alias YamlMeta =
|
||||
{ title : String
|
||||
, date : String
|
||||
, description : String
|
||||
, tags : List String
|
||||
, category : String
|
||||
, image : 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, words = List.length <| words content }
|
||||
|
||||
Err err ->
|
||||
Err ("YAML front matter parsing failed: " ++ Yaml.errorToString err)
|
||||
|
||||
|
||||
metaDecoder : Yaml.Decoder YamlMeta
|
||||
metaDecoder =
|
||||
Yaml.map7 YamlMeta
|
||||
(Yaml.field "title" Yaml.string)
|
||||
(Yaml.field "date" Yaml.string)
|
||||
(Yaml.field "description" Yaml.string)
|
||||
(Yaml.field "tags" (Yaml.list Yaml.string))
|
||||
(Yaml.field "category" Yaml.string)
|
||||
(Yaml.field "image" Yaml.string)
|
||||
(Yaml.maybe (Yaml.field "modified" Yaml.string))
|
||||
+1
-2
@@ -1,4 +1,3 @@
|
||||
import "./web-components/MarkedRender.js";
|
||||
import "./web-components/Calcom.js";
|
||||
|
||||
export const onReady = ({ app, env }) => {};
|
||||
export const onReady = ({ app, env }) => { };
|
||||
|
||||
@@ -1,144 +0,0 @@
|
||||
import { marked } from "marked";
|
||||
import { markedHighlight } from "marked-highlight";
|
||||
import Prism from "prismjs";
|
||||
|
||||
import "./Prism";
|
||||
|
||||
customElements.define(
|
||||
"rendered-md",
|
||||
class extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
this.lead = 0; // Moved lead here
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.runMarked();
|
||||
}
|
||||
|
||||
updateMeta(title, description) {
|
||||
const metaInfo = {
|
||||
'meta[name="title"]': `${title} | Avinal Kumar | Personal Website`,
|
||||
'meta[name="description"]': description,
|
||||
'meta[property="og:title"]': `${title} | Avinal Kumar | Personal Website`,
|
||||
'meta[property="og:description"]': description,
|
||||
'meta[property="og:url"]': window.location,
|
||||
'meta[property="twitter:title"]': `${title} | Avinal Kumar | Personal Website`,
|
||||
'meta[property="twitter:description"]': description,
|
||||
'meta[property="twitter:url"]': window.location,
|
||||
};
|
||||
|
||||
for (const [selector, content] of Object.entries(metaInfo)) {
|
||||
const element = document.querySelector(selector);
|
||||
if (element) {
|
||||
element.setAttribute("content", content);
|
||||
} else {
|
||||
console.warn(`Element ${selector} not found`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addComments() {
|
||||
window.remark_config = {
|
||||
host: "https://remark42.avinal.space",
|
||||
site_id: "remark",
|
||||
theme: "dark",
|
||||
show_rss_subscription: false,
|
||||
no_footer: true,
|
||||
};
|
||||
|
||||
!(function (e, n) {
|
||||
for (var o = 0; o < e.length; o++) {
|
||||
var r = n.createElement("script"),
|
||||
c = ".js",
|
||||
d = n.head || n.body;
|
||||
"noModule" in r
|
||||
? ((r.type = "module"), (c = ".mjs"))
|
||||
: (r.async = !0),
|
||||
(r.defer = !0),
|
||||
(r.src = remark_config.host + "/web/" + e[o] + c),
|
||||
d.appendChild(r);
|
||||
}
|
||||
})(remark_config.components || ["embed"], document);
|
||||
}
|
||||
|
||||
runMarked() {
|
||||
const {
|
||||
markdowndata: data,
|
||||
fragment,
|
||||
title,
|
||||
description,
|
||||
} = this.attributes;
|
||||
this.updateMeta(title.value, description.value);
|
||||
|
||||
const renderer = new marked.Renderer();
|
||||
|
||||
renderer.heading = (text, level) => {
|
||||
const escapedText = text
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
.replace(/[^\w]+/g, "-");
|
||||
|
||||
return `<h${level} id="${escapedText}">
|
||||
${text}
|
||||
<a title="Permalink to ${text}" href="#${escapedText}">
|
||||
#
|
||||
</a>
|
||||
</h${level}>`;
|
||||
};
|
||||
|
||||
renderer.paragraph = (text) => {
|
||||
this.lead++;
|
||||
return this.lead === 1
|
||||
? `<p class="lead">${text}</p>`
|
||||
: `<p>${text}</p>`;
|
||||
};
|
||||
|
||||
renderer.image = (href, title, text) => {
|
||||
let pos = text.search(":");
|
||||
let direction = text.substr(pos + 1);
|
||||
text = text.substr(0, pos);
|
||||
let put = "max-w-xs ";
|
||||
switch (direction) {
|
||||
case "right":
|
||||
put += "float-right ";
|
||||
break;
|
||||
case "left":
|
||||
put += "float-left ";
|
||||
break;
|
||||
default:
|
||||
put = "float-none ";
|
||||
}
|
||||
return `<img class="${put} grow-0 shrink-0 basis-auto w-full px-3" src=${href} alt="${text}">`;
|
||||
};
|
||||
|
||||
marked.setOptions({
|
||||
renderer: renderer,
|
||||
});
|
||||
|
||||
marked.use(
|
||||
markedHighlight({
|
||||
highlight(code, lang) {
|
||||
const grammer = Prism.languages[lang];
|
||||
if (!grammer) {
|
||||
console.warn(`Unable to find prism highlight for '${lang}'`);
|
||||
return;
|
||||
}
|
||||
return Prism.highlight(code, grammer, lang);
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
this.innerHTML = marked(data.value);
|
||||
this.addComments();
|
||||
|
||||
if (fragment && fragment.value) {
|
||||
window.location = `#${fragment.value}`;
|
||||
}
|
||||
}
|
||||
|
||||
static get observedAttributes() {
|
||||
return ["markdowndata", "fragment", "title", "description"];
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -1,48 +0,0 @@
|
||||
// Load Plugins
|
||||
|
||||
// import 'prismjs/plugins/toolbar/prism-toolbar';
|
||||
// import "prismjs/plugins/line-numbers/prism-line-numbers";
|
||||
// import "prismjs/plugins/line-numbers/prism-line-numbers.css";
|
||||
// import "prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard";
|
||||
|
||||
// load languages
|
||||
import "prismjs/components/prism-bash";
|
||||
import "prismjs/components/prism-markup";
|
||||
import "prismjs/components/prism-css";
|
||||
import "prismjs/components/prism-clike";
|
||||
import "prismjs/components/prism-javascript";
|
||||
import "prismjs/components/prism-bash";
|
||||
import "prismjs/components/prism-basic";
|
||||
import "prismjs/components/prism-brainfuck";
|
||||
import "prismjs/components/prism-c";
|
||||
import "prismjs/components/prism-cpp";
|
||||
import "prismjs/components/prism-cmake";
|
||||
import "prismjs/components/prism-diff";
|
||||
import "prismjs/components/prism-docker";
|
||||
import "prismjs/components/prism-elm";
|
||||
import "prismjs/components/prism-git";
|
||||
import "prismjs/components/prism-go";
|
||||
import "prismjs/components/prism-go-module";
|
||||
import "prismjs/components/prism-graphql";
|
||||
import "prismjs/components/prism-haskell";
|
||||
import "prismjs/components/prism-http";
|
||||
import "prismjs/components/prism-java";
|
||||
import "prismjs/components/prism-json";
|
||||
import "prismjs/components/prism-json5";
|
||||
import "prismjs/components/prism-jsonp";
|
||||
import "prismjs/components/prism-makefile";
|
||||
import "prismjs/components/prism-markdown";
|
||||
import "prismjs/components/prism-matlab";
|
||||
import "prismjs/components/prism-mermaid";
|
||||
import "prismjs/components/prism-powershell";
|
||||
import "prismjs/components/prism-protobuf";
|
||||
import "prismjs/components/prism-python";
|
||||
import "prismjs/components/prism-rest";
|
||||
import "prismjs/components/prism-rust";
|
||||
import "prismjs/components/prism-shell-session";
|
||||
import "prismjs/components/prism-sql";
|
||||
import "prismjs/components/prism-toml";
|
||||
import "prismjs/components/prism-typescript";
|
||||
import "prismjs/components/prism-vim";
|
||||
import "prismjs/components/prism-wasm";
|
||||
import "prismjs/components/prism-yaml";
|
||||
Reference in New Issue
Block a user