Add unique ID to headings

The `name` field on the `paragraph` type contains a unique ID for the
paragraph. It's not guaranteed to be there, on images for example like
in the `fd8d091ab8ef` post, but it's there for everything else I can
find.

This enables deep linking. There's no way to get to the deep link other
than opening up the web console. I wanted to link every heading, but
you can actually have links in part of a heading so that's not tenable.
Maybe a "permalink" link next to every heading?
This commit is contained in:
Edward Loveall 2023-03-25 11:16:00 -04:00
parent 761e4ef170
commit cef1bc256d
No known key found for this signature in database
11 changed files with 67 additions and 17 deletions

View file

@ -8,6 +8,7 @@ describe EmbeddedConverter do
store = GistStore.new
paragraph = PostResponse::Paragraph.from_json <<-JSON
{
"name": "ab12",
"text": "",
"type": "IFRAME",
"href": null,
@ -44,6 +45,7 @@ describe EmbeddedConverter do
store = GistStore.new
paragraph = PostResponse::Paragraph.from_json <<-JSON
{
"name": "ab12",
"text": "",
"type": "IFRAME",
"href": null,
@ -73,6 +75,7 @@ describe EmbeddedConverter do
store = GistStore.new
paragraph = PostResponse::Paragraph.from_json <<-JSON
{
"name": "ab12",
"text": "",
"type": "IFRAME",
"href": null,

View file

@ -12,6 +12,7 @@ describe GistScanner do
)
paragraphs = [
PostResponse::Paragraph.new(
name: "ab12",
text: "Check out this gist:",
type: PostResponse::ParagraphType::P,
markups: [] of PostResponse::Markup,
@ -20,6 +21,7 @@ describe GistScanner do
metadata: nil
),
PostResponse::Paragraph.new(
name: "ab13",
text: "",
type: PostResponse::ParagraphType::IFRAME,
markups: [] of PostResponse::Markup,
@ -45,6 +47,7 @@ describe GistScanner do
)
paragraphs = [
PostResponse::Paragraph.new(
name: "ab12",
text: "",
type: PostResponse::ParagraphType::IFRAME,
markups: [] of PostResponse::Markup,
@ -78,6 +81,7 @@ describe GistScanner do
)
paragraphs = [
PostResponse::Paragraph.new(
name: "ab12",
text: "",
type: PostResponse::ParagraphType::IFRAME,
markups: [] of PostResponse::Markup,
@ -86,6 +90,7 @@ describe GistScanner do
metadata: nil
),
PostResponse::Paragraph.new(
name: "ab13",
text: "",
type: PostResponse::ParagraphType::IFRAME,
markups: [] of PostResponse::Markup,

View file

@ -8,6 +8,7 @@ describe PageConverter do
paragraph_json = <<-JSON
[
{
"name": "ab12",
"text": "#{title}",
"type": "H3",
"markups": [],
@ -28,6 +29,7 @@ describe PageConverter do
it "sets the author" do
post_json = <<-JSON
{
"name": "ab12",
"title": "This is a story",
"createdAt": 0,
"creator": {
@ -52,6 +54,7 @@ describe PageConverter do
it "sets the publish date/time" do
post_json = <<-JSON
{
"name": "ab12",
"title": "This is a story",
"createdAt": 1000,
"creator": {
@ -77,6 +80,7 @@ describe PageConverter do
paragraph_json = <<-JSON
[
{
"name": "ab12",
"text": "#{title}",
"type": "H3",
"markups": [],
@ -85,6 +89,7 @@ describe PageConverter do
"metadata": null
},
{
"name": "ab12",
"text": "Content",
"type": "P",
"markups": [],
@ -117,6 +122,7 @@ def default_post_json(
)
<<-JSON
{
"name": "ab12",
"title": "#{title}",
"createdAt": 1628974309758,
"creator": {

View file

@ -8,6 +8,7 @@ describe ParagraphConverter do
paragraphs = Array(PostResponse::Paragraph).from_json <<-JSON
[
{
"name": "ab12",
"text": "Title",
"type": "H3",
"markups": [],
@ -17,7 +18,7 @@ describe ParagraphConverter do
}
]
JSON
expected = [Heading3.new(children: [Text.new(content: "Title")] of Child)]
expected = [Heading3.new(children: [Text.new(content: "Title")] of Child, identifier: "ab12")]
result = ParagraphConverter.new.convert(paragraphs, gist_store)
@ -29,6 +30,7 @@ describe ParagraphConverter do
paragraphs = Array(PostResponse::Paragraph).from_json <<-JSON
[
{
"name": "ab12",
"text": "inline code",
"type": "P",
"markups": [
@ -66,6 +68,7 @@ describe ParagraphConverter do
paragraphs = Array(PostResponse::Paragraph).from_json <<-JSON
[
{
"name": "ab12",
"text": "One",
"type": "ULI",
"markups": [],
@ -74,6 +77,7 @@ describe ParagraphConverter do
"metadata": null
},
{
"name": "ab13",
"text": "Two",
"type": "ULI",
"markups": [],
@ -82,6 +86,7 @@ describe ParagraphConverter do
"metadata": null
},
{
"name": "ab14",
"text": "Not a list item",
"type": "P",
"markups": [],
@ -109,6 +114,7 @@ describe ParagraphConverter do
paragraphs = Array(PostResponse::Paragraph).from_json <<-JSON
[
{
"name": "ab12",
"text": "One",
"type": "OLI",
"markups": [],
@ -117,6 +123,7 @@ describe ParagraphConverter do
"metadata": null
},
{
"name": "ab13",
"text": "Two",
"type": "OLI",
"markups": [],
@ -125,6 +132,7 @@ describe ParagraphConverter do
"metadata": null
},
{
"name": "ab14",
"text": "Not a list item",
"type": "P",
"markups": [],
@ -151,6 +159,7 @@ describe ParagraphConverter do
gist_store = GistStore.new
paragraph = PostResponse::Paragraph.from_json <<-JSON
{
"name": "ab12",
"text": "Image by someuser",
"type": "IMG",
"markups": [
@ -197,6 +206,7 @@ describe ParagraphConverter do
paragraphs = Array(PostResponse::Paragraph).from_json <<-JSON
[
{
"name": "ab12",
"text": "text",
"type": "H2",
"markups": [],
@ -205,6 +215,7 @@ describe ParagraphConverter do
"metadata": null
},
{
"name": "ab13",
"text": "text",
"type": "H3",
"markups": [],
@ -213,6 +224,7 @@ describe ParagraphConverter do
"metadata": null
},
{
"name": "ab14",
"text": "text",
"type": "H4",
"markups": [],
@ -221,6 +233,7 @@ describe ParagraphConverter do
"metadata": null
},
{
"name": "ab15",
"text": "text",
"type": "P",
"markups": [],
@ -229,6 +242,7 @@ describe ParagraphConverter do
"metadata": null
},
{
"name": "ab16",
"text": "text",
"type": "PRE",
"markups": [],
@ -237,6 +251,7 @@ describe ParagraphConverter do
"metadata": null
},
{
"name": "ab17",
"text": "text",
"type": "BQ",
"markups": [],
@ -245,6 +260,7 @@ describe ParagraphConverter do
"metadata": null
},
{
"name": "ab18",
"text": "text",
"type": "PQ",
"markups": [],
@ -253,6 +269,7 @@ describe ParagraphConverter do
"metadata": null
},
{
"name": "ab19",
"text": "text",
"type": "ULI",
"markups": [],
@ -261,6 +278,7 @@ describe ParagraphConverter do
"metadata": null
},
{
"name": "ab20",
"text": "text",
"type": "OLI",
"markups": [],
@ -269,6 +287,7 @@ describe ParagraphConverter do
"metadata": null
},
{
"name": "ab21",
"text": "text",
"type": "IMG",
"markups": [],
@ -281,6 +300,7 @@ describe ParagraphConverter do
}
},
{
"name": "ab22",
"text": "",
"type": "IFRAME",
"markups": [],
@ -296,6 +316,7 @@ describe ParagraphConverter do
"metadata": null
},
{
"name": "ab23",
"text": "Mixtape",
"type": "MIXTAPE_EMBED",
"href": null,
@ -317,9 +338,9 @@ describe ParagraphConverter do
]
JSON
expected = [
Heading1.new([Text.new("text")] of Child),
Heading2.new([Text.new("text")] of Child),
Heading3.new([Text.new("text")] of Child),
Heading1.new([Text.new("text")] of Child, identifier: "ab12"),
Heading2.new([Text.new("text")] of Child, identifier: "ab13"),
Heading3.new([Text.new("text")] of Child, identifier: "ab14"),
Paragraph.new([Text.new("text")] of Child),
Preformatted.new([Text.new("text")] of Child),
BlockQuote.new([Text.new("text")] of Child), # BQ

View file

@ -184,13 +184,13 @@ describe PageContent do
nodes: [
Heading1.new(children: [
Text.new(content: "Title!"),
] of Child),
] of Child, identifier: "ab12"),
] of Child
)
html = PageContent.new(page: page).render_to_string
html.should eq %(<h1>Title!</h1>)
html.should eq %(<h1 id="ab12">Title!</h1>)
end
it "renders an H3" do
@ -201,13 +201,13 @@ describe PageContent do
nodes: [
Heading2.new(children: [
Text.new(content: "Title!"),
] of Child),
] of Child, identifier: "ab12"),
] of Child
)
html = PageContent.new(page: page).render_to_string
html.should eq %(<h2>Title!</h2>)
html.should eq %(<h2 id="ab12">Title!</h2>)
end
it "renders an H4" do
@ -218,13 +218,13 @@ describe PageContent do
nodes: [
Heading3.new(children: [
Text.new(content: "In Conclusion..."),
] of Child),
] of Child, identifier: "ab12"),
] of Child
)
html = PageContent.new(page: page).render_to_string
html.should eq %(<h3>In Conclusion...</h3>)
html.should eq %(<h3 id="ab12">In Conclusion...</h3>)
end
it "renders an image" do

View file

@ -16,15 +16,15 @@ class ParagraphConverter
when PostResponse::ParagraphType::H2
paragraph = paragraphs.shift
children = MarkupConverter.convert(paragraph.text, paragraph.markups)
node = Heading1.new(children: children)
node = Heading1.new(children: children, identifier: paragraph.name || "")
when PostResponse::ParagraphType::H3
paragraph = paragraphs.shift
children = MarkupConverter.convert(paragraph.text, paragraph.markups)
node = Heading2.new(children: children)
node = Heading2.new(children: children, identifier: paragraph.name || "")
when PostResponse::ParagraphType::H4
paragraph = paragraphs.shift
children = MarkupConverter.convert(paragraph.text, paragraph.markups)
node = Heading3.new(children: children)
node = Heading3.new(children: children, identifier: paragraph.name || "")
when PostResponse::ParagraphType::IFRAME
paragraph = paragraphs.shift
node = EmbeddedConverter.convert(paragraph, gist_store)

View file

@ -27,6 +27,7 @@ class MediumClient
content {
bodyModel {
paragraphs {
name
text
type
href

View file

@ -93,15 +93,15 @@ class PageContent < BaseComponent
end
def render_child(node : Heading1)
h1 { render_children(node.children) }
h1(id: node.identifier) { render_children(node.children) }
end
def render_child(node : Heading2)
h2 { render_children(node.children) }
h2(id: node.identifier) { render_children(node.children) }
end
def render_child(node : Heading3)
h3 { render_children(node.children) }
h3(id: node.identifier) { render_children(node.children) }
end
def render_child(child : Image)

View file

@ -41,12 +41,24 @@ module Nodes
end
class Heading1 < Container
getter identifier : String
def initialize(@children : Children, @identifier : String)
end
end
class Heading2 < Container
getter identifier : String
def initialize(@children : Children, @identifier : String)
end
end
class Heading3 < Container
getter identifier : String
def initialize(@children : Children, @identifier : String)
end
end
class ListItem < Container

View file

@ -32,6 +32,7 @@ class PostResponse
end
class Paragraph < Base
property name : String?
property text : String?
property type : ParagraphType
property markups : Array(Markup)
@ -40,6 +41,7 @@ class PostResponse
property metadata : Metadata?
def initialize(
@name : String,
@text : String?,
@type : ParagraphType,
@markups : Array(Markup),

View file

@ -1,3 +1,3 @@
module Scribe
VERSION = "2022-11-06"
VERSION = "2023-03-25"
end