From b2d98bbfe707aa30bc88dd03f6ab0411f7161996 Mon Sep 17 00:00:00 2001 From: hamza-m-masood Date: Fri, 9 Aug 2024 23:29:43 +0100 Subject: [PATCH 1/5] adding functions to parse headers and nested headers --- src/layouts/components/TableOfContents.astro | 28 +++++++++++++++++++ .../components/TableOfContentsHeading.astro | 19 +++++++++++++ tsconfig.json | 1 + 3 files changed, 48 insertions(+) create mode 100644 src/layouts/components/TableOfContents.astro create mode 100644 src/layouts/components/TableOfContentsHeading.astro diff --git a/src/layouts/components/TableOfContents.astro b/src/layouts/components/TableOfContents.astro new file mode 100644 index 0000000..a4cec0d --- /dev/null +++ b/src/layouts/components/TableOfContents.astro @@ -0,0 +1,28 @@ +--- +// TableOfContents.astro +const { headings } = Astro.props; +const toc = buildToc(headings); +import TableOfContentsHeading from "./TableOfContentsHeading.astro"; + +function buildToc(headings) { + const toc = []; + const parentHeadings = new Map(); + headings.forEach((h) => { + const heading = { ...h, subheadings: [] }; + parentHeadings.set(heading.depth, heading); + // Change 2 to 1 if your markdown includes your

+ if (heading.depth === 2) { + toc.push(heading); + } else { + parentHeadings.get(heading.depth - 1).subheadings.push(heading); + } + }); + return toc; +} +--- + + \ No newline at end of file diff --git a/src/layouts/components/TableOfContentsHeading.astro b/src/layouts/components/TableOfContentsHeading.astro new file mode 100644 index 0000000..f2cc35e --- /dev/null +++ b/src/layouts/components/TableOfContentsHeading.astro @@ -0,0 +1,19 @@ +--- +// TableOfContentsHeading.astro +const { heading } = Astro.props; +--- + +
  • + + {heading.text} + + { + heading.subheadings.length > 0 && ( +
      + {heading.subheadings.map((subheading) => ( + + ))} +
    + ) + } +
  • \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 18d9566..c3483d4 100755 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,6 +11,7 @@ "isolatedModules": true, "incremental": true, "allowSyntheticDefaultImports": true, + "noImplicitAny": false, "paths": { "@/components/*": ["./src/layouts/components/*"], "@/shortcodes/*": ["./src/layouts/shortcodes/*"], From 73d0728cbf5adcf5da8ee5d6c93fffa07ff198d3 Mon Sep 17 00:00:00 2001 From: hamza-m-masood Date: Thu, 15 Aug 2024 19:21:45 +0100 Subject: [PATCH 2/5] getting table of contents somewhat working --- src/content/posts/file-io-in-go.mdx | 6 ++--- src/content/posts/why-is-concurrency-hard.mdx | 12 +++++----- src/layouts/Base.astro | 2 +- src/layouts/PostSingle.astro | 7 +++--- src/layouts/components/TableOfContents.astro | 24 +++++++++++++++---- src/pages/[regular].astro | 3 ++- 6 files changed, 35 insertions(+), 19 deletions(-) diff --git a/src/content/posts/file-io-in-go.mdx b/src/content/posts/file-io-in-go.mdx index 1b41b57..e2b5476 100755 --- a/src/content/posts/file-io-in-go.mdx +++ b/src/content/posts/file-io-in-go.mdx @@ -9,7 +9,7 @@ tags: ["go"] draft: false --- -# Printing in Golang +## Printing in Golang Go has many ways to print. All printing functions stem from the `fmt` package. @@ -31,14 +31,14 @@ Third family - `fmt.Sprintf ` outputs to a string but also format the string. -# File I/O Packages +## File I/O Packages 1. Os package: has functions to open and create files, list directories etc... and has the `File` type 2. Io package: has utilities to read and write 3. Bufio pakcage: provides buffered i/o scanners etc... 4. Io/ioutil package: has extra utilities such as reading and an entire file to memory, or writing it all out at once 5. Strconv package: has utilities to convert to/from string representations -### Misc commands for files: +## Misc commands for files: - Opening a file: `os.Open(fname)` - Copying from a file to standard output: `io.Copy(os.Stdout, file)` - Reading all the data from a file (without buffering): `ioutil.ReadAll(file)` diff --git a/src/content/posts/why-is-concurrency-hard.mdx b/src/content/posts/why-is-concurrency-hard.mdx index 8f24b11..34ed1a0 100644 --- a/src/content/posts/why-is-concurrency-hard.mdx +++ b/src/content/posts/why-is-concurrency-hard.mdx @@ -13,7 +13,7 @@ Concurrency can be extrememly difficult to get right. Bugs can occur even after Running into concurrency issues is so common that we are now able to label common pitfalls. Below I have listed the most common issues of working with concurrency: -# Race Conditions +## Race Conditions A race condition occurs when two or more processes must execute in a specific order, but the program allows for the operations to occur in any order, or an order that causes an error. A classic example is one concurrent operation trying to read from a variable while (potentially) at the same time another concurrent operation is trying to write to it. ```go showLineNumbers @@ -55,7 +55,7 @@ We have simply made it increasingly unlikely for our program to product the "inc Another technique that might help in detecting race conditions is testing your program in different environments. Data races normally tend to occur when there is a change in an environment that was not thought of like a variation in memory or CPU. -# Atomicity +## Atomicity If series of executions can in it's entirity without interruption in the defined context, then they are considered to be atomic.\ Atomic comes from the greek word Atom. Which means indivisible. Obviously, in modern physics we know this is not true. But it does bring the point across of a process or an execution being indivisible and uninterruptable. @@ -77,7 +77,7 @@ Multiple steps are completed from a simple statement.Each step within the proces Most statements are not atomic. Thus proving another reason why concurrency can be very challenging. -# Memory Access Synchronization +## Memory Access Synchronization There is a difference between a **data race** and a **race condition**. A race condition occurs when the order of executions are nondeterministic. A data race occurs when many sections of the program are trying to access the same data. A need arises to synchroinze memory when there is a data race. @@ -134,7 +134,7 @@ Knowing what data needs to be synchronized and how frequently you need to lock d If all problems of the previous section are addressed then you will never get a wrong output. The following problems are for your program to always be doing work. In other words, the program has something useful to do at all times: -# Deadlock +## Deadlock A deadlock happens when all goroutines are blocked. This can happen when all goroutines are waiting for eachother. In this case, your program will not work without manual intervention. Here is an example of a deadlock: @@ -181,7 +181,7 @@ Deadlocks can be hard to spot. A technique that can help us identify them are th The program above fulfills all of the conditions. Hence the reason for having a deadlock. -# Livelock +## Livelock A very famous example of a livelock would be the following: Imagine you were in a tight corridor. There is just enough space for two people to walk. You come face to face with another person. You move left, the other person moves left as well in an attempt to walk by. You move right, the other person moves right as well. Both people become stuck in this state of hallway shuffle moving left and right continuously! @@ -190,7 +190,7 @@ This occurs when two goroutines or concurrent processes are trying to prevent de Livelock is a subset of a larger problem called starvation. -# Starvation +## Starvation A greedy goroutine means when one goroutine gets in the way of other goroutines. When you have a greedy goroutine, other concurrent processes can't find resources to perform their work. This is an example of starvation. A goroutine can also suffer finding resources from outside the Go program as well. Lack of CPU power, database connection, lack of memory etc.. can all lead to starvation. Starvation is relatively easy to spot when external factors are in play but can be quite difficult to spot when goroutines are competing against eachother. diff --git a/src/layouts/Base.astro b/src/layouts/Base.astro index 11982da..9e13b70 100755 --- a/src/layouts/Base.astro +++ b/src/layouts/Base.astro @@ -35,7 +35,7 @@ export interface Props { canonical?: string; } -// distructure frontmatters +// destructure frontmatters const { title, meta_title, description, image, noindex, canonical } = Astro.props; --- diff --git a/src/layouts/PostSingle.astro b/src/layouts/PostSingle.astro index fd4eea5..e37cf72 100755 --- a/src/layouts/PostSingle.astro +++ b/src/layouts/PostSingle.astro @@ -7,14 +7,15 @@ import dateFormat from "@/lib/utils/dateFormat"; import similerItems from "@/lib/utils/similarItems"; import { humanize, markdownify, slugify } from "@/lib/utils/textConverter"; import { BiCalendarEdit, BiCategoryAlt } from "react-icons/bi"; +import TableOfContents from './components/TableOfContents.astro'; const allAuthors = await getSinglePage("authors"); const posts = await getSinglePage("posts"); const { post } = Astro.props; +const {headings} = Astro.props; const similarPosts = similerItems(post, posts, post.slug); const { Content } = await post.render(); -const { title, description, authors, categories, image, date, tags } = - post.data; +const { title, description, authors, categories, image, date, tags } = post.data; ---
    @@ -77,6 +78,7 @@ const { title, description, authors, categories, image, date, tags } = +
    { image && ( @@ -90,7 +92,6 @@ const { title, description, authors, categories, image, date, tags } = ) }
    -
    diff --git a/src/layouts/components/TableOfContents.astro b/src/layouts/components/TableOfContents.astro index a4cec0d..2a0a542 100644 --- a/src/layouts/components/TableOfContents.astro +++ b/src/layouts/components/TableOfContents.astro @@ -4,19 +4,33 @@ const { headings } = Astro.props; const toc = buildToc(headings); import TableOfContentsHeading from "./TableOfContentsHeading.astro"; -function buildToc(headings) { - const toc = []; - const parentHeadings = new Map(); +interface Heading { + depth: number; + title: string; + subheadings: Heading[]; +} + +function buildToc(headings: Array<{ depth: number; title: string }>): Heading[] { + const toc: Heading[] = []; + const parentHeadings = new Map(); + headings.forEach((h) => { - const heading = { ...h, subheadings: [] }; + const heading: Heading = { ...h, subheadings: [] }; parentHeadings.set(heading.depth, heading); + // Change 2 to 1 if your markdown includes your

    if (heading.depth === 2) { toc.push(heading); } else { - parentHeadings.get(heading.depth - 1).subheadings.push(heading); + const parentHeading = parentHeadings.get(heading.depth - 1); + if (parentHeading) { + parentHeading.subheadings.push(heading); + } else { + console.warn(`No parent found for heading at depth ${heading.depth}`); + } } }); + return toc; } --- diff --git a/src/pages/[regular].astro b/src/pages/[regular].astro index 8228608..3743225 100755 --- a/src/pages/[regular].astro +++ b/src/pages/[regular].astro @@ -24,6 +24,7 @@ export async function getStaticPaths() { const { page } = Astro.props; const { title, meta_title, description, image } = page.data; +const { headings } = await page.render() --- { postsSlug.includes(page.slug) ? ( - + ) : ( ) From 329b5701c4525eb85a82ecc6fcb0332308d68677 Mon Sep 17 00:00:00 2001 From: hamza-m-masood Date: Thu, 15 Aug 2024 19:38:55 +0100 Subject: [PATCH 3/5] made table of contents sticky --- src/layouts/PostSingle.astro | 2 +- src/layouts/components/TableOfContents.astro | 38 +++++++++++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/layouts/PostSingle.astro b/src/layouts/PostSingle.astro index e37cf72..fb0075e 100755 --- a/src/layouts/PostSingle.astro +++ b/src/layouts/PostSingle.astro @@ -19,6 +19,7 @@ const { title, description, authors, categories, image, date, tags } = post.data ---
    +
    @@ -78,7 +79,6 @@ const { title, description, authors, categories, image, date, tags } = post.data
    -
    { image && ( diff --git a/src/layouts/components/TableOfContents.astro b/src/layouts/components/TableOfContents.astro index 2a0a542..075983b 100644 --- a/src/layouts/components/TableOfContents.astro +++ b/src/layouts/components/TableOfContents.astro @@ -39,4 +39,40 @@ function buildToc(headings: Array<{ depth: number; title: string }>): Heading[]
      {toc.map((heading) => )}
    - \ No newline at end of file + + \ No newline at end of file From 4c874cb97df13e1192f3eb8a14844b1238429e80 Mon Sep 17 00:00:00 2001 From: hamza-m-masood Date: Thu, 15 Aug 2024 23:22:46 +0100 Subject: [PATCH 4/5] table of contents added --- src/layouts/PostSingle.astro | 212 ++++++++++++------- src/layouts/components/TableOfContents.astro | 38 +--- 2 files changed, 135 insertions(+), 115 deletions(-) diff --git a/src/layouts/PostSingle.astro b/src/layouts/PostSingle.astro index fb0075e..e89a2b8 100755 --- a/src/layouts/PostSingle.astro +++ b/src/layouts/PostSingle.astro @@ -7,51 +7,31 @@ import dateFormat from "@/lib/utils/dateFormat"; import similerItems from "@/lib/utils/similarItems"; import { humanize, markdownify, slugify } from "@/lib/utils/textConverter"; import { BiCalendarEdit, BiCategoryAlt } from "react-icons/bi"; -import TableOfContents from './components/TableOfContents.astro'; +import TableOfContents from "./components/TableOfContents.astro"; const allAuthors = await getSinglePage("authors"); const posts = await getSinglePage("posts"); const { post } = Astro.props; -const {headings} = Astro.props; +const { headings } = Astro.props; const similarPosts = similerItems(post, posts, post.slug); const { Content } = await post.render(); -const { title, description, authors, categories, image, date, tags } = post.data; +const { title, description, authors, categories, image, date, tags } = + post.data; --- -
    - -
    -
    -
    -

    -
      -
    • - { - allAuthors - .filter((author) => - authors - .map((author: string) => slugify(author)) - .includes(slugify(author.data.title)), - ) - .map((author, i) => ( - - {author.data.image && ( - {author.data.title} - )} - {author.data.title} - - )) - } -
    • +
      +
      +
      +
      +

      +
      • <>{dateFormat(date)} @@ -78,49 +58,66 @@ const { title, description, authors, categories, image, date, tags } = post.data

      - -
      - { - image && ( - {title} - ) - } -
      -
      -
      - -
      -
      - - +
      + { + image && ( + {title} -
      + ) + } +
      +
      + +
      + + +
      +
      + +
      +
      -
      -

    +
    +
    + + +
    +
    @@ -134,3 +131,62 @@ const { title, description, authors, categories, image, date, tags } = post.data

    ) } + + diff --git a/src/layouts/components/TableOfContents.astro b/src/layouts/components/TableOfContents.astro index 075983b..2a0a542 100644 --- a/src/layouts/components/TableOfContents.astro +++ b/src/layouts/components/TableOfContents.astro @@ -39,40 +39,4 @@ function buildToc(headings: Array<{ depth: number; title: string }>): Heading[]
      {toc.map((heading) => )}
    - - \ No newline at end of file + \ No newline at end of file From bf06b0233831aaee22254eaed686cf2948d53649 Mon Sep 17 00:00:00 2001 From: hamza-m-masood Date: Thu, 15 Aug 2024 23:39:09 +0100 Subject: [PATCH 5/5] color change --- src/layouts/PostSingle.astro | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/layouts/PostSingle.astro b/src/layouts/PostSingle.astro index e89a2b8..ab7e1a4 100755 --- a/src/layouts/PostSingle.astro +++ b/src/layouts/PostSingle.astro @@ -143,24 +143,20 @@ const { title, description, authors, categories, image, date, tags } = ); if (entry.isIntersecting) { - index?.classList.remove("bg-slate-200", "dark:bg-slate-800"); // remove bg index?.classList.add( - "bg-indigo-600", - "dark:bg-indigo-700", - "text-white", + "bg-blue-100", + "bg-blue-100", "font-bold", "transition-colors", - "duration-200", + "duration-100", ); } else { - index?.classList.add("bg-slate-200", "dark:bg-slate-800"); // add bg index?.classList.remove( - "bg-indigo-600", - "dark:bg-indigo-700", - "text-white", + "bg-blue-100", + "bg-blue-100", "font-bold", "transition-colors", - "duration-200", + "duration-100", ); } }); @@ -182,6 +178,7 @@ const { title, description, authors, categories, image, date, tags } = observer.observe(heading); }); }; + fnObserver(); document.addEventListener("astro:after-swap", fnObserver);