Created
August 15, 2021 03:45
-
-
Save AngelMunoz/cea5be5853b2cf7410738edd96ffba63 to your computer and use it in GitHub Desktop.
Convert Dev.to articles into markdown files with site-fi front matter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#r "nuget: FSharp.SystemTextJson, 0.17.4" | |
#r "nuget: Ply, 0.3.1" | |
open System.IO | |
open System.Text.Json | |
open System.Text.Json.Serialization | |
open System | |
type DevToPost = | |
{ created_at: DateTime | |
crossposted_at: DateTime option | |
edited_at: DateTime option | |
last_comment_at: DateTime option | |
published_at: DateTime | |
canonical_url: string option | |
feed_source_url: string option | |
video_closed_caption_track_url: string option | |
video_source_url: string option | |
video_thumbnail_url: string option | |
body_markdown: string | |
cached_tag_list: string option | |
cached_user_name: string option | |
cached_user_username: string option | |
comments_count: int | |
description: string option | |
main_image: string option | |
main_image_background_hex_color: string | |
path: string | |
public_reactions_count: int | |
processed_html: string | |
published: bool | |
published_from_feed: bool | |
show_comments: bool | |
slug: string | |
social_image: string option | |
title: string | |
video: string option | |
video_code: string option } | |
type PostConfig = | |
{ title: string | |
subtitle: string | |
``abstract``: string option | |
date: string | |
categories: string | |
language: string | |
markdown: string } | |
let template (post: PostConfig) : string = | |
sprintf | |
""" | |
--- | |
title: %s | |
subtitle: %s | |
categories: %s | |
abstract: %s | |
date: %s | |
language: %s | |
--- | |
%s | |
""" | |
(post.title.Trim()) | |
(post.subtitle.Trim()) | |
(post.categories.Trim()) | |
((post.``abstract`` |> Option.defaultValue "").Trim()) | |
(post.date.Trim()) | |
(post.language.Trim()) | |
(post.markdown.Trim()) | |
let file = File.ReadAllText("./articles.json") | |
let jsonOpts = | |
let opts = JsonSerializerOptions() | |
opts.AllowTrailingCommas <- true | |
opts.ReadCommentHandling <- JsonCommentHandling.Skip | |
opts.DefaultIgnoreCondition <- JsonIgnoreCondition.WhenWritingNull | |
opts.Converters.Add(JsonFSharpConverter()) | |
opts | |
let getTags (tags: string option) = | |
match tags with | |
| Some tags -> tags.Replace(" ", "") | |
| None -> "uncategorized" | |
let getDate (date: DateTime) = $"{date.Year}-%02i{date.Month}-%02i{date.Day}" | |
let posts = | |
JsonSerializer.Deserialize<DevToPost array>(file, jsonOpts) | |
posts | |
|> Array.Parallel.iter | |
(fun post -> | |
let value = | |
{ title = post.title | |
subtitle = "~" | |
``abstract`` = post.description | |
categories = getTags post.cached_tag_list | |
date = getDate post.published_at | |
language = "en" | |
markdown = post.body_markdown } | |
let fileContent = template value | |
let path = | |
Path.Combine("./posts", $"{getDate post.published_at}-{post.slug}.md") | |
File.WriteAllText(path, fileContent)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment