Added resources drafts.
This commit is contained in:
		
							parent
							
								
									be2467d2c8
								
							
						
					
					
						commit
						4e95c02b6f
					
				
							
								
								
									
										20
									
								
								.env
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								.env
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					# Flag to push posts to the ghost instance
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					PUSH_POSTS=true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Download remote/internet-hosted images?
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					DOWNLOAD_IMAGES=false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Base URL
 | 
				
			||||||
 | 
					# Final URL should be: https://www.laurivan.com/
 | 
				
			||||||
 | 
					BASE_URL="http://localhost:2368"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Ghost - related variables
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					API_KEY="62ac6f5ab1479d0001082bd4:73341f843a5be78647c6f7e47d43d6cb09ec323df6d5706915df4685b3d46ce7"
 | 
				
			||||||
 | 
					API_VERSION="v4.0"
 | 
				
			||||||
 | 
					AUTHOR_EMAIL=laur.ivan@gmail.com
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Location of head/hero images
 | 
				
			||||||
 | 
					HEAD_IMAGE_PATH="src/data/images/headers/"
 | 
				
			||||||
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -1,4 +1,5 @@
 | 
				
			|||||||
.idea
 | 
					.idea
 | 
				
			||||||
 | 
					data
 | 
				
			||||||
node_modules
 | 
					node_modules
 | 
				
			||||||
dist
 | 
					dist
 | 
				
			||||||
temp
 | 
					temp
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										1
									
								
								.prettierignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.prettierignore
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					.env
 | 
				
			||||||
							
								
								
									
										5
									
								
								.prettierrc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								.prettierrc
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "tabWidth": 2,
 | 
				
			||||||
 | 
					  "useTabs": false,
 | 
				
			||||||
 | 
					  "semi": true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										12
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "editor.formatOnPaste": true,
 | 
				
			||||||
 | 
					  "editor.formatOnSave": true,
 | 
				
			||||||
 | 
					  "html.format.enable": true,
 | 
				
			||||||
 | 
					  "json.format.enable": true,
 | 
				
			||||||
 | 
					  "javascript.format.enable": true,
 | 
				
			||||||
 | 
					  "typescript.format.enable": true,
 | 
				
			||||||
 | 
					  "css.format.enable": true,
 | 
				
			||||||
 | 
					  "less.format.enable": true,
 | 
				
			||||||
 | 
					  "scss.format.enable": true,
 | 
				
			||||||
 | 
					  "editor.defaultFormatter": "esbenp.prettier-vscode"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										14
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										14
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@ -12,6 +12,7 @@
 | 
				
			|||||||
        "@tryghost/admin-api": "^1.13.0",
 | 
					        "@tryghost/admin-api": "^1.13.0",
 | 
				
			||||||
        "@types/markdown-it": "^12.2.3",
 | 
					        "@types/markdown-it": "^12.2.3",
 | 
				
			||||||
        "axios": "^0.27.2",
 | 
					        "axios": "^0.27.2",
 | 
				
			||||||
 | 
					        "dotenv": "^16.0.1",
 | 
				
			||||||
        "fs": "^0.0.1-security",
 | 
					        "fs": "^0.0.1-security",
 | 
				
			||||||
        "jsonwebtoken": "^8.5.1",
 | 
					        "jsonwebtoken": "^8.5.1",
 | 
				
			||||||
        "markdown-it": "^13.0.1",
 | 
					        "markdown-it": "^13.0.1",
 | 
				
			||||||
@ -154,6 +155,14 @@
 | 
				
			|||||||
        "node": ">=0.3.1"
 | 
					        "node": ">=0.3.1"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/dotenv": {
 | 
				
			||||||
 | 
					      "version": "16.0.1",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.1.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ==",
 | 
				
			||||||
 | 
					      "engines": {
 | 
				
			||||||
 | 
					        "node": ">=12"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/ecdsa-sig-formatter": {
 | 
					    "node_modules/ecdsa-sig-formatter": {
 | 
				
			||||||
      "version": "1.0.11",
 | 
					      "version": "1.0.11",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
 | 
				
			||||||
@ -643,6 +652,11 @@
 | 
				
			|||||||
      "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
 | 
					      "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
 | 
				
			||||||
      "dev": true
 | 
					      "dev": true
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "dotenv": {
 | 
				
			||||||
 | 
					      "version": "16.0.1",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.1.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ=="
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "ecdsa-sig-formatter": {
 | 
					    "ecdsa-sig-formatter": {
 | 
				
			||||||
      "version": "1.0.11",
 | 
					      "version": "1.0.11",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
 | 
				
			||||||
 | 
				
			|||||||
@ -33,6 +33,7 @@
 | 
				
			|||||||
    "@tryghost/admin-api": "^1.13.0",
 | 
					    "@tryghost/admin-api": "^1.13.0",
 | 
				
			||||||
    "@types/markdown-it": "^12.2.3",
 | 
					    "@types/markdown-it": "^12.2.3",
 | 
				
			||||||
    "axios": "^0.27.2",
 | 
					    "axios": "^0.27.2",
 | 
				
			||||||
 | 
					    "dotenv": "^16.0.1",
 | 
				
			||||||
    "fs": "^0.0.1-security",
 | 
					    "fs": "^0.0.1-security",
 | 
				
			||||||
    "jsonwebtoken": "^8.5.1",
 | 
					    "jsonwebtoken": "^8.5.1",
 | 
				
			||||||
    "markdown-it": "^13.0.1",
 | 
					    "markdown-it": "^13.0.1",
 | 
				
			||||||
 | 
				
			|||||||
@ -19,10 +19,6 @@ switch (command) {
 | 
				
			|||||||
      .browse()
 | 
					      .browse()
 | 
				
			||||||
      .then((response: any) => console.log(JSON.stringify(response)))
 | 
					      .then((response: any) => console.log(JSON.stringify(response)))
 | 
				
			||||||
      .catch((error: any) => console.error(error));
 | 
					      .catch((error: any) => console.error(error));
 | 
				
			||||||
    api.images
 | 
					 | 
				
			||||||
      .browse()
 | 
					 | 
				
			||||||
      .then((response: any) => console.log(JSON.stringify(response)))
 | 
					 | 
				
			||||||
      .catch((error: any) => console.error(error));
 | 
					 | 
				
			||||||
    break;
 | 
					    break;
 | 
				
			||||||
  case 1:
 | 
					  case 1:
 | 
				
			||||||
    const post = fs.readFileSync("./src/data/draftpost.json", {
 | 
					    const post = fs.readFileSync("./src/data/draftpost.json", {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,33 +1,35 @@
 | 
				
			|||||||
/**
 | 
					/**
 | 
				
			||||||
 * Load a file, parse it through markdonw-it and display its components
 | 
					 * Load a file, parse it through markdonw-it and display its components
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					import * as dotenv from "dotenv";
 | 
				
			||||||
import { Convertor } from "./convertor/Processors";
 | 
					//import { ImageProcessor } from "./convertor/ImageProcessor";
 | 
				
			||||||
 | 
					import { BlockConvertor as Convertor } from "./convertor/BlockConvertor";
 | 
				
			||||||
const GhostAdminAPI = require("@tryghost/admin-api");
 | 
					const GhostAdminAPI = require("@tryghost/admin-api");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Init config
 | 
				
			||||||
 | 
					dotenv.config();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Configure the client
 | 
					// Configure the client
 | 
				
			||||||
const api = new GhostAdminAPI({
 | 
					const api = new GhostAdminAPI({
 | 
				
			||||||
  url: "http://localhost:2368",
 | 
					  url: process.env.BASE_URL,
 | 
				
			||||||
  // Admin API key goes here
 | 
					  // Admin API key goes here
 | 
				
			||||||
  key: "62ac6f5ab1479d0001082bd4:73341f843a5be78647c6f7e47d43d6cb09ec323df6d5706915df4685b3d46ce7",
 | 
					  key: process.env.API_KEY,
 | 
				
			||||||
  version: "v4.0",
 | 
					  version: process.env.API_VERSION,
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
let convertor = new Convertor("./src/data/markdown-it-example.md");
 | 
					let convertor = new Convertor(
 | 
				
			||||||
convertor
 | 
					  "./src/data/blog/2019-10-31-ie-11-angular-compatibility.md"
 | 
				
			||||||
  .processImages(api, "./temp")
 | 
					);
 | 
				
			||||||
  .then(() => {
 | 
					//let imageProcessor = new ImageProcessor();
 | 
				
			||||||
    console.log("ok");
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
  .catch((r) => {
 | 
					 | 
				
			||||||
    console.log(r);
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
let mdoc: string = ""; //convertor.process();
 | 
					async function main() {
 | 
				
			||||||
 | 
					  //await imageProcessor.processImages(convertor, api, "./temp");
 | 
				
			||||||
let creation = false;
 | 
					  await convertor.process(api);
 | 
				
			||||||
 | 
					 | 
				
			||||||
if (creation) {
 | 
					 | 
				
			||||||
  api.posts
 | 
					 | 
				
			||||||
    .add(JSON.parse(mdoc))
 | 
					 | 
				
			||||||
    .then((response: any) => console.log(JSON.stringify(response)))
 | 
					 | 
				
			||||||
    .catch((error: any) => console.error(error));
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					main()
 | 
				
			||||||
 | 
					  .then(() => {
 | 
				
			||||||
 | 
					    console.log("OK");
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					  .catch((r: any) => {
 | 
				
			||||||
 | 
					    throw new Error(r);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										147
									
								
								src/convertor/BlockConvertor.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								src/convertor/BlockConvertor.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,147 @@
 | 
				
			|||||||
 | 
					import { PostNodeBuilder, Renderer } from "mobiledoc-kit";
 | 
				
			||||||
 | 
					import fs from "fs";
 | 
				
			||||||
 | 
					import metadataParser from "markdown-yaml-metadata-parser";
 | 
				
			||||||
 | 
					import { Convertor } from "./Convertor";
 | 
				
			||||||
 | 
					//import { StackedImage } from "./ImageProcessor";
 | 
				
			||||||
 | 
					import path from "node:path";
 | 
				
			||||||
 | 
					import { downloadImagefromURL, uploadToGhost } from "./images";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const renderer: any = Renderer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class BlockConvertor implements Convertor {
 | 
				
			||||||
 | 
					  builder: any = new PostNodeBuilder();
 | 
				
			||||||
 | 
					  filename: string;
 | 
				
			||||||
 | 
					  // The markdown bits (preamble and content)
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					  metadata: any;
 | 
				
			||||||
 | 
					  content = "";
 | 
				
			||||||
 | 
					  featureImage: string | undefined;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Constructor
 | 
				
			||||||
 | 
					   *
 | 
				
			||||||
 | 
					   * @param filename the file name
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  constructor(filename: string) {
 | 
				
			||||||
 | 
					    this.filename = filename;
 | 
				
			||||||
 | 
					    this.initialize(filename);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  setFeatureImage(url: string): void {
 | 
				
			||||||
 | 
					    this.featureImage = url;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Initialize/reset the convertor class.
 | 
				
			||||||
 | 
					   *
 | 
				
			||||||
 | 
					   * @param filename The file to be loaded
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  public initialize(filename: string): BlockConvertor {
 | 
				
			||||||
 | 
					    this.builder = new PostNodeBuilder();
 | 
				
			||||||
 | 
					    let content = fs.readFileSync(filename, {
 | 
				
			||||||
 | 
					      encoding: "utf8",
 | 
				
			||||||
 | 
					      flag: "r",
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    const parsed = metadataParser(content);
 | 
				
			||||||
 | 
					    this.metadata = parsed.metadata;
 | 
				
			||||||
 | 
					    this.content = parsed.content;
 | 
				
			||||||
 | 
					    return this;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public async process(api: any) {
 | 
				
			||||||
 | 
					    await this.processImages(api, "./temp");
 | 
				
			||||||
 | 
					    let markdownSection = this.builder.createCardSection("markdown", {
 | 
				
			||||||
 | 
					      markdown: this.content,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let post = this.builder.createPost([markdownSection]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let result = JSON.stringify({
 | 
				
			||||||
 | 
					      title: this.metadata.title,
 | 
				
			||||||
 | 
					      slug: this.metadata.slug,
 | 
				
			||||||
 | 
					      mobiledoc: `${JSON.stringify(renderer.render(post, "0.3.1"))}`,
 | 
				
			||||||
 | 
					      status:
 | 
				
			||||||
 | 
					        "draft" in this.metadata
 | 
				
			||||||
 | 
					          ? this.metadata["draft"]
 | 
				
			||||||
 | 
					            ? "draft"
 | 
				
			||||||
 | 
					            : "published"
 | 
				
			||||||
 | 
					          : "draft",
 | 
				
			||||||
 | 
					      visibility: "public",
 | 
				
			||||||
 | 
					      created_at: this.metadata["date"],
 | 
				
			||||||
 | 
					      updated_at: this.metadata["date"],
 | 
				
			||||||
 | 
					      published_at: this.metadata["date"],
 | 
				
			||||||
 | 
					      tags: this.metadata["tags"],
 | 
				
			||||||
 | 
					      author: process.env.AUTHOR_EMAIL,
 | 
				
			||||||
 | 
					      feature_image: this.featureImage,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    console.log(JSON.stringify(this.metadata));
 | 
				
			||||||
 | 
					    console.log(JSON.stringify(result));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (process.env.PUSH_POSTS === "true") {
 | 
				
			||||||
 | 
					      await api.posts.add(JSON.parse(result));
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      console.log(
 | 
				
			||||||
 | 
					        "Env PUSH_POST is configured so no posts are saved to the ghost instance."
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Identifies images and tries to process them
 | 
				
			||||||
 | 
					   * @param api the ghost api reference
 | 
				
			||||||
 | 
					   * @param basepath the path where to save images hosted online
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  public async processImages(api: any, basepath: string) {
 | 
				
			||||||
 | 
					    // collect images in an array
 | 
				
			||||||
 | 
					    //let images: Record<string, StackedImage> = {};
 | 
				
			||||||
 | 
					    const imageRegex = /!\[[^\]]*\]\((.*?)\s*("(?:.*[^"])")?\s*\)/g;
 | 
				
			||||||
 | 
					    //let images: string[] = [];
 | 
				
			||||||
 | 
					    //let m: any;
 | 
				
			||||||
 | 
					    [
 | 
				
			||||||
 | 
					      ...this.content.matchAll(imageRegex),
 | 
				
			||||||
 | 
					      ["", "@@@" + this.metadata.cover, ""],
 | 
				
			||||||
 | 
					    ].forEach(async (item) => {
 | 
				
			||||||
 | 
					      console.log(JSON.stringify(item));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      let url = item[1];
 | 
				
			||||||
 | 
					      let imageURL = url;
 | 
				
			||||||
 | 
					      let imagePath = url;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      let localpath = url;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (url.startsWith("@@@")) {
 | 
				
			||||||
 | 
					        localpath = "" + process.env.HEAD_IMAGE_PATH + url.slice(3);
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        localpath = path.join(path.dirname(this.filename), url);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Download images locally if not already
 | 
				
			||||||
 | 
					      if (url.toLowerCase().startsWith("http")) {
 | 
				
			||||||
 | 
					        // Download the image locally
 | 
				
			||||||
 | 
					        let localpath = path.join(basepath, path.basename(url));
 | 
				
			||||||
 | 
					        await downloadImagefromURL(url, localpath);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Upload the image to ghost
 | 
				
			||||||
 | 
					      if (api) {
 | 
				
			||||||
 | 
					        let reference = await uploadToGhost(api, localpath);
 | 
				
			||||||
 | 
					        imageURL = reference.url;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // replace the image string with the new URL
 | 
				
			||||||
 | 
					      console.log("replace", imagePath, " with ", imageURL);
 | 
				
			||||||
 | 
					      this.content = this.content.replaceAll(imagePath, imageURL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Set the feature image if any
 | 
				
			||||||
 | 
					      if (imagePath.startsWith("@@@")) {
 | 
				
			||||||
 | 
					        this.setFeatureImage(imageURL);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // debug: show the updated content if necessary
 | 
				
			||||||
 | 
					      // console.log(this.content);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										10
									
								
								src/convertor/Convertor.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/convertor/Convertor.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					export interface Convertor {
 | 
				
			||||||
 | 
					  // The markdown bits (preamble and content)
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					  filename: string;
 | 
				
			||||||
 | 
					  content: string;
 | 
				
			||||||
 | 
					  metadata: Record<string, any>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  process(api: any): void;
 | 
				
			||||||
 | 
					  setFeatureImage(url: string): void;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -3,36 +3,43 @@ import fs from "fs";
 | 
				
			|||||||
import MarkdownIt from "markdown-it";
 | 
					import MarkdownIt from "markdown-it";
 | 
				
			||||||
import Token from "markdown-it/lib/token";
 | 
					import Token from "markdown-it/lib/token";
 | 
				
			||||||
import metadataParser from "markdown-yaml-metadata-parser";
 | 
					import metadataParser from "markdown-yaml-metadata-parser";
 | 
				
			||||||
import { downloadImagefromURL, uploadToGhost } from "./images";
 | 
					import { Convertor } from "./Convertor";
 | 
				
			||||||
import path from "node:path";
 | 
					
 | 
				
			||||||
 | 
					const debugFence = false;
 | 
				
			||||||
 | 
					const debugInline = true;
 | 
				
			||||||
 | 
					const debugBlock = false;
 | 
				
			||||||
 | 
					const debugHeader = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface Stack {
 | 
					interface Stack {
 | 
				
			||||||
  tag: string;
 | 
					  tag: string;
 | 
				
			||||||
  meta: any;
 | 
					  meta: any;
 | 
				
			||||||
  token: Token;
 | 
					  token: Token;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
interface StackedImage {
 | 
					 | 
				
			||||||
  path: string;
 | 
					 | 
				
			||||||
  url: string;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const renderer: any = Renderer;
 | 
					const renderer: any = Renderer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const predefinedBlocks = ["blockquote", "table", "bullet_list", "ordered_list"];
 | 
					const predefinedBlocks = [
 | 
				
			||||||
 | 
					  "blockquote",
 | 
				
			||||||
 | 
					  "table",
 | 
				
			||||||
 | 
					  "bullet_list",
 | 
				
			||||||
 | 
					  "ordered_list",
 | 
				
			||||||
 | 
					  "paragraph",
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const headerAsMarkdown = true;
 | 
					const headerAsMarkdown = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class Convertor {
 | 
					export class DetailedConvertor implements Convertor {
 | 
				
			||||||
  markups: Record<string, any> = {};
 | 
					  markups: Record<string, any> = {};
 | 
				
			||||||
  markers: Record<string, any> = {};
 | 
					  markers: Record<string, any> = {};
 | 
				
			||||||
  images: Record<string, StackedImage> = {};
 | 
					
 | 
				
			||||||
  sections: any[] = [];
 | 
					  sections: any[] = [];
 | 
				
			||||||
  builder: any = new PostNodeBuilder();
 | 
					  builder: any = new PostNodeBuilder();
 | 
				
			||||||
 | 
					  filename: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // The markdown bits (preamble and content)
 | 
					  // The markdown bits (preamble and content)
 | 
				
			||||||
  //
 | 
					  //
 | 
				
			||||||
  preamble: string = "";
 | 
					  metadata = {};
 | 
				
			||||||
  content: string = "";
 | 
					  content = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // The line-by-line split of the markdown
 | 
					  // The line-by-line split of the markdown
 | 
				
			||||||
  //
 | 
					  //
 | 
				
			||||||
@ -45,22 +52,26 @@ export class Convertor {
 | 
				
			|||||||
   * @param filename the file name
 | 
					   * @param filename the file name
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  constructor(filename: string) {
 | 
					  constructor(filename: string) {
 | 
				
			||||||
 | 
					    this.filename = filename;
 | 
				
			||||||
    this.initialize(filename);
 | 
					    this.initialize(filename);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  setFeatureImage(url: string): void {
 | 
				
			||||||
 | 
					    throw new Error("Method not implemented.", url);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Initialize/reset the convertor class.
 | 
					   * Initialize/reset the convertor class.
 | 
				
			||||||
   *
 | 
					   *
 | 
				
			||||||
   * @param filename The file to be loaded
 | 
					   * @param filename The file to be loaded
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  public initialize(filename: string): Convertor {
 | 
					  public initialize(filename: string): DetailedConvertor {
 | 
				
			||||||
    this.builder = new PostNodeBuilder();
 | 
					    this.builder = new PostNodeBuilder();
 | 
				
			||||||
    let content = fs.readFileSync(filename, {
 | 
					    let content = fs.readFileSync(filename, {
 | 
				
			||||||
      encoding: "utf8",
 | 
					      encoding: "utf8",
 | 
				
			||||||
      flag: "r",
 | 
					      flag: "r",
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    const parsed = metadataParser(content);
 | 
					    const parsed = metadataParser(content);
 | 
				
			||||||
    this.preamble = parsed.preamble;
 | 
					    this.metadata = parsed.metadata;
 | 
				
			||||||
    this.content = parsed.content;
 | 
					    this.content = parsed.content;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Split the lines
 | 
					    // Split the lines
 | 
				
			||||||
@ -73,7 +84,7 @@ export class Convertor {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public process(): string {
 | 
					  public process(): string {
 | 
				
			||||||
    if (this.preamble === "" && this.content == "") {
 | 
					    if (this.metadata === undefined && this.content == "") {
 | 
				
			||||||
      throw new Error(
 | 
					      throw new Error(
 | 
				
			||||||
        "Convertor not initialised. Please use initalize(...) first"
 | 
					        "Convertor not initialised. Please use initalize(...) first"
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
@ -87,6 +98,7 @@ export class Convertor {
 | 
				
			|||||||
      let components: string[] = value.type.split("_");
 | 
					      let components: string[] = value.type.split("_");
 | 
				
			||||||
      let action: string | undefined = components.pop();
 | 
					      let action: string | undefined = components.pop();
 | 
				
			||||||
      let name = components.join("_");
 | 
					      let name = components.join("_");
 | 
				
			||||||
 | 
					      console.log("BEGIN: ", value.tag, value.type);
 | 
				
			||||||
      switch (action) {
 | 
					      switch (action) {
 | 
				
			||||||
        case "open":
 | 
					        case "open":
 | 
				
			||||||
          if (name in predefinedBlocks) blockNesting++;
 | 
					          if (name in predefinedBlocks) blockNesting++;
 | 
				
			||||||
@ -101,8 +113,9 @@ export class Convertor {
 | 
				
			|||||||
          stack.pop();
 | 
					          stack.pop();
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
        case "fence":
 | 
					        case "fence":
 | 
				
			||||||
 | 
					        case "block":
 | 
				
			||||||
          if (blockNesting == 0) {
 | 
					          if (blockNesting == 0) {
 | 
				
			||||||
            console.log("Process fence...");
 | 
					            this.sections.push(this.processFence(value));
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
        case "inline":
 | 
					        case "inline":
 | 
				
			||||||
@ -136,7 +149,8 @@ export class Convertor {
 | 
				
			|||||||
            this.processBlock(value);
 | 
					            this.processBlock(value);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      } else if (blockNesting == 0 && action === "inline") {
 | 
					      } else if (blockNesting == 0 && action === "inline") {
 | 
				
			||||||
        console.log(value.level, stack[0].token.type);
 | 
					        if (debugInline)
 | 
				
			||||||
 | 
					          console.log(value.level, stack[0].token.type, stack[0].tag);
 | 
				
			||||||
        switch (stack[0].token.type) {
 | 
					        switch (stack[0].token.type) {
 | 
				
			||||||
          case "heading_open":
 | 
					          case "heading_open":
 | 
				
			||||||
            this.sections.push(this.processHeader(stack, value));
 | 
					            this.sections.push(this.processHeader(stack, value));
 | 
				
			||||||
@ -156,39 +170,87 @@ export class Convertor {
 | 
				
			|||||||
      author: "laur.ivan@gmail.com",
 | 
					      author: "laur.ivan@gmail.com",
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    console.log("BLOG ENTRY------------------------------------");
 | 
					    console.log("BLOG ENTRY------------------------------------");
 | 
				
			||||||
    console.log(result);
 | 
					    console.log(JSON.stringify(renderer.render(post, "0.3.1")));
 | 
				
			||||||
    console.log("BLOG ENTRY------------------------------------");
 | 
					    console.log("BLOG ENTRY------------------------------------");
 | 
				
			||||||
    return result;
 | 
					    return result;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private processInline(stack: Stack[], t: Token) {
 | 
					  private processInline(stack: Stack[], t: Token) {
 | 
				
			||||||
    console.log("*********************************************");
 | 
					    if (debugInline) {
 | 
				
			||||||
    console.log(stack.length, JSON.stringify(stack[0]));
 | 
					      console.log("processInline:", stack.length, JSON.stringify(stack[0]));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    // build the header as a markdown card
 | 
					    // build the header as a markdown card
 | 
				
			||||||
    let tbuf: string[] = [];
 | 
					    let tbuf: string[] = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (t.map != null)
 | 
					    if (t.map != null)
 | 
				
			||||||
      for (let i = t.map[0]; i < t.map[1]; i++) tbuf.push(this.lines[i]);
 | 
					      for (let i = t.map[0]; i < t.map[1]; i++) tbuf.push(this.lines[i]);
 | 
				
			||||||
 | 
					    let markdown = this.map2markdown(t.map);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (debugInline) {
 | 
				
			||||||
 | 
					      console.log("processInline:", JSON.stringify(markdown));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let result = this.builder.createCardSection("markdown", {
 | 
					    let result = this.builder.createCardSection("markdown", {
 | 
				
			||||||
      markdown: tbuf.join("\n"),
 | 
					      markdown: markdown,
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    return result;
 | 
					    return result;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private processBlock(t: Token) {
 | 
					  /**
 | 
				
			||||||
 | 
					   * Get the string off lines range
 | 
				
			||||||
 | 
					   *
 | 
				
			||||||
 | 
					   * @param map the [lineStart, lineEnd] array
 | 
				
			||||||
 | 
					   * @returns a sting containing the lines
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  private map2markdown(map: [number, number] | null): string {
 | 
				
			||||||
    let tbuf: string[] = [];
 | 
					    let tbuf: string[] = [];
 | 
				
			||||||
    if (t.map != null)
 | 
					    if (map != null)
 | 
				
			||||||
      for (let i = t.map[0]; i < t.map[1]; i++) tbuf.push(this.lines[i]);
 | 
					      for (let i = map[0]; i < map[1]; i++) tbuf.push(this.lines[i]);
 | 
				
			||||||
    //console.log("----------------------------------------------------");
 | 
					    return tbuf.join("\n");
 | 
				
			||||||
    //console.log(JSON.stringify(t));
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Process a fence (or code block)
 | 
				
			||||||
 | 
					   *
 | 
				
			||||||
 | 
					   * @param t the token of the fence
 | 
				
			||||||
 | 
					   * @returns a markdown card
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  private processFence(t: Token): any {
 | 
				
			||||||
 | 
					    let result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (debugFence) {
 | 
				
			||||||
 | 
					      console.log("processFence:", console.log(JSON.stringify(t)));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // build the fence as a markdown card
 | 
				
			||||||
 | 
					    let markdown = this.map2markdown(t.map);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (debugFence) {
 | 
				
			||||||
 | 
					      console.log("processFence:", console.log(JSON.stringify(markdown)));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    result = this.builder.createCardSection("markdown", {
 | 
				
			||||||
 | 
					      markdown: markdown,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private processBlock(t: Token): any {
 | 
				
			||||||
 | 
					    let markdown = this.map2markdown(t.map);
 | 
				
			||||||
 | 
					    if (debugBlock) {
 | 
				
			||||||
 | 
					      console.log("processBlock", JSON.stringify(t));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
      content: tbuf.join("\n"),
 | 
					      content: markdown,
 | 
				
			||||||
      token: t,
 | 
					      token: t,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private processHeader(stack: Stack[], t: Token): any {
 | 
					  private processHeader(stack: Stack[], t: Token): any {
 | 
				
			||||||
    console.log("+++++++++++++++++++++++++++++++++++++++++++++");
 | 
					    if (debugHeader) {
 | 
				
			||||||
    console.log(JSON.stringify(stack[0].token));
 | 
					      console.log("processHeader", JSON.stringify(stack[0].token));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let result: any = undefined;
 | 
					    let result: any = undefined;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -198,66 +260,13 @@ export class Convertor {
 | 
				
			|||||||
      result = this.builder.createMarkupSection(stack[0].tag, [marker]);
 | 
					      result = this.builder.createMarkupSection(stack[0].tag, [marker]);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      // build the header as a markdown card
 | 
					      // build the header as a markdown card
 | 
				
			||||||
      let tbuf: string[] = [];
 | 
					      let markdown = this.map2markdown(t.map);
 | 
				
			||||||
      if (t.map != null)
 | 
					
 | 
				
			||||||
        for (let i = t.map[0]; i < t.map[1]; i++) tbuf.push(this.lines[i]);
 | 
					 | 
				
			||||||
      result = this.builder.createCardSection("markdown", {
 | 
					      result = this.builder.createCardSection("markdown", {
 | 
				
			||||||
        markdown: tbuf.join("\n"),
 | 
					        markdown: markdown,
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return result;
 | 
					    return result;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					 | 
				
			||||||
  /**
 | 
					 | 
				
			||||||
   * Identifies images and tries to process them
 | 
					 | 
				
			||||||
   *
 | 
					 | 
				
			||||||
   * @returns this
 | 
					 | 
				
			||||||
   */
 | 
					 | 
				
			||||||
  public async processImages(api: any, basepath: string) {
 | 
					 | 
				
			||||||
    // collect images in an array
 | 
					 | 
				
			||||||
    const imageRegex = /!\[[^\]]*\]\((.*?)\s*("(?:.*[^"])")?\s*\)/g;
 | 
					 | 
				
			||||||
    //let images: string[] = [];
 | 
					 | 
				
			||||||
    //let m: any;
 | 
					 | 
				
			||||||
    [...this.content.matchAll(imageRegex)].forEach(async (item) => {
 | 
					 | 
				
			||||||
      console.log(JSON.stringify(item));
 | 
					 | 
				
			||||||
      if (item[1] in this.images) {
 | 
					 | 
				
			||||||
        console.log("Skip cached image for URL: ", item[1]);
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        let url = item[1];
 | 
					 | 
				
			||||||
        // Add the image to the cache of processed images
 | 
					 | 
				
			||||||
        this.images[url] = {
 | 
					 | 
				
			||||||
          path: url,
 | 
					 | 
				
			||||||
          url: url,
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Download images locally if not already
 | 
					 | 
				
			||||||
        if (url.toLowerCase().startsWith("http")) {
 | 
					 | 
				
			||||||
          // Download the image locally
 | 
					 | 
				
			||||||
          let localpath = path.join(basepath, path.basename(url));
 | 
					 | 
				
			||||||
          await downloadImagefromURL(url, localpath);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          // Upload the image to ghost
 | 
					 | 
				
			||||||
          if (api) {
 | 
					 | 
				
			||||||
            let reference = await uploadToGhost(api, localpath);
 | 
					 | 
				
			||||||
            this.images[url].url = reference.url;
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // replace the image string with the new URL
 | 
					 | 
				
			||||||
        console.log(
 | 
					 | 
				
			||||||
          "replace",
 | 
					 | 
				
			||||||
          this.images[url].path,
 | 
					 | 
				
			||||||
          " with ",
 | 
					 | 
				
			||||||
          this.images[url].url
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
        this.content = this.content.replaceAll(
 | 
					 | 
				
			||||||
          this.images[url].path,
 | 
					 | 
				
			||||||
          this.images[url].url
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      console.log(this.content);
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										85
									
								
								src/convertor/ImageProcessor.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								src/convertor/ImageProcessor.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,85 @@
 | 
				
			|||||||
 | 
					import * as dotenv from "dotenv";
 | 
				
			||||||
 | 
					import path from "node:path";
 | 
				
			||||||
 | 
					import { downloadImagefromURL, uploadToGhost } from "./images";
 | 
				
			||||||
 | 
					import { Convertor } from "./Convertor";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Init config
 | 
				
			||||||
 | 
					dotenv.config();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface StackedImage {
 | 
				
			||||||
 | 
					  path: string;
 | 
				
			||||||
 | 
					  url: string;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class ImageProcessor {
 | 
				
			||||||
 | 
					  images: Record<string, StackedImage> = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Identifies images and tries to process them
 | 
				
			||||||
 | 
					   * @param api the ghost api reference
 | 
				
			||||||
 | 
					   * @param basepath the path where to save images hosted online
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  public async processImages(processor: Convertor, api: any, basepath: string) {
 | 
				
			||||||
 | 
					    // collect images in an array
 | 
				
			||||||
 | 
					    const imageRegex = /!\[[^\]]*\]\((.*?)\s*("(?:.*[^"])")?\s*\)/g;
 | 
				
			||||||
 | 
					    //let images: string[] = [];
 | 
				
			||||||
 | 
					    //let m: any;
 | 
				
			||||||
 | 
					    [
 | 
				
			||||||
 | 
					      ...processor.content.matchAll(imageRegex),
 | 
				
			||||||
 | 
					      ["", "@@@" + processor.metadata.cover, ""],
 | 
				
			||||||
 | 
					    ].forEach(async (item) => {
 | 
				
			||||||
 | 
					      console.log(JSON.stringify(item));
 | 
				
			||||||
 | 
					      if (item[1] in this.images) {
 | 
				
			||||||
 | 
					        console.log("Skip cached image for URL: ", item[1]);
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        let url = item[1];
 | 
				
			||||||
 | 
					        // Add the image to the cache of processed images
 | 
				
			||||||
 | 
					        this.images[url] = {
 | 
				
			||||||
 | 
					          path: url,
 | 
				
			||||||
 | 
					          url: url,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let localpath = url;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (url.startsWith("@@@")) {
 | 
				
			||||||
 | 
					          localpath = "" + process.env.HEAD_IMAGE_PATH + url.slice(3);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          localpath = path.join(path.dirname(processor.filename), url);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Download images locally if not already
 | 
				
			||||||
 | 
					        if (url.toLowerCase().startsWith("http")) {
 | 
				
			||||||
 | 
					          // Download the image locally
 | 
				
			||||||
 | 
					          let localpath = path.join(basepath, path.basename(url));
 | 
				
			||||||
 | 
					          await downloadImagefromURL(url, localpath);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Upload the image to ghost
 | 
				
			||||||
 | 
					        if (api) {
 | 
				
			||||||
 | 
					          let reference = await uploadToGhost(api, localpath);
 | 
				
			||||||
 | 
					          this.images[url].url = reference.url;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // replace the image string with the new URL
 | 
				
			||||||
 | 
					        console.log(
 | 
				
			||||||
 | 
					          "replace",
 | 
				
			||||||
 | 
					          this.images[url].path,
 | 
				
			||||||
 | 
					          " with ",
 | 
				
			||||||
 | 
					          this.images[url].url
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        processor.content = processor.content.replaceAll(
 | 
				
			||||||
 | 
					          this.images[url].path,
 | 
				
			||||||
 | 
					          this.images[url].url
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Set the feature image if any
 | 
				
			||||||
 | 
					        if (this.images[url].path.startsWith("@@@")) {
 | 
				
			||||||
 | 
					          processor.setFeatureImage(this.images[url].url);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // debug: show the updated content if necessary
 | 
				
			||||||
 | 
					      // console.log(this.content);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -45,16 +45,21 @@ export interface GhostReference {
 | 
				
			|||||||
  ref: string;
 | 
					  ref: string;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param api the Ghost API object
 | 
				
			||||||
 | 
					 * @param filename the file name of the image to be uploaded
 | 
				
			||||||
 | 
					 * @returns a GhostReference promise with the real file name.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
export async function uploadToGhost(
 | 
					export async function uploadToGhost(
 | 
				
			||||||
  api: any,
 | 
					  api: any,
 | 
				
			||||||
  filename: string
 | 
					  filename: string
 | 
				
			||||||
): Promise<GhostReference> {
 | 
					): Promise<GhostReference> {
 | 
				
			||||||
  //const data: Buffer = fs.readFileSync(filename);
 | 
					 | 
				
			||||||
  let image: Image = {
 | 
					  let image: Image = {
 | 
				
			||||||
    ref: path.basename(filename),
 | 
					    ref: path.basename(filename),
 | 
				
			||||||
    file: filename,
 | 
					    file: filename,
 | 
				
			||||||
    purpose: "image",
 | 
					    purpose: "image",
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  let result = api.images.upload(image);
 | 
					  let result = await api.images.upload(image);
 | 
				
			||||||
  return result;
 | 
					  return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,37 +0,0 @@
 | 
				
			|||||||
---
 | 
					 | 
				
			||||||
title: Basic markdown file
 | 
					 | 
				
			||||||
author: Laur IVAN
 | 
					 | 
				
			||||||
version: 1.0
 | 
					 | 
				
			||||||
date: "2022-06-24"
 | 
					 | 
				
			||||||
license: "[CC-BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/)"
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# H1 header
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## H2 header
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### H3 header
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This is a paragraph
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This is another paragraph.
 | 
					 | 
				
			||||||
With multipine.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- Bullet
 | 
					 | 
				
			||||||
- Bullet
 | 
					 | 
				
			||||||
- Bullet
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
1. Ordered list
 | 
					 | 
				
			||||||
1. Ordered list
 | 
					 | 
				
			||||||
1. Ordered list
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```json
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  "code": "if(true) then true else false"
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| Table | Table |
 | 
					 | 
				
			||||||
+---+---+
 | 
					 | 
				
			||||||
| one | two |
 | 
					 | 
				
			||||||
| three | four |
 | 
					 | 
				
			||||||
@ -1,6 +0,0 @@
 | 
				
			|||||||
{
 | 
					 | 
				
			||||||
  "title": "A post",
 | 
					 | 
				
			||||||
  "mobiledoc": "{\"version\":\"0.3.1\",\"atoms\":[],\"cards\":[[\"markdown\",{\"markdown\":\"```js\\nlet value = 0\\n```\"}]],\"markups\":[[\"strong\"]],\"sections\":[[1,\"p\",[[0,[0],0,\"Hi \"],[0,[],1,\" Bye\"]]],[10,0]]}",
 | 
					 | 
				
			||||||
  "status": "draft",
 | 
					 | 
				
			||||||
  "authors": ["laur.ivan@gmail.com"]
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,6 +0,0 @@
 | 
				
			|||||||
{
 | 
					 | 
				
			||||||
  "title": "A post",
 | 
					 | 
				
			||||||
  "slug": "a-post",
 | 
					 | 
				
			||||||
  "mobiledoc": "{\"version\":\"0.3.1\",\"atoms\":[],\"cards\":[],\"markups\":[],\"sections\":[[1,\"p\",[[0,[],0,\"👋 Welcome, it's great to have you here.\"]]]]}",
 | 
					 | 
				
			||||||
  "status": "published"
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,3 +0,0 @@
 | 
				
			|||||||
{
 | 
					 | 
				
			||||||
  "title": "A post"
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,450 +0,0 @@
 | 
				
			|||||||
[
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "id": "62b72926609faa00017b7f44",
 | 
					 | 
				
			||||||
    "uuid": "948abc50-4233-4c29-8429-3fa75eba6610",
 | 
					 | 
				
			||||||
    "title": "This is the title",
 | 
					 | 
				
			||||||
    "slug": "this-is-the-title",
 | 
					 | 
				
			||||||
    "mobiledoc": "{\"version\":\"0.3.1\",\"atoms\":[],\"cards\":[],\"markups\":[[\"strong\"],[\"em\"]],\"sections\":[[1,\"p\",[[0,[],0,\"I am \"],[0,[0],1,\"writing \"],[0,[],0,\"my \"],[0,[1],1,\"post @laur\"]]]],\"ghostVersion\":\"4.0\"}",
 | 
					 | 
				
			||||||
    "comment_id": "62b72926609faa00017b7f44",
 | 
					 | 
				
			||||||
    "feature_image": null,
 | 
					 | 
				
			||||||
    "featured": false,
 | 
					 | 
				
			||||||
    "status": "published",
 | 
					 | 
				
			||||||
    "visibility": "public",
 | 
					 | 
				
			||||||
    "created_at": "2022-06-25T15:26:30.000Z",
 | 
					 | 
				
			||||||
    "updated_at": "2022-06-25T15:27:08.000Z",
 | 
					 | 
				
			||||||
    "published_at": "2022-06-25T15:27:08.000Z",
 | 
					 | 
				
			||||||
    "custom_excerpt": null,
 | 
					 | 
				
			||||||
    "codeinjection_head": null,
 | 
					 | 
				
			||||||
    "codeinjection_foot": null,
 | 
					 | 
				
			||||||
    "custom_template": null,
 | 
					 | 
				
			||||||
    "canonical_url": null,
 | 
					 | 
				
			||||||
    "tags": [],
 | 
					 | 
				
			||||||
    "authors": [
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "id": "1",
 | 
					 | 
				
			||||||
        "name": "Laur Ivan",
 | 
					 | 
				
			||||||
        "slug": "laur",
 | 
					 | 
				
			||||||
        "email": "laur.ivan@gmail.com",
 | 
					 | 
				
			||||||
        "profile_image": "https://www.gravatar.com/avatar/1abe88862a65973704f7c9b028cf7afe?s=250&r=x&d=mp",
 | 
					 | 
				
			||||||
        "cover_image": null,
 | 
					 | 
				
			||||||
        "bio": null,
 | 
					 | 
				
			||||||
        "website": null,
 | 
					 | 
				
			||||||
        "location": null,
 | 
					 | 
				
			||||||
        "facebook": null,
 | 
					 | 
				
			||||||
        "twitter": null,
 | 
					 | 
				
			||||||
        "accessibility": "{\"nightShift\":true}",
 | 
					 | 
				
			||||||
        "status": "active",
 | 
					 | 
				
			||||||
        "meta_title": null,
 | 
					 | 
				
			||||||
        "meta_description": null,
 | 
					 | 
				
			||||||
        "tour": null,
 | 
					 | 
				
			||||||
        "last_seen": "2022-06-25T15:27:07.000Z",
 | 
					 | 
				
			||||||
        "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
        "updated_at": "2022-06-25T15:27:07.000Z",
 | 
					 | 
				
			||||||
        "roles": [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            "id": "629609ae8b281d00012eb297",
 | 
					 | 
				
			||||||
            "name": "Owner",
 | 
					 | 
				
			||||||
            "description": "Blog Owner",
 | 
					 | 
				
			||||||
            "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
            "updated_at": "2022-05-31T12:27:26.000Z"
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        "url": "http://localhost:2368/author/laur/"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    "tiers": [
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "id": "629609ae8b281d00012eb29c",
 | 
					 | 
				
			||||||
        "name": "Free",
 | 
					 | 
				
			||||||
        "slug": "free",
 | 
					 | 
				
			||||||
        "active": true,
 | 
					 | 
				
			||||||
        "welcome_page_url": null,
 | 
					 | 
				
			||||||
        "visibility": "public",
 | 
					 | 
				
			||||||
        "monthly_price_id": null,
 | 
					 | 
				
			||||||
        "yearly_price_id": null,
 | 
					 | 
				
			||||||
        "description": null,
 | 
					 | 
				
			||||||
        "type": "free",
 | 
					 | 
				
			||||||
        "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
        "updated_at": "2022-05-31T12:27:26.000Z"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "id": "629609ae8b281d00012eb29d",
 | 
					 | 
				
			||||||
        "name": "Laur's blog",
 | 
					 | 
				
			||||||
        "slug": "default-product",
 | 
					 | 
				
			||||||
        "active": true,
 | 
					 | 
				
			||||||
        "welcome_page_url": null,
 | 
					 | 
				
			||||||
        "visibility": "public",
 | 
					 | 
				
			||||||
        "monthly_price_id": null,
 | 
					 | 
				
			||||||
        "yearly_price_id": null,
 | 
					 | 
				
			||||||
        "description": null,
 | 
					 | 
				
			||||||
        "type": "paid",
 | 
					 | 
				
			||||||
        "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
        "updated_at": "2022-05-31T12:29:05.000Z"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    "primary_author": {
 | 
					 | 
				
			||||||
      "id": "1",
 | 
					 | 
				
			||||||
      "name": "Laur Ivan",
 | 
					 | 
				
			||||||
      "slug": "laur",
 | 
					 | 
				
			||||||
      "email": "laur.ivan@gmail.com",
 | 
					 | 
				
			||||||
      "profile_image": "https://www.gravatar.com/avatar/1abe88862a65973704f7c9b028cf7afe?s=250&r=x&d=mp",
 | 
					 | 
				
			||||||
      "cover_image": null,
 | 
					 | 
				
			||||||
      "bio": null,
 | 
					 | 
				
			||||||
      "website": null,
 | 
					 | 
				
			||||||
      "location": null,
 | 
					 | 
				
			||||||
      "facebook": null,
 | 
					 | 
				
			||||||
      "twitter": null,
 | 
					 | 
				
			||||||
      "accessibility": "{\"nightShift\":true}",
 | 
					 | 
				
			||||||
      "status": "active",
 | 
					 | 
				
			||||||
      "meta_title": null,
 | 
					 | 
				
			||||||
      "meta_description": null,
 | 
					 | 
				
			||||||
      "tour": null,
 | 
					 | 
				
			||||||
      "last_seen": "2022-06-25T15:27:07.000Z",
 | 
					 | 
				
			||||||
      "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
      "updated_at": "2022-06-25T15:27:07.000Z",
 | 
					 | 
				
			||||||
      "roles": [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          "id": "629609ae8b281d00012eb297",
 | 
					 | 
				
			||||||
          "name": "Owner",
 | 
					 | 
				
			||||||
          "description": "Blog Owner",
 | 
					 | 
				
			||||||
          "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
          "updated_at": "2022-05-31T12:27:26.000Z"
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "url": "http://localhost:2368/author/laur/"
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "primary_tag": null,
 | 
					 | 
				
			||||||
    "email_segment": "all",
 | 
					 | 
				
			||||||
    "url": "http://localhost:2368/this-is-the-title/",
 | 
					 | 
				
			||||||
    "excerpt": "I am writing my post @laur",
 | 
					 | 
				
			||||||
    "og_image": null,
 | 
					 | 
				
			||||||
    "og_title": null,
 | 
					 | 
				
			||||||
    "og_description": null,
 | 
					 | 
				
			||||||
    "twitter_image": null,
 | 
					 | 
				
			||||||
    "twitter_title": null,
 | 
					 | 
				
			||||||
    "twitter_description": null,
 | 
					 | 
				
			||||||
    "meta_title": null,
 | 
					 | 
				
			||||||
    "meta_description": null,
 | 
					 | 
				
			||||||
    "email_subject": null,
 | 
					 | 
				
			||||||
    "frontmatter": null,
 | 
					 | 
				
			||||||
    "feature_image_alt": null,
 | 
					 | 
				
			||||||
    "feature_image_caption": null,
 | 
					 | 
				
			||||||
    "email_only": false,
 | 
					 | 
				
			||||||
    "email": null,
 | 
					 | 
				
			||||||
    "newsletter": null
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "id": "62960a928b281d00012eb478",
 | 
					 | 
				
			||||||
    "uuid": "e50c8ca6-055d-483e-ba27-bbb3bc2f854a",
 | 
					 | 
				
			||||||
    "title": "I really want this",
 | 
					 | 
				
			||||||
    "slug": "i-really-want-this",
 | 
					 | 
				
			||||||
    "mobiledoc": "{\"version\":\"0.3.1\",\"atoms\":[],\"cards\":[[\"markdown\",{\"markdown\":\"## I am very markdowny\"}],[\"markdown\",{\"markdown\":\"```json\\n{\\n \\\"a\\\": true\\n}\\n```\\n\\n| one  | two  | three  | four  | five  |\\n|---|---|---|---|---|\\n|  row |   |   |   |   |\\n|  row |   |   |   |   |\\n| row  |   |   |   | row  |\"}]],\"markups\":[],\"sections\":[[1,\"p\",[[0,[],0,\"Some markdown to be put here\"]]],[10,0],[10,1],[1,\"p\",[]]],\"ghostVersion\":\"4.0\"}",
 | 
					 | 
				
			||||||
    "comment_id": "62960a928b281d00012eb478",
 | 
					 | 
				
			||||||
    "feature_image": null,
 | 
					 | 
				
			||||||
    "featured": false,
 | 
					 | 
				
			||||||
    "status": "published",
 | 
					 | 
				
			||||||
    "visibility": "public",
 | 
					 | 
				
			||||||
    "created_at": "2022-05-31T12:31:14.000Z",
 | 
					 | 
				
			||||||
    "updated_at": "2022-06-15T18:15:52.000Z",
 | 
					 | 
				
			||||||
    "published_at": "2022-06-15T18:13:26.000Z",
 | 
					 | 
				
			||||||
    "custom_excerpt": null,
 | 
					 | 
				
			||||||
    "codeinjection_head": null,
 | 
					 | 
				
			||||||
    "codeinjection_foot": null,
 | 
					 | 
				
			||||||
    "custom_template": null,
 | 
					 | 
				
			||||||
    "canonical_url": null,
 | 
					 | 
				
			||||||
    "tags": [],
 | 
					 | 
				
			||||||
    "authors": [
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "id": "1",
 | 
					 | 
				
			||||||
        "name": "Laur Ivan",
 | 
					 | 
				
			||||||
        "slug": "laur",
 | 
					 | 
				
			||||||
        "email": "laur.ivan@gmail.com",
 | 
					 | 
				
			||||||
        "profile_image": "https://www.gravatar.com/avatar/1abe88862a65973704f7c9b028cf7afe?s=250&r=x&d=mp",
 | 
					 | 
				
			||||||
        "cover_image": null,
 | 
					 | 
				
			||||||
        "bio": null,
 | 
					 | 
				
			||||||
        "website": null,
 | 
					 | 
				
			||||||
        "location": null,
 | 
					 | 
				
			||||||
        "facebook": null,
 | 
					 | 
				
			||||||
        "twitter": null,
 | 
					 | 
				
			||||||
        "accessibility": "{\"nightShift\":true}",
 | 
					 | 
				
			||||||
        "status": "active",
 | 
					 | 
				
			||||||
        "meta_title": null,
 | 
					 | 
				
			||||||
        "meta_description": null,
 | 
					 | 
				
			||||||
        "tour": null,
 | 
					 | 
				
			||||||
        "last_seen": "2022-06-25T15:27:07.000Z",
 | 
					 | 
				
			||||||
        "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
        "updated_at": "2022-06-25T15:27:07.000Z",
 | 
					 | 
				
			||||||
        "roles": [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            "id": "629609ae8b281d00012eb297",
 | 
					 | 
				
			||||||
            "name": "Owner",
 | 
					 | 
				
			||||||
            "description": "Blog Owner",
 | 
					 | 
				
			||||||
            "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
            "updated_at": "2022-05-31T12:27:26.000Z"
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        "url": "http://localhost:2368/author/laur/"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    "tiers": [
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "id": "629609ae8b281d00012eb29c",
 | 
					 | 
				
			||||||
        "name": "Free",
 | 
					 | 
				
			||||||
        "slug": "free",
 | 
					 | 
				
			||||||
        "active": true,
 | 
					 | 
				
			||||||
        "welcome_page_url": null,
 | 
					 | 
				
			||||||
        "visibility": "public",
 | 
					 | 
				
			||||||
        "monthly_price_id": null,
 | 
					 | 
				
			||||||
        "yearly_price_id": null,
 | 
					 | 
				
			||||||
        "description": null,
 | 
					 | 
				
			||||||
        "type": "free",
 | 
					 | 
				
			||||||
        "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
        "updated_at": "2022-05-31T12:27:26.000Z"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "id": "629609ae8b281d00012eb29d",
 | 
					 | 
				
			||||||
        "name": "Laur's blog",
 | 
					 | 
				
			||||||
        "slug": "default-product",
 | 
					 | 
				
			||||||
        "active": true,
 | 
					 | 
				
			||||||
        "welcome_page_url": null,
 | 
					 | 
				
			||||||
        "visibility": "public",
 | 
					 | 
				
			||||||
        "monthly_price_id": null,
 | 
					 | 
				
			||||||
        "yearly_price_id": null,
 | 
					 | 
				
			||||||
        "description": null,
 | 
					 | 
				
			||||||
        "type": "paid",
 | 
					 | 
				
			||||||
        "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
        "updated_at": "2022-05-31T12:29:05.000Z"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    "primary_author": {
 | 
					 | 
				
			||||||
      "id": "1",
 | 
					 | 
				
			||||||
      "name": "Laur Ivan",
 | 
					 | 
				
			||||||
      "slug": "laur",
 | 
					 | 
				
			||||||
      "email": "laur.ivan@gmail.com",
 | 
					 | 
				
			||||||
      "profile_image": "https://www.gravatar.com/avatar/1abe88862a65973704f7c9b028cf7afe?s=250&r=x&d=mp",
 | 
					 | 
				
			||||||
      "cover_image": null,
 | 
					 | 
				
			||||||
      "bio": null,
 | 
					 | 
				
			||||||
      "website": null,
 | 
					 | 
				
			||||||
      "location": null,
 | 
					 | 
				
			||||||
      "facebook": null,
 | 
					 | 
				
			||||||
      "twitter": null,
 | 
					 | 
				
			||||||
      "accessibility": "{\"nightShift\":true}",
 | 
					 | 
				
			||||||
      "status": "active",
 | 
					 | 
				
			||||||
      "meta_title": null,
 | 
					 | 
				
			||||||
      "meta_description": null,
 | 
					 | 
				
			||||||
      "tour": null,
 | 
					 | 
				
			||||||
      "last_seen": "2022-06-25T15:27:07.000Z",
 | 
					 | 
				
			||||||
      "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
      "updated_at": "2022-06-25T15:27:07.000Z",
 | 
					 | 
				
			||||||
      "roles": [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          "id": "629609ae8b281d00012eb297",
 | 
					 | 
				
			||||||
          "name": "Owner",
 | 
					 | 
				
			||||||
          "description": "Blog Owner",
 | 
					 | 
				
			||||||
          "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
          "updated_at": "2022-05-31T12:27:26.000Z"
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "url": "http://localhost:2368/author/laur/"
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "primary_tag": null,
 | 
					 | 
				
			||||||
    "email_segment": "all",
 | 
					 | 
				
			||||||
    "url": "http://localhost:2368/i-really-want-this/",
 | 
					 | 
				
			||||||
    "excerpt": "Some markdown to be put here\n\n\nI am very markdowny\n\n\n{\n \"a\": true\n}\n\n\n\n\n\n\none\ntwo\nthree\nfour\nfive\n\n\n\n\nrow\n\n\n\n\n\n\nrow\n\n\n\n\n\n\nrow\n\n\n\nrow\n\n\n\n",
 | 
					 | 
				
			||||||
    "og_image": null,
 | 
					 | 
				
			||||||
    "og_title": null,
 | 
					 | 
				
			||||||
    "og_description": null,
 | 
					 | 
				
			||||||
    "twitter_image": null,
 | 
					 | 
				
			||||||
    "twitter_title": null,
 | 
					 | 
				
			||||||
    "twitter_description": null,
 | 
					 | 
				
			||||||
    "meta_title": null,
 | 
					 | 
				
			||||||
    "meta_description": null,
 | 
					 | 
				
			||||||
    "email_subject": null,
 | 
					 | 
				
			||||||
    "frontmatter": null,
 | 
					 | 
				
			||||||
    "feature_image_alt": null,
 | 
					 | 
				
			||||||
    "feature_image_caption": null,
 | 
					 | 
				
			||||||
    "email_only": false,
 | 
					 | 
				
			||||||
    "email": null,
 | 
					 | 
				
			||||||
    "newsletter": null
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "id": "629609ae8b281d00012eb300",
 | 
					 | 
				
			||||||
    "uuid": "49d5c2d3-2aa8-4ea9-9682-47da5c4b73fd",
 | 
					 | 
				
			||||||
    "title": "Coming really soon",
 | 
					 | 
				
			||||||
    "slug": "coming-soon",
 | 
					 | 
				
			||||||
    "mobiledoc": "{\"version\":\"0.3.1\",\"atoms\":[],\"cards\":[],\"markups\":[[\"a\",[\"href\",\"#/portal/\"]]],\"sections\":[[1,\"p\",[[0,[],0,\"This is Laur's blog, a brand new site by Laur Ivan that's just getting started. Things will be up and running here shortly, but you can \"],[0,[0],1,\"subscribe\"],[0,[],0,\" in the meantime if you'd like to stay up to date and receive emails when new content is published!\"]]]],\"ghostVersion\":\"4.0\"}",
 | 
					 | 
				
			||||||
    "comment_id": "629609ae8b281d00012eb300",
 | 
					 | 
				
			||||||
    "feature_image": "https://static.ghost.org/v4.0.0/images/feature-image.jpg",
 | 
					 | 
				
			||||||
    "featured": false,
 | 
					 | 
				
			||||||
    "status": "published",
 | 
					 | 
				
			||||||
    "visibility": "public",
 | 
					 | 
				
			||||||
    "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
    "updated_at": "2022-05-31T12:30:09.000Z",
 | 
					 | 
				
			||||||
    "published_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
    "custom_excerpt": null,
 | 
					 | 
				
			||||||
    "codeinjection_head": null,
 | 
					 | 
				
			||||||
    "codeinjection_foot": null,
 | 
					 | 
				
			||||||
    "custom_template": null,
 | 
					 | 
				
			||||||
    "canonical_url": null,
 | 
					 | 
				
			||||||
    "tags": [
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "id": "629609ae8b281d00012eb29f",
 | 
					 | 
				
			||||||
        "name": "News",
 | 
					 | 
				
			||||||
        "slug": "news",
 | 
					 | 
				
			||||||
        "description": null,
 | 
					 | 
				
			||||||
        "feature_image": null,
 | 
					 | 
				
			||||||
        "visibility": "public",
 | 
					 | 
				
			||||||
        "og_image": null,
 | 
					 | 
				
			||||||
        "og_title": null,
 | 
					 | 
				
			||||||
        "og_description": null,
 | 
					 | 
				
			||||||
        "twitter_image": null,
 | 
					 | 
				
			||||||
        "twitter_title": null,
 | 
					 | 
				
			||||||
        "twitter_description": null,
 | 
					 | 
				
			||||||
        "meta_title": null,
 | 
					 | 
				
			||||||
        "meta_description": null,
 | 
					 | 
				
			||||||
        "codeinjection_head": null,
 | 
					 | 
				
			||||||
        "codeinjection_foot": null,
 | 
					 | 
				
			||||||
        "canonical_url": null,
 | 
					 | 
				
			||||||
        "accent_color": null,
 | 
					 | 
				
			||||||
        "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
        "updated_at": "2022-05-31T12:30:09.000Z",
 | 
					 | 
				
			||||||
        "url": "http://localhost:2368/tag/news/"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    "authors": [
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "id": "1",
 | 
					 | 
				
			||||||
        "name": "Laur Ivan",
 | 
					 | 
				
			||||||
        "slug": "laur",
 | 
					 | 
				
			||||||
        "email": "laur.ivan@gmail.com",
 | 
					 | 
				
			||||||
        "profile_image": "https://www.gravatar.com/avatar/1abe88862a65973704f7c9b028cf7afe?s=250&r=x&d=mp",
 | 
					 | 
				
			||||||
        "cover_image": null,
 | 
					 | 
				
			||||||
        "bio": null,
 | 
					 | 
				
			||||||
        "website": null,
 | 
					 | 
				
			||||||
        "location": null,
 | 
					 | 
				
			||||||
        "facebook": null,
 | 
					 | 
				
			||||||
        "twitter": null,
 | 
					 | 
				
			||||||
        "accessibility": "{\"nightShift\":true}",
 | 
					 | 
				
			||||||
        "status": "active",
 | 
					 | 
				
			||||||
        "meta_title": null,
 | 
					 | 
				
			||||||
        "meta_description": null,
 | 
					 | 
				
			||||||
        "tour": null,
 | 
					 | 
				
			||||||
        "last_seen": "2022-06-25T15:27:07.000Z",
 | 
					 | 
				
			||||||
        "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
        "updated_at": "2022-06-25T15:27:07.000Z",
 | 
					 | 
				
			||||||
        "roles": [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            "id": "629609ae8b281d00012eb297",
 | 
					 | 
				
			||||||
            "name": "Owner",
 | 
					 | 
				
			||||||
            "description": "Blog Owner",
 | 
					 | 
				
			||||||
            "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
            "updated_at": "2022-05-31T12:27:26.000Z"
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        "url": "http://localhost:2368/author/laur/"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    "tiers": [
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "id": "629609ae8b281d00012eb29c",
 | 
					 | 
				
			||||||
        "name": "Free",
 | 
					 | 
				
			||||||
        "slug": "free",
 | 
					 | 
				
			||||||
        "active": true,
 | 
					 | 
				
			||||||
        "welcome_page_url": null,
 | 
					 | 
				
			||||||
        "visibility": "public",
 | 
					 | 
				
			||||||
        "monthly_price_id": null,
 | 
					 | 
				
			||||||
        "yearly_price_id": null,
 | 
					 | 
				
			||||||
        "description": null,
 | 
					 | 
				
			||||||
        "type": "free",
 | 
					 | 
				
			||||||
        "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
        "updated_at": "2022-05-31T12:27:26.000Z"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "id": "629609ae8b281d00012eb29d",
 | 
					 | 
				
			||||||
        "name": "Laur's blog",
 | 
					 | 
				
			||||||
        "slug": "default-product",
 | 
					 | 
				
			||||||
        "active": true,
 | 
					 | 
				
			||||||
        "welcome_page_url": null,
 | 
					 | 
				
			||||||
        "visibility": "public",
 | 
					 | 
				
			||||||
        "monthly_price_id": null,
 | 
					 | 
				
			||||||
        "yearly_price_id": null,
 | 
					 | 
				
			||||||
        "description": null,
 | 
					 | 
				
			||||||
        "type": "paid",
 | 
					 | 
				
			||||||
        "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
        "updated_at": "2022-05-31T12:29:05.000Z"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    "primary_author": {
 | 
					 | 
				
			||||||
      "id": "1",
 | 
					 | 
				
			||||||
      "name": "Laur Ivan",
 | 
					 | 
				
			||||||
      "slug": "laur",
 | 
					 | 
				
			||||||
      "email": "laur.ivan@gmail.com",
 | 
					 | 
				
			||||||
      "profile_image": "https://www.gravatar.com/avatar/1abe88862a65973704f7c9b028cf7afe?s=250&r=x&d=mp",
 | 
					 | 
				
			||||||
      "cover_image": null,
 | 
					 | 
				
			||||||
      "bio": null,
 | 
					 | 
				
			||||||
      "website": null,
 | 
					 | 
				
			||||||
      "location": null,
 | 
					 | 
				
			||||||
      "facebook": null,
 | 
					 | 
				
			||||||
      "twitter": null,
 | 
					 | 
				
			||||||
      "accessibility": "{\"nightShift\":true}",
 | 
					 | 
				
			||||||
      "status": "active",
 | 
					 | 
				
			||||||
      "meta_title": null,
 | 
					 | 
				
			||||||
      "meta_description": null,
 | 
					 | 
				
			||||||
      "tour": null,
 | 
					 | 
				
			||||||
      "last_seen": "2022-06-25T15:27:07.000Z",
 | 
					 | 
				
			||||||
      "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
      "updated_at": "2022-06-25T15:27:07.000Z",
 | 
					 | 
				
			||||||
      "roles": [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          "id": "629609ae8b281d00012eb297",
 | 
					 | 
				
			||||||
          "name": "Owner",
 | 
					 | 
				
			||||||
          "description": "Blog Owner",
 | 
					 | 
				
			||||||
          "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
          "updated_at": "2022-05-31T12:27:26.000Z"
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "url": "http://localhost:2368/author/laur/"
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "primary_tag": {
 | 
					 | 
				
			||||||
      "id": "629609ae8b281d00012eb29f",
 | 
					 | 
				
			||||||
      "name": "News",
 | 
					 | 
				
			||||||
      "slug": "news",
 | 
					 | 
				
			||||||
      "description": null,
 | 
					 | 
				
			||||||
      "feature_image": null,
 | 
					 | 
				
			||||||
      "visibility": "public",
 | 
					 | 
				
			||||||
      "og_image": null,
 | 
					 | 
				
			||||||
      "og_title": null,
 | 
					 | 
				
			||||||
      "og_description": null,
 | 
					 | 
				
			||||||
      "twitter_image": null,
 | 
					 | 
				
			||||||
      "twitter_title": null,
 | 
					 | 
				
			||||||
      "twitter_description": null,
 | 
					 | 
				
			||||||
      "meta_title": null,
 | 
					 | 
				
			||||||
      "meta_description": null,
 | 
					 | 
				
			||||||
      "codeinjection_head": null,
 | 
					 | 
				
			||||||
      "codeinjection_foot": null,
 | 
					 | 
				
			||||||
      "canonical_url": null,
 | 
					 | 
				
			||||||
      "accent_color": null,
 | 
					 | 
				
			||||||
      "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
      "updated_at": "2022-05-31T12:30:09.000Z",
 | 
					 | 
				
			||||||
      "url": "http://localhost:2368/tag/news/"
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "email_segment": "all",
 | 
					 | 
				
			||||||
    "url": "http://localhost:2368/coming-soon/",
 | 
					 | 
				
			||||||
    "excerpt": "This is Laur's blog, a brand new site by Laur Ivan that's just getting started. Things will be up and running here shortly, but you can subscribe in the meantime if you'd like to stay up to date and receive emails when new content is published!",
 | 
					 | 
				
			||||||
    "og_image": null,
 | 
					 | 
				
			||||||
    "og_title": null,
 | 
					 | 
				
			||||||
    "og_description": null,
 | 
					 | 
				
			||||||
    "twitter_image": null,
 | 
					 | 
				
			||||||
    "twitter_title": null,
 | 
					 | 
				
			||||||
    "twitter_description": null,
 | 
					 | 
				
			||||||
    "meta_title": null,
 | 
					 | 
				
			||||||
    "meta_description": null,
 | 
					 | 
				
			||||||
    "email_subject": null,
 | 
					 | 
				
			||||||
    "frontmatter": null,
 | 
					 | 
				
			||||||
    "feature_image_alt": null,
 | 
					 | 
				
			||||||
    "feature_image_caption": null,
 | 
					 | 
				
			||||||
    "email_only": false,
 | 
					 | 
				
			||||||
    "email": null,
 | 
					 | 
				
			||||||
    "newsletter": null
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
@ -1,182 +0,0 @@
 | 
				
			|||||||
[
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "id": "62b81b265fb4ca000119c894",
 | 
					 | 
				
			||||||
    "uuid": "41ced005-2d7c-4965-907c-0c87f5bfe1af",
 | 
					 | 
				
			||||||
    "title": "A post",
 | 
					 | 
				
			||||||
    "slug": "a-post",
 | 
					 | 
				
			||||||
    "mobiledoc": "{\"version\":\"0.3.1\",\"atoms\":[],\"cards\":[[\"markdown\",{\"markdown\":\"```js\\nlet value = 0\\n```\"}],[\"image\",{\"src\":\"http://localhost:2368/content/images/2022/06/ubuntu_black-orange_hex-1.png\",\"width\":758,\"height\":171,\"alt\":\"Ubuntu logo\"}]],\"markups\":[[\"strong\"]],\"sections\":[[1,\"p\",[[0,[0],0,\"Hi \"],[0,[],1,\" Bye\"]]],[10,0],[10,1],[1,\"h2\",[[0,[],0,\"A title\"]]],[1,\"h3\",[[0,[],0,\"A second title\"]]]],\"ghostVersion\":\"4.0\"}",
 | 
					 | 
				
			||||||
    "comment_id": "62b81b265fb4ca000119c894",
 | 
					 | 
				
			||||||
    "feature_image": "http://localhost:2368/content/images/2022/06/dragonfly.jpg",
 | 
					 | 
				
			||||||
    "featured": false,
 | 
					 | 
				
			||||||
    "status": "published",
 | 
					 | 
				
			||||||
    "visibility": "public",
 | 
					 | 
				
			||||||
    "created_at": "2022-06-26T08:39:02.000Z",
 | 
					 | 
				
			||||||
    "updated_at": "2022-06-28T13:31:24.000Z",
 | 
					 | 
				
			||||||
    "published_at": "2022-06-26T08:39:23.000Z",
 | 
					 | 
				
			||||||
    "custom_excerpt": null,
 | 
					 | 
				
			||||||
    "codeinjection_head": null,
 | 
					 | 
				
			||||||
    "codeinjection_foot": null,
 | 
					 | 
				
			||||||
    "custom_template": null,
 | 
					 | 
				
			||||||
    "canonical_url": null,
 | 
					 | 
				
			||||||
    "tags": [
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "id": "629609ae8b281d00012eb29f",
 | 
					 | 
				
			||||||
        "name": "News",
 | 
					 | 
				
			||||||
        "slug": "news",
 | 
					 | 
				
			||||||
        "description": null,
 | 
					 | 
				
			||||||
        "feature_image": null,
 | 
					 | 
				
			||||||
        "visibility": "public",
 | 
					 | 
				
			||||||
        "og_image": null,
 | 
					 | 
				
			||||||
        "og_title": null,
 | 
					 | 
				
			||||||
        "og_description": null,
 | 
					 | 
				
			||||||
        "twitter_image": null,
 | 
					 | 
				
			||||||
        "twitter_title": null,
 | 
					 | 
				
			||||||
        "twitter_description": null,
 | 
					 | 
				
			||||||
        "meta_title": null,
 | 
					 | 
				
			||||||
        "meta_description": null,
 | 
					 | 
				
			||||||
        "codeinjection_head": null,
 | 
					 | 
				
			||||||
        "codeinjection_foot": null,
 | 
					 | 
				
			||||||
        "canonical_url": null,
 | 
					 | 
				
			||||||
        "accent_color": null,
 | 
					 | 
				
			||||||
        "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
        "updated_at": "2022-06-28T13:31:24.000Z",
 | 
					 | 
				
			||||||
        "url": "http://localhost:2368/tag/news/"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    "authors": [
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "id": "1",
 | 
					 | 
				
			||||||
        "name": "Laur Ivan",
 | 
					 | 
				
			||||||
        "slug": "laur",
 | 
					 | 
				
			||||||
        "email": "laur.ivan@gmail.com",
 | 
					 | 
				
			||||||
        "profile_image": "https://www.gravatar.com/avatar/1abe88862a65973704f7c9b028cf7afe?s=250&r=x&d=mp",
 | 
					 | 
				
			||||||
        "cover_image": null,
 | 
					 | 
				
			||||||
        "bio": null,
 | 
					 | 
				
			||||||
        "website": null,
 | 
					 | 
				
			||||||
        "location": null,
 | 
					 | 
				
			||||||
        "facebook": null,
 | 
					 | 
				
			||||||
        "twitter": null,
 | 
					 | 
				
			||||||
        "accessibility": "{\"nightShift\":true}",
 | 
					 | 
				
			||||||
        "status": "active",
 | 
					 | 
				
			||||||
        "meta_title": null,
 | 
					 | 
				
			||||||
        "meta_description": null,
 | 
					 | 
				
			||||||
        "tour": null,
 | 
					 | 
				
			||||||
        "last_seen": "2022-06-28T13:30:38.000Z",
 | 
					 | 
				
			||||||
        "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
        "updated_at": "2022-06-28T13:30:38.000Z",
 | 
					 | 
				
			||||||
        "roles": [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            "id": "629609ae8b281d00012eb297",
 | 
					 | 
				
			||||||
            "name": "Owner",
 | 
					 | 
				
			||||||
            "description": "Blog Owner",
 | 
					 | 
				
			||||||
            "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
            "updated_at": "2022-05-31T12:27:26.000Z"
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        "url": "http://localhost:2368/author/laur/"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    "tiers": [
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "id": "629609ae8b281d00012eb29c",
 | 
					 | 
				
			||||||
        "name": "Free",
 | 
					 | 
				
			||||||
        "slug": "free",
 | 
					 | 
				
			||||||
        "active": true,
 | 
					 | 
				
			||||||
        "welcome_page_url": null,
 | 
					 | 
				
			||||||
        "visibility": "public",
 | 
					 | 
				
			||||||
        "monthly_price_id": null,
 | 
					 | 
				
			||||||
        "yearly_price_id": null,
 | 
					 | 
				
			||||||
        "description": null,
 | 
					 | 
				
			||||||
        "type": "free",
 | 
					 | 
				
			||||||
        "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
        "updated_at": "2022-05-31T12:27:26.000Z"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "id": "629609ae8b281d00012eb29d",
 | 
					 | 
				
			||||||
        "name": "Laur's blog",
 | 
					 | 
				
			||||||
        "slug": "default-product",
 | 
					 | 
				
			||||||
        "active": true,
 | 
					 | 
				
			||||||
        "welcome_page_url": null,
 | 
					 | 
				
			||||||
        "visibility": "public",
 | 
					 | 
				
			||||||
        "monthly_price_id": null,
 | 
					 | 
				
			||||||
        "yearly_price_id": null,
 | 
					 | 
				
			||||||
        "description": null,
 | 
					 | 
				
			||||||
        "type": "paid",
 | 
					 | 
				
			||||||
        "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
        "updated_at": "2022-05-31T12:29:05.000Z"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    "primary_author": {
 | 
					 | 
				
			||||||
      "id": "1",
 | 
					 | 
				
			||||||
      "name": "Laur Ivan",
 | 
					 | 
				
			||||||
      "slug": "laur",
 | 
					 | 
				
			||||||
      "email": "laur.ivan@gmail.com",
 | 
					 | 
				
			||||||
      "profile_image": "https://www.gravatar.com/avatar/1abe88862a65973704f7c9b028cf7afe?s=250&r=x&d=mp",
 | 
					 | 
				
			||||||
      "cover_image": null,
 | 
					 | 
				
			||||||
      "bio": null,
 | 
					 | 
				
			||||||
      "website": null,
 | 
					 | 
				
			||||||
      "location": null,
 | 
					 | 
				
			||||||
      "facebook": null,
 | 
					 | 
				
			||||||
      "twitter": null,
 | 
					 | 
				
			||||||
      "accessibility": "{\"nightShift\":true}",
 | 
					 | 
				
			||||||
      "status": "active",
 | 
					 | 
				
			||||||
      "meta_title": null,
 | 
					 | 
				
			||||||
      "meta_description": null,
 | 
					 | 
				
			||||||
      "tour": null,
 | 
					 | 
				
			||||||
      "last_seen": "2022-06-28T13:30:38.000Z",
 | 
					 | 
				
			||||||
      "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
      "updated_at": "2022-06-28T13:30:38.000Z",
 | 
					 | 
				
			||||||
      "roles": [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          "id": "629609ae8b281d00012eb297",
 | 
					 | 
				
			||||||
          "name": "Owner",
 | 
					 | 
				
			||||||
          "description": "Blog Owner",
 | 
					 | 
				
			||||||
          "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
          "updated_at": "2022-05-31T12:27:26.000Z"
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "url": "http://localhost:2368/author/laur/"
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "primary_tag": {
 | 
					 | 
				
			||||||
      "id": "629609ae8b281d00012eb29f",
 | 
					 | 
				
			||||||
      "name": "News",
 | 
					 | 
				
			||||||
      "slug": "news",
 | 
					 | 
				
			||||||
      "description": null,
 | 
					 | 
				
			||||||
      "feature_image": null,
 | 
					 | 
				
			||||||
      "visibility": "public",
 | 
					 | 
				
			||||||
      "og_image": null,
 | 
					 | 
				
			||||||
      "og_title": null,
 | 
					 | 
				
			||||||
      "og_description": null,
 | 
					 | 
				
			||||||
      "twitter_image": null,
 | 
					 | 
				
			||||||
      "twitter_title": null,
 | 
					 | 
				
			||||||
      "twitter_description": null,
 | 
					 | 
				
			||||||
      "meta_title": null,
 | 
					 | 
				
			||||||
      "meta_description": null,
 | 
					 | 
				
			||||||
      "codeinjection_head": null,
 | 
					 | 
				
			||||||
      "codeinjection_foot": null,
 | 
					 | 
				
			||||||
      "canonical_url": null,
 | 
					 | 
				
			||||||
      "accent_color": null,
 | 
					 | 
				
			||||||
      "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
      "updated_at": "2022-06-28T13:31:24.000Z",
 | 
					 | 
				
			||||||
      "url": "http://localhost:2368/tag/news/"
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "email_segment": "all",
 | 
					 | 
				
			||||||
    "url": "http://localhost:2368/a-post/",
 | 
					 | 
				
			||||||
    "excerpt": "Hi Bye\n\nlet value = 0\n\n\n\n\nA title\n\n\nA second title",
 | 
					 | 
				
			||||||
    "og_image": null,
 | 
					 | 
				
			||||||
    "og_title": null,
 | 
					 | 
				
			||||||
    "og_description": null,
 | 
					 | 
				
			||||||
    "twitter_image": null,
 | 
					 | 
				
			||||||
    "twitter_title": null,
 | 
					 | 
				
			||||||
    "twitter_description": null,
 | 
					 | 
				
			||||||
    "meta_title": null,
 | 
					 | 
				
			||||||
    "meta_description": null,
 | 
					 | 
				
			||||||
    "email_subject": null,
 | 
					 | 
				
			||||||
    "frontmatter": null,
 | 
					 | 
				
			||||||
    "feature_image_alt": null,
 | 
					 | 
				
			||||||
    "feature_image_caption": null,
 | 
					 | 
				
			||||||
    "email_only": false,
 | 
					 | 
				
			||||||
    "email": null,
 | 
					 | 
				
			||||||
    "newsletter": null
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
@ -1,450 +0,0 @@
 | 
				
			|||||||
[
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "id": "62af12d78bab0400019822ae",
 | 
					 | 
				
			||||||
    "uuid": "98737bca-331d-4812-9b19-e6737ece9aa7",
 | 
					 | 
				
			||||||
    "title": "Hello world",
 | 
					 | 
				
			||||||
    "slug": "hello-world",
 | 
					 | 
				
			||||||
    "mobiledoc": "{\"version\":\"0.3.1\",\"ghostVersion\":\"4.0\",\"markups\":[],\"atoms\":[],\"cards\":[],\"sections\":[[1,\"p\",[[0,[],0,\"\"]]]]}",
 | 
					 | 
				
			||||||
    "comment_id": "62af12d78bab0400019822ae",
 | 
					 | 
				
			||||||
    "feature_image": null,
 | 
					 | 
				
			||||||
    "featured": false,
 | 
					 | 
				
			||||||
    "status": "draft",
 | 
					 | 
				
			||||||
    "visibility": "public",
 | 
					 | 
				
			||||||
    "created_at": "2022-06-19T12:13:11.000Z",
 | 
					 | 
				
			||||||
    "updated_at": "2022-06-19T12:13:11.000Z",
 | 
					 | 
				
			||||||
    "published_at": null,
 | 
					 | 
				
			||||||
    "custom_excerpt": null,
 | 
					 | 
				
			||||||
    "codeinjection_head": null,
 | 
					 | 
				
			||||||
    "codeinjection_foot": null,
 | 
					 | 
				
			||||||
    "custom_template": null,
 | 
					 | 
				
			||||||
    "canonical_url": null,
 | 
					 | 
				
			||||||
    "tags": [],
 | 
					 | 
				
			||||||
    "authors": [
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "id": "1",
 | 
					 | 
				
			||||||
        "name": "Laur Ivan",
 | 
					 | 
				
			||||||
        "slug": "laur",
 | 
					 | 
				
			||||||
        "email": "laur.ivan@gmail.com",
 | 
					 | 
				
			||||||
        "profile_image": "https://www.gravatar.com/avatar/1abe88862a65973704f7c9b028cf7afe?s=250&r=x&d=mp",
 | 
					 | 
				
			||||||
        "cover_image": null,
 | 
					 | 
				
			||||||
        "bio": null,
 | 
					 | 
				
			||||||
        "website": null,
 | 
					 | 
				
			||||||
        "location": null,
 | 
					 | 
				
			||||||
        "facebook": null,
 | 
					 | 
				
			||||||
        "twitter": null,
 | 
					 | 
				
			||||||
        "accessibility": "{\"nightShift\":true}",
 | 
					 | 
				
			||||||
        "status": "active",
 | 
					 | 
				
			||||||
        "meta_title": null,
 | 
					 | 
				
			||||||
        "meta_description": null,
 | 
					 | 
				
			||||||
        "tour": null,
 | 
					 | 
				
			||||||
        "last_seen": "2022-06-19T12:07:51.000Z",
 | 
					 | 
				
			||||||
        "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
        "updated_at": "2022-06-19T12:07:51.000Z",
 | 
					 | 
				
			||||||
        "roles": [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            "id": "629609ae8b281d00012eb297",
 | 
					 | 
				
			||||||
            "name": "Owner",
 | 
					 | 
				
			||||||
            "description": "Blog Owner",
 | 
					 | 
				
			||||||
            "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
            "updated_at": "2022-05-31T12:27:26.000Z"
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        "url": "http://localhost:2368/author/laur/"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    "tiers": [
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "id": "629609ae8b281d00012eb29c",
 | 
					 | 
				
			||||||
        "name": "Free",
 | 
					 | 
				
			||||||
        "slug": "free",
 | 
					 | 
				
			||||||
        "active": true,
 | 
					 | 
				
			||||||
        "welcome_page_url": null,
 | 
					 | 
				
			||||||
        "visibility": "public",
 | 
					 | 
				
			||||||
        "monthly_price_id": null,
 | 
					 | 
				
			||||||
        "yearly_price_id": null,
 | 
					 | 
				
			||||||
        "description": null,
 | 
					 | 
				
			||||||
        "type": "free",
 | 
					 | 
				
			||||||
        "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
        "updated_at": "2022-05-31T12:27:26.000Z"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "id": "629609ae8b281d00012eb29d",
 | 
					 | 
				
			||||||
        "name": "Laur's blog",
 | 
					 | 
				
			||||||
        "slug": "default-product",
 | 
					 | 
				
			||||||
        "active": true,
 | 
					 | 
				
			||||||
        "welcome_page_url": null,
 | 
					 | 
				
			||||||
        "visibility": "public",
 | 
					 | 
				
			||||||
        "monthly_price_id": null,
 | 
					 | 
				
			||||||
        "yearly_price_id": null,
 | 
					 | 
				
			||||||
        "description": null,
 | 
					 | 
				
			||||||
        "type": "paid",
 | 
					 | 
				
			||||||
        "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
        "updated_at": "2022-05-31T12:29:05.000Z"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    "primary_author": {
 | 
					 | 
				
			||||||
      "id": "1",
 | 
					 | 
				
			||||||
      "name": "Laur Ivan",
 | 
					 | 
				
			||||||
      "slug": "laur",
 | 
					 | 
				
			||||||
      "email": "laur.ivan@gmail.com",
 | 
					 | 
				
			||||||
      "profile_image": "https://www.gravatar.com/avatar/1abe88862a65973704f7c9b028cf7afe?s=250&r=x&d=mp",
 | 
					 | 
				
			||||||
      "cover_image": null,
 | 
					 | 
				
			||||||
      "bio": null,
 | 
					 | 
				
			||||||
      "website": null,
 | 
					 | 
				
			||||||
      "location": null,
 | 
					 | 
				
			||||||
      "facebook": null,
 | 
					 | 
				
			||||||
      "twitter": null,
 | 
					 | 
				
			||||||
      "accessibility": "{\"nightShift\":true}",
 | 
					 | 
				
			||||||
      "status": "active",
 | 
					 | 
				
			||||||
      "meta_title": null,
 | 
					 | 
				
			||||||
      "meta_description": null,
 | 
					 | 
				
			||||||
      "tour": null,
 | 
					 | 
				
			||||||
      "last_seen": "2022-06-19T12:07:51.000Z",
 | 
					 | 
				
			||||||
      "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
      "updated_at": "2022-06-19T12:07:51.000Z",
 | 
					 | 
				
			||||||
      "roles": [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          "id": "629609ae8b281d00012eb297",
 | 
					 | 
				
			||||||
          "name": "Owner",
 | 
					 | 
				
			||||||
          "description": "Blog Owner",
 | 
					 | 
				
			||||||
          "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
          "updated_at": "2022-05-31T12:27:26.000Z"
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "url": "http://localhost:2368/author/laur/"
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "primary_tag": null,
 | 
					 | 
				
			||||||
    "email_segment": "all",
 | 
					 | 
				
			||||||
    "url": "http://localhost:2368/p/98737bca-331d-4812-9b19-e6737ece9aa7/",
 | 
					 | 
				
			||||||
    "excerpt": null,
 | 
					 | 
				
			||||||
    "og_image": null,
 | 
					 | 
				
			||||||
    "og_title": null,
 | 
					 | 
				
			||||||
    "og_description": null,
 | 
					 | 
				
			||||||
    "twitter_image": null,
 | 
					 | 
				
			||||||
    "twitter_title": null,
 | 
					 | 
				
			||||||
    "twitter_description": null,
 | 
					 | 
				
			||||||
    "meta_title": null,
 | 
					 | 
				
			||||||
    "meta_description": null,
 | 
					 | 
				
			||||||
    "email_subject": null,
 | 
					 | 
				
			||||||
    "frontmatter": null,
 | 
					 | 
				
			||||||
    "feature_image_alt": null,
 | 
					 | 
				
			||||||
    "feature_image_caption": null,
 | 
					 | 
				
			||||||
    "email_only": false,
 | 
					 | 
				
			||||||
    "email": null,
 | 
					 | 
				
			||||||
    "newsletter": null
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "id": "62960a928b281d00012eb478",
 | 
					 | 
				
			||||||
    "uuid": "e50c8ca6-055d-483e-ba27-bbb3bc2f854a",
 | 
					 | 
				
			||||||
    "title": "I really want this",
 | 
					 | 
				
			||||||
    "slug": "i-really-want-this",
 | 
					 | 
				
			||||||
    "mobiledoc": "{\"version\":\"0.3.1\",\"atoms\":[],\"cards\":[[\"markdown\",{\"markdown\":\"## I am very markdowny\"}],[\"markdown\",{\"markdown\":\"```json\\n{\\n \\\"a\\\": true\\n}\\n```\\n\\n| one  | two  | three  | four  | five  |\\n|---|---|---|---|---|\\n|  row |   |   |   |   |\\n|  row |   |   |   |   |\\n| row  |   |   |   | row  |\"}]],\"markups\":[],\"sections\":[[1,\"p\",[[0,[],0,\"Some markdown to be put here\"]]],[10,0],[10,1],[1,\"p\",[]]],\"ghostVersion\":\"4.0\"}",
 | 
					 | 
				
			||||||
    "comment_id": "62960a928b281d00012eb478",
 | 
					 | 
				
			||||||
    "feature_image": null,
 | 
					 | 
				
			||||||
    "featured": false,
 | 
					 | 
				
			||||||
    "status": "published",
 | 
					 | 
				
			||||||
    "visibility": "public",
 | 
					 | 
				
			||||||
    "created_at": "2022-05-31T12:31:14.000Z",
 | 
					 | 
				
			||||||
    "updated_at": "2022-06-15T18:15:52.000Z",
 | 
					 | 
				
			||||||
    "published_at": "2022-06-15T18:13:26.000Z",
 | 
					 | 
				
			||||||
    "custom_excerpt": null,
 | 
					 | 
				
			||||||
    "codeinjection_head": null,
 | 
					 | 
				
			||||||
    "codeinjection_foot": null,
 | 
					 | 
				
			||||||
    "custom_template": null,
 | 
					 | 
				
			||||||
    "canonical_url": null,
 | 
					 | 
				
			||||||
    "tags": [],
 | 
					 | 
				
			||||||
    "authors": [
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "id": "1",
 | 
					 | 
				
			||||||
        "name": "Laur Ivan",
 | 
					 | 
				
			||||||
        "slug": "laur",
 | 
					 | 
				
			||||||
        "email": "laur.ivan@gmail.com",
 | 
					 | 
				
			||||||
        "profile_image": "https://www.gravatar.com/avatar/1abe88862a65973704f7c9b028cf7afe?s=250&r=x&d=mp",
 | 
					 | 
				
			||||||
        "cover_image": null,
 | 
					 | 
				
			||||||
        "bio": null,
 | 
					 | 
				
			||||||
        "website": null,
 | 
					 | 
				
			||||||
        "location": null,
 | 
					 | 
				
			||||||
        "facebook": null,
 | 
					 | 
				
			||||||
        "twitter": null,
 | 
					 | 
				
			||||||
        "accessibility": "{\"nightShift\":true}",
 | 
					 | 
				
			||||||
        "status": "active",
 | 
					 | 
				
			||||||
        "meta_title": null,
 | 
					 | 
				
			||||||
        "meta_description": null,
 | 
					 | 
				
			||||||
        "tour": null,
 | 
					 | 
				
			||||||
        "last_seen": "2022-06-19T12:07:51.000Z",
 | 
					 | 
				
			||||||
        "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
        "updated_at": "2022-06-19T12:07:51.000Z",
 | 
					 | 
				
			||||||
        "roles": [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            "id": "629609ae8b281d00012eb297",
 | 
					 | 
				
			||||||
            "name": "Owner",
 | 
					 | 
				
			||||||
            "description": "Blog Owner",
 | 
					 | 
				
			||||||
            "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
            "updated_at": "2022-05-31T12:27:26.000Z"
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        "url": "http://localhost:2368/author/laur/"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    "tiers": [
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "id": "629609ae8b281d00012eb29c",
 | 
					 | 
				
			||||||
        "name": "Free",
 | 
					 | 
				
			||||||
        "slug": "free",
 | 
					 | 
				
			||||||
        "active": true,
 | 
					 | 
				
			||||||
        "welcome_page_url": null,
 | 
					 | 
				
			||||||
        "visibility": "public",
 | 
					 | 
				
			||||||
        "monthly_price_id": null,
 | 
					 | 
				
			||||||
        "yearly_price_id": null,
 | 
					 | 
				
			||||||
        "description": null,
 | 
					 | 
				
			||||||
        "type": "free",
 | 
					 | 
				
			||||||
        "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
        "updated_at": "2022-05-31T12:27:26.000Z"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "id": "629609ae8b281d00012eb29d",
 | 
					 | 
				
			||||||
        "name": "Laur's blog",
 | 
					 | 
				
			||||||
        "slug": "default-product",
 | 
					 | 
				
			||||||
        "active": true,
 | 
					 | 
				
			||||||
        "welcome_page_url": null,
 | 
					 | 
				
			||||||
        "visibility": "public",
 | 
					 | 
				
			||||||
        "monthly_price_id": null,
 | 
					 | 
				
			||||||
        "yearly_price_id": null,
 | 
					 | 
				
			||||||
        "description": null,
 | 
					 | 
				
			||||||
        "type": "paid",
 | 
					 | 
				
			||||||
        "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
        "updated_at": "2022-05-31T12:29:05.000Z"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    "primary_author": {
 | 
					 | 
				
			||||||
      "id": "1",
 | 
					 | 
				
			||||||
      "name": "Laur Ivan",
 | 
					 | 
				
			||||||
      "slug": "laur",
 | 
					 | 
				
			||||||
      "email": "laur.ivan@gmail.com",
 | 
					 | 
				
			||||||
      "profile_image": "https://www.gravatar.com/avatar/1abe88862a65973704f7c9b028cf7afe?s=250&r=x&d=mp",
 | 
					 | 
				
			||||||
      "cover_image": null,
 | 
					 | 
				
			||||||
      "bio": null,
 | 
					 | 
				
			||||||
      "website": null,
 | 
					 | 
				
			||||||
      "location": null,
 | 
					 | 
				
			||||||
      "facebook": null,
 | 
					 | 
				
			||||||
      "twitter": null,
 | 
					 | 
				
			||||||
      "accessibility": "{\"nightShift\":true}",
 | 
					 | 
				
			||||||
      "status": "active",
 | 
					 | 
				
			||||||
      "meta_title": null,
 | 
					 | 
				
			||||||
      "meta_description": null,
 | 
					 | 
				
			||||||
      "tour": null,
 | 
					 | 
				
			||||||
      "last_seen": "2022-06-19T12:07:51.000Z",
 | 
					 | 
				
			||||||
      "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
      "updated_at": "2022-06-19T12:07:51.000Z",
 | 
					 | 
				
			||||||
      "roles": [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          "id": "629609ae8b281d00012eb297",
 | 
					 | 
				
			||||||
          "name": "Owner",
 | 
					 | 
				
			||||||
          "description": "Blog Owner",
 | 
					 | 
				
			||||||
          "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
          "updated_at": "2022-05-31T12:27:26.000Z"
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "url": "http://localhost:2368/author/laur/"
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "primary_tag": null,
 | 
					 | 
				
			||||||
    "email_segment": "all",
 | 
					 | 
				
			||||||
    "url": "http://localhost:2368/i-really-want-this/",
 | 
					 | 
				
			||||||
    "excerpt": "Some markdown to be put here\n\n\nI am very markdowny\n\n\n{\n \"a\": true\n}\n\n\n\n\n\n\none\ntwo\nthree\nfour\nfive\n\n\n\n\nrow\n\n\n\n\n\n\nrow\n\n\n\n\n\n\nrow\n\n\n\nrow\n\n\n\n",
 | 
					 | 
				
			||||||
    "og_image": null,
 | 
					 | 
				
			||||||
    "og_title": null,
 | 
					 | 
				
			||||||
    "og_description": null,
 | 
					 | 
				
			||||||
    "twitter_image": null,
 | 
					 | 
				
			||||||
    "twitter_title": null,
 | 
					 | 
				
			||||||
    "twitter_description": null,
 | 
					 | 
				
			||||||
    "meta_title": null,
 | 
					 | 
				
			||||||
    "meta_description": null,
 | 
					 | 
				
			||||||
    "email_subject": null,
 | 
					 | 
				
			||||||
    "frontmatter": null,
 | 
					 | 
				
			||||||
    "feature_image_alt": null,
 | 
					 | 
				
			||||||
    "feature_image_caption": null,
 | 
					 | 
				
			||||||
    "email_only": false,
 | 
					 | 
				
			||||||
    "email": null,
 | 
					 | 
				
			||||||
    "newsletter": null
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "id": "629609ae8b281d00012eb300",
 | 
					 | 
				
			||||||
    "uuid": "49d5c2d3-2aa8-4ea9-9682-47da5c4b73fd",
 | 
					 | 
				
			||||||
    "title": "Coming really soon",
 | 
					 | 
				
			||||||
    "slug": "coming-soon",
 | 
					 | 
				
			||||||
    "mobiledoc": "{\"version\":\"0.3.1\",\"atoms\":[],\"cards\":[],\"markups\":[[\"a\",[\"href\",\"#/portal/\"]]],\"sections\":[[1,\"p\",[[0,[],0,\"This is Laur's blog, a brand new site by Laur Ivan that's just getting started. Things will be up and running here shortly, but you can \"],[0,[0],1,\"subscribe\"],[0,[],0,\" in the meantime if you'd like to stay up to date and receive emails when new content is published!\"]]]],\"ghostVersion\":\"4.0\"}",
 | 
					 | 
				
			||||||
    "comment_id": "629609ae8b281d00012eb300",
 | 
					 | 
				
			||||||
    "feature_image": "https://static.ghost.org/v4.0.0/images/feature-image.jpg",
 | 
					 | 
				
			||||||
    "featured": false,
 | 
					 | 
				
			||||||
    "status": "published",
 | 
					 | 
				
			||||||
    "visibility": "public",
 | 
					 | 
				
			||||||
    "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
    "updated_at": "2022-05-31T12:30:09.000Z",
 | 
					 | 
				
			||||||
    "published_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
    "custom_excerpt": null,
 | 
					 | 
				
			||||||
    "codeinjection_head": null,
 | 
					 | 
				
			||||||
    "codeinjection_foot": null,
 | 
					 | 
				
			||||||
    "custom_template": null,
 | 
					 | 
				
			||||||
    "canonical_url": null,
 | 
					 | 
				
			||||||
    "tags": [
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "id": "629609ae8b281d00012eb29f",
 | 
					 | 
				
			||||||
        "name": "News",
 | 
					 | 
				
			||||||
        "slug": "news",
 | 
					 | 
				
			||||||
        "description": null,
 | 
					 | 
				
			||||||
        "feature_image": null,
 | 
					 | 
				
			||||||
        "visibility": "public",
 | 
					 | 
				
			||||||
        "og_image": null,
 | 
					 | 
				
			||||||
        "og_title": null,
 | 
					 | 
				
			||||||
        "og_description": null,
 | 
					 | 
				
			||||||
        "twitter_image": null,
 | 
					 | 
				
			||||||
        "twitter_title": null,
 | 
					 | 
				
			||||||
        "twitter_description": null,
 | 
					 | 
				
			||||||
        "meta_title": null,
 | 
					 | 
				
			||||||
        "meta_description": null,
 | 
					 | 
				
			||||||
        "codeinjection_head": null,
 | 
					 | 
				
			||||||
        "codeinjection_foot": null,
 | 
					 | 
				
			||||||
        "canonical_url": null,
 | 
					 | 
				
			||||||
        "accent_color": null,
 | 
					 | 
				
			||||||
        "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
        "updated_at": "2022-05-31T12:30:09.000Z",
 | 
					 | 
				
			||||||
        "url": "http://localhost:2368/tag/news/"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    "authors": [
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "id": "1",
 | 
					 | 
				
			||||||
        "name": "Laur Ivan",
 | 
					 | 
				
			||||||
        "slug": "laur",
 | 
					 | 
				
			||||||
        "email": "laur.ivan@gmail.com",
 | 
					 | 
				
			||||||
        "profile_image": "https://www.gravatar.com/avatar/1abe88862a65973704f7c9b028cf7afe?s=250&r=x&d=mp",
 | 
					 | 
				
			||||||
        "cover_image": null,
 | 
					 | 
				
			||||||
        "bio": null,
 | 
					 | 
				
			||||||
        "website": null,
 | 
					 | 
				
			||||||
        "location": null,
 | 
					 | 
				
			||||||
        "facebook": null,
 | 
					 | 
				
			||||||
        "twitter": null,
 | 
					 | 
				
			||||||
        "accessibility": "{\"nightShift\":true}",
 | 
					 | 
				
			||||||
        "status": "active",
 | 
					 | 
				
			||||||
        "meta_title": null,
 | 
					 | 
				
			||||||
        "meta_description": null,
 | 
					 | 
				
			||||||
        "tour": null,
 | 
					 | 
				
			||||||
        "last_seen": "2022-06-19T12:07:51.000Z",
 | 
					 | 
				
			||||||
        "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
        "updated_at": "2022-06-19T12:07:51.000Z",
 | 
					 | 
				
			||||||
        "roles": [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            "id": "629609ae8b281d00012eb297",
 | 
					 | 
				
			||||||
            "name": "Owner",
 | 
					 | 
				
			||||||
            "description": "Blog Owner",
 | 
					 | 
				
			||||||
            "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
            "updated_at": "2022-05-31T12:27:26.000Z"
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        "url": "http://localhost:2368/author/laur/"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    "tiers": [
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "id": "629609ae8b281d00012eb29c",
 | 
					 | 
				
			||||||
        "name": "Free",
 | 
					 | 
				
			||||||
        "slug": "free",
 | 
					 | 
				
			||||||
        "active": true,
 | 
					 | 
				
			||||||
        "welcome_page_url": null,
 | 
					 | 
				
			||||||
        "visibility": "public",
 | 
					 | 
				
			||||||
        "monthly_price_id": null,
 | 
					 | 
				
			||||||
        "yearly_price_id": null,
 | 
					 | 
				
			||||||
        "description": null,
 | 
					 | 
				
			||||||
        "type": "free",
 | 
					 | 
				
			||||||
        "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
        "updated_at": "2022-05-31T12:27:26.000Z"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "id": "629609ae8b281d00012eb29d",
 | 
					 | 
				
			||||||
        "name": "Laur's blog",
 | 
					 | 
				
			||||||
        "slug": "default-product",
 | 
					 | 
				
			||||||
        "active": true,
 | 
					 | 
				
			||||||
        "welcome_page_url": null,
 | 
					 | 
				
			||||||
        "visibility": "public",
 | 
					 | 
				
			||||||
        "monthly_price_id": null,
 | 
					 | 
				
			||||||
        "yearly_price_id": null,
 | 
					 | 
				
			||||||
        "description": null,
 | 
					 | 
				
			||||||
        "type": "paid",
 | 
					 | 
				
			||||||
        "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
        "updated_at": "2022-05-31T12:29:05.000Z"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    "primary_author": {
 | 
					 | 
				
			||||||
      "id": "1",
 | 
					 | 
				
			||||||
      "name": "Laur Ivan",
 | 
					 | 
				
			||||||
      "slug": "laur",
 | 
					 | 
				
			||||||
      "email": "laur.ivan@gmail.com",
 | 
					 | 
				
			||||||
      "profile_image": "https://www.gravatar.com/avatar/1abe88862a65973704f7c9b028cf7afe?s=250&r=x&d=mp",
 | 
					 | 
				
			||||||
      "cover_image": null,
 | 
					 | 
				
			||||||
      "bio": null,
 | 
					 | 
				
			||||||
      "website": null,
 | 
					 | 
				
			||||||
      "location": null,
 | 
					 | 
				
			||||||
      "facebook": null,
 | 
					 | 
				
			||||||
      "twitter": null,
 | 
					 | 
				
			||||||
      "accessibility": "{\"nightShift\":true}",
 | 
					 | 
				
			||||||
      "status": "active",
 | 
					 | 
				
			||||||
      "meta_title": null,
 | 
					 | 
				
			||||||
      "meta_description": null,
 | 
					 | 
				
			||||||
      "tour": null,
 | 
					 | 
				
			||||||
      "last_seen": "2022-06-19T12:07:51.000Z",
 | 
					 | 
				
			||||||
      "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
      "updated_at": "2022-06-19T12:07:51.000Z",
 | 
					 | 
				
			||||||
      "roles": [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          "id": "629609ae8b281d00012eb297",
 | 
					 | 
				
			||||||
          "name": "Owner",
 | 
					 | 
				
			||||||
          "description": "Blog Owner",
 | 
					 | 
				
			||||||
          "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
          "updated_at": "2022-05-31T12:27:26.000Z"
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "url": "http://localhost:2368/author/laur/"
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "primary_tag": {
 | 
					 | 
				
			||||||
      "id": "629609ae8b281d00012eb29f",
 | 
					 | 
				
			||||||
      "name": "News",
 | 
					 | 
				
			||||||
      "slug": "news",
 | 
					 | 
				
			||||||
      "description": null,
 | 
					 | 
				
			||||||
      "feature_image": null,
 | 
					 | 
				
			||||||
      "visibility": "public",
 | 
					 | 
				
			||||||
      "og_image": null,
 | 
					 | 
				
			||||||
      "og_title": null,
 | 
					 | 
				
			||||||
      "og_description": null,
 | 
					 | 
				
			||||||
      "twitter_image": null,
 | 
					 | 
				
			||||||
      "twitter_title": null,
 | 
					 | 
				
			||||||
      "twitter_description": null,
 | 
					 | 
				
			||||||
      "meta_title": null,
 | 
					 | 
				
			||||||
      "meta_description": null,
 | 
					 | 
				
			||||||
      "codeinjection_head": null,
 | 
					 | 
				
			||||||
      "codeinjection_foot": null,
 | 
					 | 
				
			||||||
      "canonical_url": null,
 | 
					 | 
				
			||||||
      "accent_color": null,
 | 
					 | 
				
			||||||
      "created_at": "2022-05-31T12:27:26.000Z",
 | 
					 | 
				
			||||||
      "updated_at": "2022-05-31T12:30:09.000Z",
 | 
					 | 
				
			||||||
      "url": "http://localhost:2368/tag/news/"
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "email_segment": "all",
 | 
					 | 
				
			||||||
    "url": "http://localhost:2368/coming-soon/",
 | 
					 | 
				
			||||||
    "excerpt": "This is Laur's blog, a brand new site by Laur Ivan that's just getting started. Things will be up and running here shortly, but you can subscribe in the meantime if you'd like to stay up to date and receive emails when new content is published!",
 | 
					 | 
				
			||||||
    "og_image": null,
 | 
					 | 
				
			||||||
    "og_title": null,
 | 
					 | 
				
			||||||
    "og_description": null,
 | 
					 | 
				
			||||||
    "twitter_image": null,
 | 
					 | 
				
			||||||
    "twitter_title": null,
 | 
					 | 
				
			||||||
    "twitter_description": null,
 | 
					 | 
				
			||||||
    "meta_title": null,
 | 
					 | 
				
			||||||
    "meta_description": null,
 | 
					 | 
				
			||||||
    "email_subject": null,
 | 
					 | 
				
			||||||
    "frontmatter": null,
 | 
					 | 
				
			||||||
    "feature_image_alt": null,
 | 
					 | 
				
			||||||
    "feature_image_caption": null,
 | 
					 | 
				
			||||||
    "email_only": false,
 | 
					 | 
				
			||||||
    "email": null,
 | 
					 | 
				
			||||||
    "newsletter": null
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
@ -1,240 +0,0 @@
 | 
				
			|||||||
---
 | 
					 | 
				
			||||||
title: Basic markdown file (markdown.it example)
 | 
					 | 
				
			||||||
author: Laur IVAN
 | 
					 | 
				
			||||||
version: 1.0
 | 
					 | 
				
			||||||
date: "2022-06-24"
 | 
					 | 
				
			||||||
license: "[CC-BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/)"
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
**Advertisement :)**
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- **[pica](https://nodeca.github.io/pica/demo/)** - high quality and fast image
 | 
					 | 
				
			||||||
  resize in browser.
 | 
					 | 
				
			||||||
- **[babelfish](https://github.com/nodeca/babelfish/)** - developer friendly
 | 
					 | 
				
			||||||
  i18n with plurals support and easy syntax.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
You will like those projects!
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# h1 Heading 8-)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## h2 Heading
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### h3 Heading
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#### h4 Heading
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
##### h5 Heading
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
###### h6 Heading
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Horizontal Rules
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Typographic replacements
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Enable typographer option to see result.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(c) (C) (r) (R) (tm) (TM) (p) (P) +-
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test.. test... test..... test?..... test!....
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
!!!!!! ???? ,, -- ---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
"Smartypants, double quotes" and 'single quotes'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Emphasis
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
**This is bold text**
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
**This is bold text**
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
_This is italic text_
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
_This is italic text_
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
~~Strikethrough~~
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Blockquotes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
> Blockquotes can also be nested...
 | 
					 | 
				
			||||||
>
 | 
					 | 
				
			||||||
> > ...by using additional greater-than signs right next to each other...
 | 
					 | 
				
			||||||
> >
 | 
					 | 
				
			||||||
> > > ...or with spaces between arrows.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Lists
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Unordered
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- Create a list by starting a line with `+`, `-`, or `*`
 | 
					 | 
				
			||||||
- Sub-lists are made by indenting 2 spaces:
 | 
					 | 
				
			||||||
  - Marker character change forces new list start:
 | 
					 | 
				
			||||||
    - Ac tristique libero volutpat at
 | 
					 | 
				
			||||||
    * Facilisis in pretium nisl aliquet
 | 
					 | 
				
			||||||
    - Nulla volutpat aliquam velit
 | 
					 | 
				
			||||||
- Very easy!
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Ordered
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
1. Lorem ipsum dolor sit amet
 | 
					 | 
				
			||||||
2. Consectetur adipiscing elit
 | 
					 | 
				
			||||||
3. Integer molestie lorem at massa
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
4. You can use sequential numbers...
 | 
					 | 
				
			||||||
5. ...or keep all the numbers as `1.`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Start numbering with offset:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
57. foo
 | 
					 | 
				
			||||||
1. bar
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Code
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Inline `code`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Indented code
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Some comments
 | 
					 | 
				
			||||||
    line 1 of code
 | 
					 | 
				
			||||||
    line 2 of code
 | 
					 | 
				
			||||||
    line 3 of code
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Block code "fences"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
Sample text here...
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Syntax highlighting
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```js
 | 
					 | 
				
			||||||
var foo = function (bar) {
 | 
					 | 
				
			||||||
  return bar++;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
console.log(foo(5));
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Tables
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| Option | Description                                                               |
 | 
					 | 
				
			||||||
| ------ | ------------------------------------------------------------------------- |
 | 
					 | 
				
			||||||
| data   | path to data files to supply the data that will be passed into templates. |
 | 
					 | 
				
			||||||
| engine | engine to be used for processing templates. Handlebars is the default.    |
 | 
					 | 
				
			||||||
| ext    | extension to be used for dest files.                                      |
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Right aligned columns
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| Option |                                                               Description |
 | 
					 | 
				
			||||||
| -----: | ------------------------------------------------------------------------: |
 | 
					 | 
				
			||||||
|   data | path to data files to supply the data that will be passed into templates. |
 | 
					 | 
				
			||||||
| engine |    engine to be used for processing templates. Handlebars is the default. |
 | 
					 | 
				
			||||||
|    ext |                                      extension to be used for dest files. |
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Links
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[link text](http://dev.nodeca.com)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[link with title](http://nodeca.github.io/pica/demo/ "title text!")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Autoconverted link https://github.com/nodeca/pica (enable linkify to see)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Images
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||

 | 
					 | 
				
			||||||

 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Like links, Images also have a footnote style syntax
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
![Alt text][id]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
With a reference later in the document defining the URL location:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[id]: https://octodex.github.com/images/dojocat.jpg "The Dojocat"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Plugins
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The killer feature of `markdown-it` is very effective support of
 | 
					 | 
				
			||||||
[syntax plugins](https://www.npmjs.org/browse/keyword/markdown-it-plugin).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### [Emojies](https://github.com/markdown-it/markdown-it-emoji)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
> Classic markup: :wink: :crush: :cry: :tear: :laughing: :yum:
 | 
					 | 
				
			||||||
>
 | 
					 | 
				
			||||||
> Shortcuts (emoticons): :-) :-( 8-) ;)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
see [how to change output](https://github.com/markdown-it/markdown-it-emoji#change-output) with twemoji.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### [Subscript](https://github.com/markdown-it/markdown-it-sub) / [Superscript](https://github.com/markdown-it/markdown-it-sup)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- 19^th^
 | 
					 | 
				
			||||||
- H~2~O
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### [\<ins>](https://github.com/markdown-it/markdown-it-ins)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
++Inserted text++
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### [\<mark>](https://github.com/markdown-it/markdown-it-mark)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
==Marked text==
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### [Footnotes](https://github.com/markdown-it/markdown-it-footnote)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Footnote 1 link[^first].
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Footnote 2 link[^second].
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Inline footnote^[Text of inline footnote] definition.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Duplicated footnote reference[^second].
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[^first]: Footnote **can have markup**
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    and multiple paragraphs.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[^second]: Footnote text.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### [Definition lists](https://github.com/markdown-it/markdown-it-deflist)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Term 1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
: Definition 1
 | 
					 | 
				
			||||||
with lazy continuation.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Term 2 with _inline markup_
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
: Definition 2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        { some code, part of Definition 2 }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Third paragraph of definition 2.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
_Compact style:_
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Term 1
 | 
					 | 
				
			||||||
~ Definition 1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Term 2
 | 
					 | 
				
			||||||
~ Definition 2a
 | 
					 | 
				
			||||||
~ Definition 2b
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### [Abbreviations](https://github.com/markdown-it/markdown-it-abbr)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This is HTML abbreviation example.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
It converts "HTML", but keep intact partial entries like "xxxHTMLyyy" and so on.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
\*[HTML]: Hyper Text Markup Language
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### [Custom containers](https://github.com/markdown-it/markdown-it-container)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
::: warning
 | 
					 | 
				
			||||||
_here be dragons_
 | 
					 | 
				
			||||||
:::
 | 
					 | 
				
			||||||
							
								
								
									
										9141
									
								
								src/data/spec.md
									
									
									
									
									
								
							
							
						
						
									
										9141
									
								
								src/data/spec.md
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
		Reference in New Issue
	
	Block a user