Compare commits
No commits in common. "5ab9c48e2c8b6befb288ea2a5ce7e78a499b4674" and "9fd5b1a28ea5c65c79512d39c2dad109dfd69a41" have entirely different histories.
5ab9c48e2c
...
9fd5b1a28e
27 changed files with 124 additions and 243 deletions
|
@ -1 +1 @@
|
||||||
1.8.1
|
1.5.0
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
nodejs 16.18.0
|
nodejs 12.14.1
|
||||||
crystal 1.5.0
|
crystal 1.5.0
|
||||||
|
|
33
CHANGELOG
33
CHANGELOG
|
@ -1,36 +1,3 @@
|
||||||
2023-05-06
|
|
||||||
|
|
||||||
* Upgrade to Lucky framework 1.0.0
|
|
||||||
* Upgrade to Crystal version 1.8.1
|
|
||||||
* If embedded media has a caption, it will now be displayed
|
|
||||||
|
|
||||||
2023-03-25
|
|
||||||
|
|
||||||
* Headings now have an ID so readers can link to a part if an article
|
|
||||||
* If a URL contains `global-identity-2`, Scribe will now correctly parse the article ID.
|
|
||||||
|
|
||||||
2022-11-06
|
|
||||||
|
|
||||||
* Fix viewing articles if the URL has a trailing slash
|
|
||||||
* Update to nodejs 16.18.0
|
|
||||||
|
|
||||||
2022-10-30
|
|
||||||
|
|
||||||
* Update to nodejs 16.18.0
|
|
||||||
|
|
||||||
2022-10-30
|
|
||||||
|
|
||||||
* Fix viewing articles if the URL has a trailing slash
|
|
||||||
|
|
||||||
2022-10-11
|
|
||||||
|
|
||||||
* Don't clip gist contents (CSS fix)
|
|
||||||
|
|
||||||
2022-09-24
|
|
||||||
|
|
||||||
* Replace Redirector extension with LibRedirect
|
|
||||||
* Remove downloadable Redirector config
|
|
||||||
|
|
||||||
2022-07-19
|
2022-07-19
|
||||||
|
|
||||||
* Fix downloadable config file for Redirector extension
|
* Fix downloadable config file for Redirector extension
|
||||||
|
|
|
@ -5,7 +5,5 @@
|
||||||
"https://scribe.bus-hit.me",
|
"https://scribe.bus-hit.me",
|
||||||
"https://scribe.froth.zone",
|
"https://scribe.froth.zone",
|
||||||
"https://scribe.esmailelbob.xyz",
|
"https://scribe.esmailelbob.xyz",
|
||||||
"https://scribe.privacydev.net",
|
"https://scribe.privacydev.net"
|
||||||
"https://scribe.rawbit.ninja",
|
|
||||||
"https://sc.vern.cc"
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,11 +7,7 @@
|
||||||
* <https://scribe.froth.zone>
|
* <https://scribe.froth.zone>
|
||||||
* <https://scribe.esmailelbob.xyz>
|
* <https://scribe.esmailelbob.xyz>
|
||||||
* <https://scribe.privacydev.net>
|
* <https://scribe.privacydev.net>
|
||||||
* <https://scribe.rawbit.ninja>
|
* <scribe.lqs5fjmajyp7rvp4qvyubwofzi6d4imua7vs237rkc4m5qogitqwrgyd.onion> (Tor)
|
||||||
* <http://scribe.esmail5pdn24shtvieloeedh7ehz3nrwcdivnfhfcedl7gf4kwddhkqd.onion> (Tor)
|
|
||||||
* <http://w7uhv5lxhgck72hhimdglmusc54t4m6bionlmd5mvyddq3bs53mohqid.onion> (Tor)
|
|
||||||
* <http://scribe.g4c3eya4clenolymqbpgwz3q3tawoxw56yhzk4vugqrl6dtu3ejvhjid.onion> (Tor)
|
|
||||||
* [sc.vern.i2p](http://vern3whzyfmjclq6snhlupma6nrmojghwp37tydfgqotj7sc6izq.b32.i2p) (I2P)
|
|
||||||
|
|
||||||
## How do I get my instance on this list?
|
## How do I get my instance on this list?
|
||||||
|
|
||||||
|
|
42
shard.lock
42
shard.lock
|
@ -2,27 +2,31 @@ version: 2.0
|
||||||
shards:
|
shards:
|
||||||
authentic:
|
authentic:
|
||||||
git: https://github.com/luckyframework/authentic.git
|
git: https://github.com/luckyframework/authentic.git
|
||||||
version: 1.0.0
|
version: 0.8.2
|
||||||
|
|
||||||
avram:
|
avram:
|
||||||
git: https://github.com/luckyframework/avram.git
|
git: https://github.com/luckyframework/avram.git
|
||||||
version: 1.0.0
|
version: 0.23.0
|
||||||
|
|
||||||
backtracer:
|
backtracer:
|
||||||
git: https://github.com/sija/backtracer.cr.git
|
git: https://github.com/sija/backtracer.cr.git
|
||||||
version: 1.2.2
|
version: 1.2.1
|
||||||
|
|
||||||
cadmium_transliterator:
|
cadmium_transliterator:
|
||||||
git: https://github.com/cadmiumcr/transliterator.git
|
git: https://github.com/cadmiumcr/transliterator.git
|
||||||
version: 0.1.0+git.commit.46c4c14594057dbcfaf27e7e7c8c164d3f0ce3f1
|
version: 0.1.0+git.commit.46c4c14594057dbcfaf27e7e7c8c164d3f0ce3f1
|
||||||
|
|
||||||
|
carbon:
|
||||||
|
git: https://github.com/luckyframework/carbon.git
|
||||||
|
version: 0.2.1
|
||||||
|
|
||||||
cry:
|
cry:
|
||||||
git: https://github.com/luckyframework/cry.git
|
git: https://github.com/luckyframework/cry.git
|
||||||
version: 0.4.3
|
version: 0.4.3
|
||||||
|
|
||||||
crystar:
|
crystar:
|
||||||
git: https://github.com/naqvis/crystar.git
|
git: https://github.com/naqvis/crystar.git
|
||||||
version: 0.2.0+git.commit.56db8bb9dfbd5ed6d7908353405a5fae632a6561
|
version: 0.2.0
|
||||||
|
|
||||||
db:
|
db:
|
||||||
git: https://github.com/crystal-lang/crystal-db.git
|
git: https://github.com/crystal-lang/crystal-db.git
|
||||||
|
@ -34,23 +38,15 @@ shards:
|
||||||
|
|
||||||
exception_page:
|
exception_page:
|
||||||
git: https://github.com/crystal-loot/exception_page.git
|
git: https://github.com/crystal-loot/exception_page.git
|
||||||
version: 0.3.0
|
version: 0.2.2
|
||||||
|
|
||||||
fnv:
|
|
||||||
git: https://github.com/naqvis/crystal-fnv.git
|
|
||||||
version: 0.1.3
|
|
||||||
|
|
||||||
habitat:
|
habitat:
|
||||||
git: https://github.com/luckyframework/habitat.git
|
git: https://github.com/luckyframework/habitat.git
|
||||||
version: 0.4.7
|
version: 0.4.7
|
||||||
|
|
||||||
html5:
|
|
||||||
git: https://github.com/naqvis/crystal-html5.git
|
|
||||||
version: 0.4.0
|
|
||||||
|
|
||||||
lucky:
|
lucky:
|
||||||
git: https://github.com/luckyframework/lucky.git
|
git: https://github.com/luckyframework/lucky.git
|
||||||
version: 1.0.0
|
version: 0.30.1
|
||||||
|
|
||||||
lucky_cache:
|
lucky_cache:
|
||||||
git: https://github.com/luckyframework/lucky_cache.git
|
git: https://github.com/luckyframework/lucky_cache.git
|
||||||
|
@ -62,11 +58,11 @@ shards:
|
||||||
|
|
||||||
lucky_flow:
|
lucky_flow:
|
||||||
git: https://github.com/luckyframework/lucky_flow.git
|
git: https://github.com/luckyframework/lucky_flow.git
|
||||||
version: 0.9.0
|
version: 0.7.3
|
||||||
|
|
||||||
lucky_router:
|
lucky_router:
|
||||||
git: https://github.com/luckyframework/lucky_router.git
|
git: https://github.com/luckyframework/lucky_router.git
|
||||||
version: 0.5.2
|
version: 0.5.1
|
||||||
|
|
||||||
lucky_task:
|
lucky_task:
|
||||||
git: https://github.com/luckyframework/lucky_task.git
|
git: https://github.com/luckyframework/lucky_task.git
|
||||||
|
@ -86,7 +82,7 @@ shards:
|
||||||
|
|
||||||
selenium:
|
selenium:
|
||||||
git: https://github.com/matthewmcgarvey/selenium.cr.git
|
git: https://github.com/matthewmcgarvey/selenium.cr.git
|
||||||
version: 0.10.0
|
version: 0.9.1
|
||||||
|
|
||||||
shell-table:
|
shell-table:
|
||||||
git: https://github.com/luckyframework/shell-table.cr.git
|
git: https://github.com/luckyframework/shell-table.cr.git
|
||||||
|
@ -102,17 +98,9 @@ shards:
|
||||||
|
|
||||||
webdrivers:
|
webdrivers:
|
||||||
git: https://github.com/matthewmcgarvey/webdrivers.cr.git
|
git: https://github.com/matthewmcgarvey/webdrivers.cr.git
|
||||||
version: 0.4.1
|
version: 0.4.0
|
||||||
|
|
||||||
webless:
|
|
||||||
git: https://github.com/matthewmcgarvey/webless.git
|
|
||||||
version: 0.1.0
|
|
||||||
|
|
||||||
wordsmith:
|
wordsmith:
|
||||||
git: https://github.com/luckyframework/wordsmith.git
|
git: https://github.com/luckyframework/wordsmith.git
|
||||||
version: 0.4.0
|
version: 0.3.0
|
||||||
|
|
||||||
xpath2:
|
|
||||||
git: https://github.com/naqvis/crystal-xpath2.git
|
|
||||||
version: 0.1.3
|
|
||||||
|
|
||||||
|
|
14
shard.yml
14
shard.yml
|
@ -8,18 +8,18 @@ targets:
|
||||||
scribe:
|
scribe:
|
||||||
main: src/scribe.cr
|
main: src/scribe.cr
|
||||||
|
|
||||||
crystal: 1.8.1
|
crystal: 1.5.0
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
lucky:
|
lucky:
|
||||||
github: luckyframework/lucky
|
github: luckyframework/lucky
|
||||||
version: ~> 1.0.0
|
version: ~> 0.30.1
|
||||||
avram:
|
|
||||||
github: luckyframework/avram
|
|
||||||
version: ~> 1.0.0
|
|
||||||
authentic:
|
authentic:
|
||||||
github: luckyframework/authentic
|
github: luckyframework/authentic
|
||||||
version: ~> 1.0.0
|
version: ~> 0.8.2
|
||||||
|
carbon:
|
||||||
|
github: luckyframework/carbon
|
||||||
|
version: ~> 0.2.0
|
||||||
lucky_env:
|
lucky_env:
|
||||||
github: luckyframework/lucky_env
|
github: luckyframework/lucky_env
|
||||||
version: ~> 0.1.4
|
version: ~> 0.1.4
|
||||||
|
@ -31,4 +31,4 @@ dependencies:
|
||||||
development_dependencies:
|
development_dependencies:
|
||||||
lucky_flow:
|
lucky_flow:
|
||||||
github: luckyframework/lucky_flow
|
github: luckyframework/lucky_flow
|
||||||
version: ~> 0.9.0
|
version: ~> 0.7.3
|
||||||
|
|
|
@ -78,14 +78,6 @@ describe ArticleIdParser do
|
||||||
result.should eq(Monads::Just.new("888888abcdef"))
|
result.should eq(Monads::Just.new("888888abcdef"))
|
||||||
end
|
end
|
||||||
|
|
||||||
it "parses the post id for global identity 2 redirects" do
|
|
||||||
request = resource_request("/m/global-identity-2?redirectUrl=https%3A%2F%2Fexample.com%2Fmy-post-999999abcdef")
|
|
||||||
|
|
||||||
result = ArticleIdParser.parse(request)
|
|
||||||
|
|
||||||
result.should eq(Monads::Just.new("999999abcdef"))
|
|
||||||
end
|
|
||||||
|
|
||||||
it "returns Nothing if path is a username" do
|
it "returns Nothing if path is a username" do
|
||||||
request = resource_request("/@ba5eba11")
|
request = resource_request("/@ba5eba11")
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ describe EmbeddedConverter do
|
||||||
store = GistStore.new
|
store = GistStore.new
|
||||||
paragraph = PostResponse::Paragraph.from_json <<-JSON
|
paragraph = PostResponse::Paragraph.from_json <<-JSON
|
||||||
{
|
{
|
||||||
"name": "ab12",
|
|
||||||
"text": "",
|
"text": "",
|
||||||
"type": "IFRAME",
|
"type": "IFRAME",
|
||||||
"href": null,
|
"href": null,
|
||||||
|
@ -37,44 +36,6 @@ describe EmbeddedConverter do
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
context "and a caption exists" do
|
|
||||||
it "returns an EmbeddedContent node with caption" do
|
|
||||||
store = GistStore.new
|
|
||||||
paragraph = PostResponse::Paragraph.from_json <<-JSON
|
|
||||||
{
|
|
||||||
"name": "ab12",
|
|
||||||
"text": "Caption",
|
|
||||||
"type": "IFRAME",
|
|
||||||
"href": null,
|
|
||||||
"layout": "INSET_CENTER",
|
|
||||||
"markups": [],
|
|
||||||
"iframe": {
|
|
||||||
"mediaResource": {
|
|
||||||
"id": "abc123",
|
|
||||||
"href": "https://twitter.com/user/status/1",
|
|
||||||
"iframeSrc": "https://cdn.embedly.com/widgets/...",
|
|
||||||
"iframeWidth": 500,
|
|
||||||
"iframeHeight": 281
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"metadata": null
|
|
||||||
}
|
|
||||||
JSON
|
|
||||||
caption = FigureCaption.new(children: [Text.new("Caption")] of Child)
|
|
||||||
|
|
||||||
result = EmbeddedConverter.convert(paragraph, store)
|
|
||||||
|
|
||||||
result.should eq(
|
|
||||||
EmbeddedContent.new(
|
|
||||||
src: "https://cdn.embedly.com/widgets/...",
|
|
||||||
originalWidth: 500,
|
|
||||||
originalHeight: 281,
|
|
||||||
caption: caption,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when the mediaResource has a blank iframeSrc value" do
|
context "when the mediaResource has a blank iframeSrc value" do
|
||||||
|
@ -83,7 +44,6 @@ describe EmbeddedConverter do
|
||||||
store = GistStore.new
|
store = GistStore.new
|
||||||
paragraph = PostResponse::Paragraph.from_json <<-JSON
|
paragraph = PostResponse::Paragraph.from_json <<-JSON
|
||||||
{
|
{
|
||||||
"name": "ab12",
|
|
||||||
"text": "",
|
"text": "",
|
||||||
"type": "IFRAME",
|
"type": "IFRAME",
|
||||||
"href": null,
|
"href": null,
|
||||||
|
@ -113,7 +73,6 @@ describe EmbeddedConverter do
|
||||||
store = GistStore.new
|
store = GistStore.new
|
||||||
paragraph = PostResponse::Paragraph.from_json <<-JSON
|
paragraph = PostResponse::Paragraph.from_json <<-JSON
|
||||||
{
|
{
|
||||||
"name": "ab12",
|
|
||||||
"text": "",
|
"text": "",
|
||||||
"type": "IFRAME",
|
"type": "IFRAME",
|
||||||
"href": null,
|
"href": null,
|
||||||
|
|
|
@ -12,7 +12,6 @@ describe GistScanner do
|
||||||
)
|
)
|
||||||
paragraphs = [
|
paragraphs = [
|
||||||
PostResponse::Paragraph.new(
|
PostResponse::Paragraph.new(
|
||||||
name: "ab12",
|
|
||||||
text: "Check out this gist:",
|
text: "Check out this gist:",
|
||||||
type: PostResponse::ParagraphType::P,
|
type: PostResponse::ParagraphType::P,
|
||||||
markups: [] of PostResponse::Markup,
|
markups: [] of PostResponse::Markup,
|
||||||
|
@ -21,7 +20,6 @@ describe GistScanner do
|
||||||
metadata: nil
|
metadata: nil
|
||||||
),
|
),
|
||||||
PostResponse::Paragraph.new(
|
PostResponse::Paragraph.new(
|
||||||
name: "ab13",
|
|
||||||
text: "",
|
text: "",
|
||||||
type: PostResponse::ParagraphType::IFRAME,
|
type: PostResponse::ParagraphType::IFRAME,
|
||||||
markups: [] of PostResponse::Markup,
|
markups: [] of PostResponse::Markup,
|
||||||
|
@ -47,7 +45,6 @@ describe GistScanner do
|
||||||
)
|
)
|
||||||
paragraphs = [
|
paragraphs = [
|
||||||
PostResponse::Paragraph.new(
|
PostResponse::Paragraph.new(
|
||||||
name: "ab12",
|
|
||||||
text: "",
|
text: "",
|
||||||
type: PostResponse::ParagraphType::IFRAME,
|
type: PostResponse::ParagraphType::IFRAME,
|
||||||
markups: [] of PostResponse::Markup,
|
markups: [] of PostResponse::Markup,
|
||||||
|
@ -81,7 +78,6 @@ describe GistScanner do
|
||||||
)
|
)
|
||||||
paragraphs = [
|
paragraphs = [
|
||||||
PostResponse::Paragraph.new(
|
PostResponse::Paragraph.new(
|
||||||
name: "ab12",
|
|
||||||
text: "",
|
text: "",
|
||||||
type: PostResponse::ParagraphType::IFRAME,
|
type: PostResponse::ParagraphType::IFRAME,
|
||||||
markups: [] of PostResponse::Markup,
|
markups: [] of PostResponse::Markup,
|
||||||
|
@ -90,7 +86,6 @@ describe GistScanner do
|
||||||
metadata: nil
|
metadata: nil
|
||||||
),
|
),
|
||||||
PostResponse::Paragraph.new(
|
PostResponse::Paragraph.new(
|
||||||
name: "ab13",
|
|
||||||
text: "",
|
text: "",
|
||||||
type: PostResponse::ParagraphType::IFRAME,
|
type: PostResponse::ParagraphType::IFRAME,
|
||||||
markups: [] of PostResponse::Markup,
|
markups: [] of PostResponse::Markup,
|
||||||
|
|
|
@ -8,7 +8,6 @@ describe PageConverter do
|
||||||
paragraph_json = <<-JSON
|
paragraph_json = <<-JSON
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "ab12",
|
|
||||||
"text": "#{title}",
|
"text": "#{title}",
|
||||||
"type": "H3",
|
"type": "H3",
|
||||||
"markups": [],
|
"markups": [],
|
||||||
|
@ -29,7 +28,6 @@ describe PageConverter do
|
||||||
it "sets the author" do
|
it "sets the author" do
|
||||||
post_json = <<-JSON
|
post_json = <<-JSON
|
||||||
{
|
{
|
||||||
"name": "ab12",
|
|
||||||
"title": "This is a story",
|
"title": "This is a story",
|
||||||
"createdAt": 0,
|
"createdAt": 0,
|
||||||
"creator": {
|
"creator": {
|
||||||
|
@ -54,7 +52,6 @@ describe PageConverter do
|
||||||
it "sets the publish date/time" do
|
it "sets the publish date/time" do
|
||||||
post_json = <<-JSON
|
post_json = <<-JSON
|
||||||
{
|
{
|
||||||
"name": "ab12",
|
|
||||||
"title": "This is a story",
|
"title": "This is a story",
|
||||||
"createdAt": 1000,
|
"createdAt": 1000,
|
||||||
"creator": {
|
"creator": {
|
||||||
|
@ -80,7 +77,6 @@ describe PageConverter do
|
||||||
paragraph_json = <<-JSON
|
paragraph_json = <<-JSON
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "ab12",
|
|
||||||
"text": "#{title}",
|
"text": "#{title}",
|
||||||
"type": "H3",
|
"type": "H3",
|
||||||
"markups": [],
|
"markups": [],
|
||||||
|
@ -89,7 +85,6 @@ describe PageConverter do
|
||||||
"metadata": null
|
"metadata": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ab12",
|
|
||||||
"text": "Content",
|
"text": "Content",
|
||||||
"type": "P",
|
"type": "P",
|
||||||
"markups": [],
|
"markups": [],
|
||||||
|
@ -122,7 +117,6 @@ def default_post_json(
|
||||||
)
|
)
|
||||||
<<-JSON
|
<<-JSON
|
||||||
{
|
{
|
||||||
"name": "ab12",
|
|
||||||
"title": "#{title}",
|
"title": "#{title}",
|
||||||
"createdAt": 1628974309758,
|
"createdAt": 1628974309758,
|
||||||
"creator": {
|
"creator": {
|
||||||
|
|
|
@ -8,7 +8,6 @@ describe ParagraphConverter do
|
||||||
paragraphs = Array(PostResponse::Paragraph).from_json <<-JSON
|
paragraphs = Array(PostResponse::Paragraph).from_json <<-JSON
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "ab12",
|
|
||||||
"text": "Title",
|
"text": "Title",
|
||||||
"type": "H3",
|
"type": "H3",
|
||||||
"markups": [],
|
"markups": [],
|
||||||
|
@ -18,7 +17,7 @@ describe ParagraphConverter do
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
JSON
|
JSON
|
||||||
expected = [Heading3.new(children: [Text.new(content: "Title")] of Child, identifier: "ab12")]
|
expected = [Heading3.new(children: [Text.new(content: "Title")] of Child)]
|
||||||
|
|
||||||
result = ParagraphConverter.new.convert(paragraphs, gist_store)
|
result = ParagraphConverter.new.convert(paragraphs, gist_store)
|
||||||
|
|
||||||
|
@ -30,7 +29,6 @@ describe ParagraphConverter do
|
||||||
paragraphs = Array(PostResponse::Paragraph).from_json <<-JSON
|
paragraphs = Array(PostResponse::Paragraph).from_json <<-JSON
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "ab12",
|
|
||||||
"text": "inline code",
|
"text": "inline code",
|
||||||
"type": "P",
|
"type": "P",
|
||||||
"markups": [
|
"markups": [
|
||||||
|
@ -68,7 +66,6 @@ describe ParagraphConverter do
|
||||||
paragraphs = Array(PostResponse::Paragraph).from_json <<-JSON
|
paragraphs = Array(PostResponse::Paragraph).from_json <<-JSON
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "ab12",
|
|
||||||
"text": "One",
|
"text": "One",
|
||||||
"type": "ULI",
|
"type": "ULI",
|
||||||
"markups": [],
|
"markups": [],
|
||||||
|
@ -77,7 +74,6 @@ describe ParagraphConverter do
|
||||||
"metadata": null
|
"metadata": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ab13",
|
|
||||||
"text": "Two",
|
"text": "Two",
|
||||||
"type": "ULI",
|
"type": "ULI",
|
||||||
"markups": [],
|
"markups": [],
|
||||||
|
@ -86,7 +82,6 @@ describe ParagraphConverter do
|
||||||
"metadata": null
|
"metadata": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ab14",
|
|
||||||
"text": "Not a list item",
|
"text": "Not a list item",
|
||||||
"type": "P",
|
"type": "P",
|
||||||
"markups": [],
|
"markups": [],
|
||||||
|
@ -114,7 +109,6 @@ describe ParagraphConverter do
|
||||||
paragraphs = Array(PostResponse::Paragraph).from_json <<-JSON
|
paragraphs = Array(PostResponse::Paragraph).from_json <<-JSON
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "ab12",
|
|
||||||
"text": "One",
|
"text": "One",
|
||||||
"type": "OLI",
|
"type": "OLI",
|
||||||
"markups": [],
|
"markups": [],
|
||||||
|
@ -123,7 +117,6 @@ describe ParagraphConverter do
|
||||||
"metadata": null
|
"metadata": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ab13",
|
|
||||||
"text": "Two",
|
"text": "Two",
|
||||||
"type": "OLI",
|
"type": "OLI",
|
||||||
"markups": [],
|
"markups": [],
|
||||||
|
@ -132,7 +125,6 @@ describe ParagraphConverter do
|
||||||
"metadata": null
|
"metadata": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ab14",
|
|
||||||
"text": "Not a list item",
|
"text": "Not a list item",
|
||||||
"type": "P",
|
"type": "P",
|
||||||
"markups": [],
|
"markups": [],
|
||||||
|
@ -159,7 +151,6 @@ describe ParagraphConverter do
|
||||||
gist_store = GistStore.new
|
gist_store = GistStore.new
|
||||||
paragraph = PostResponse::Paragraph.from_json <<-JSON
|
paragraph = PostResponse::Paragraph.from_json <<-JSON
|
||||||
{
|
{
|
||||||
"name": "ab12",
|
|
||||||
"text": "Image by someuser",
|
"text": "Image by someuser",
|
||||||
"type": "IMG",
|
"type": "IMG",
|
||||||
"markups": [
|
"markups": [
|
||||||
|
@ -206,7 +197,6 @@ describe ParagraphConverter do
|
||||||
paragraphs = Array(PostResponse::Paragraph).from_json <<-JSON
|
paragraphs = Array(PostResponse::Paragraph).from_json <<-JSON
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "ab12",
|
|
||||||
"text": "text",
|
"text": "text",
|
||||||
"type": "H2",
|
"type": "H2",
|
||||||
"markups": [],
|
"markups": [],
|
||||||
|
@ -215,7 +205,6 @@ describe ParagraphConverter do
|
||||||
"metadata": null
|
"metadata": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ab13",
|
|
||||||
"text": "text",
|
"text": "text",
|
||||||
"type": "H3",
|
"type": "H3",
|
||||||
"markups": [],
|
"markups": [],
|
||||||
|
@ -224,7 +213,6 @@ describe ParagraphConverter do
|
||||||
"metadata": null
|
"metadata": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ab14",
|
|
||||||
"text": "text",
|
"text": "text",
|
||||||
"type": "H4",
|
"type": "H4",
|
||||||
"markups": [],
|
"markups": [],
|
||||||
|
@ -233,7 +221,6 @@ describe ParagraphConverter do
|
||||||
"metadata": null
|
"metadata": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ab15",
|
|
||||||
"text": "text",
|
"text": "text",
|
||||||
"type": "P",
|
"type": "P",
|
||||||
"markups": [],
|
"markups": [],
|
||||||
|
@ -242,7 +229,6 @@ describe ParagraphConverter do
|
||||||
"metadata": null
|
"metadata": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ab16",
|
|
||||||
"text": "text",
|
"text": "text",
|
||||||
"type": "PRE",
|
"type": "PRE",
|
||||||
"markups": [],
|
"markups": [],
|
||||||
|
@ -251,7 +237,6 @@ describe ParagraphConverter do
|
||||||
"metadata": null
|
"metadata": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ab17",
|
|
||||||
"text": "text",
|
"text": "text",
|
||||||
"type": "BQ",
|
"type": "BQ",
|
||||||
"markups": [],
|
"markups": [],
|
||||||
|
@ -260,7 +245,6 @@ describe ParagraphConverter do
|
||||||
"metadata": null
|
"metadata": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ab18",
|
|
||||||
"text": "text",
|
"text": "text",
|
||||||
"type": "PQ",
|
"type": "PQ",
|
||||||
"markups": [],
|
"markups": [],
|
||||||
|
@ -269,7 +253,6 @@ describe ParagraphConverter do
|
||||||
"metadata": null
|
"metadata": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ab19",
|
|
||||||
"text": "text",
|
"text": "text",
|
||||||
"type": "ULI",
|
"type": "ULI",
|
||||||
"markups": [],
|
"markups": [],
|
||||||
|
@ -278,7 +261,6 @@ describe ParagraphConverter do
|
||||||
"metadata": null
|
"metadata": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ab20",
|
|
||||||
"text": "text",
|
"text": "text",
|
||||||
"type": "OLI",
|
"type": "OLI",
|
||||||
"markups": [],
|
"markups": [],
|
||||||
|
@ -287,7 +269,6 @@ describe ParagraphConverter do
|
||||||
"metadata": null
|
"metadata": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ab21",
|
|
||||||
"text": "text",
|
"text": "text",
|
||||||
"type": "IMG",
|
"type": "IMG",
|
||||||
"markups": [],
|
"markups": [],
|
||||||
|
@ -300,7 +281,6 @@ describe ParagraphConverter do
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ab22",
|
|
||||||
"text": "",
|
"text": "",
|
||||||
"type": "IFRAME",
|
"type": "IFRAME",
|
||||||
"markups": [],
|
"markups": [],
|
||||||
|
@ -316,7 +296,6 @@ describe ParagraphConverter do
|
||||||
"metadata": null
|
"metadata": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ab23",
|
|
||||||
"text": "Mixtape",
|
"text": "Mixtape",
|
||||||
"type": "MIXTAPE_EMBED",
|
"type": "MIXTAPE_EMBED",
|
||||||
"href": null,
|
"href": null,
|
||||||
|
@ -338,9 +317,9 @@ describe ParagraphConverter do
|
||||||
]
|
]
|
||||||
JSON
|
JSON
|
||||||
expected = [
|
expected = [
|
||||||
Heading1.new([Text.new("text")] of Child, identifier: "ab12"),
|
Heading1.new([Text.new("text")] of Child),
|
||||||
Heading2.new([Text.new("text")] of Child, identifier: "ab13"),
|
Heading2.new([Text.new("text")] of Child),
|
||||||
Heading3.new([Text.new("text")] of Child, identifier: "ab14"),
|
Heading3.new([Text.new("text")] of Child),
|
||||||
Paragraph.new([Text.new("text")] of Child),
|
Paragraph.new([Text.new("text")] of Child),
|
||||||
Preformatted.new([Text.new("text")] of Child),
|
Preformatted.new([Text.new("text")] of Child),
|
||||||
BlockQuote.new([Text.new("text")] of Child), # BQ
|
BlockQuote.new([Text.new("text")] of Child), # BQ
|
||||||
|
|
|
@ -184,13 +184,13 @@ describe PageContent do
|
||||||
nodes: [
|
nodes: [
|
||||||
Heading1.new(children: [
|
Heading1.new(children: [
|
||||||
Text.new(content: "Title!"),
|
Text.new(content: "Title!"),
|
||||||
] of Child, identifier: "ab12"),
|
] of Child),
|
||||||
] of Child
|
] of Child
|
||||||
)
|
)
|
||||||
|
|
||||||
html = PageContent.new(page: page).render_to_string
|
html = PageContent.new(page: page).render_to_string
|
||||||
|
|
||||||
html.should eq %(<h1 id="ab12">Title!</h1>)
|
html.should eq %(<h1>Title!</h1>)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "renders an H3" do
|
it "renders an H3" do
|
||||||
|
@ -201,13 +201,13 @@ describe PageContent do
|
||||||
nodes: [
|
nodes: [
|
||||||
Heading2.new(children: [
|
Heading2.new(children: [
|
||||||
Text.new(content: "Title!"),
|
Text.new(content: "Title!"),
|
||||||
] of Child, identifier: "ab12"),
|
] of Child),
|
||||||
] of Child
|
] of Child
|
||||||
)
|
)
|
||||||
|
|
||||||
html = PageContent.new(page: page).render_to_string
|
html = PageContent.new(page: page).render_to_string
|
||||||
|
|
||||||
html.should eq %(<h2 id="ab12">Title!</h2>)
|
html.should eq %(<h2>Title!</h2>)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "renders an H4" do
|
it "renders an H4" do
|
||||||
|
@ -218,13 +218,13 @@ describe PageContent do
|
||||||
nodes: [
|
nodes: [
|
||||||
Heading3.new(children: [
|
Heading3.new(children: [
|
||||||
Text.new(content: "In Conclusion..."),
|
Text.new(content: "In Conclusion..."),
|
||||||
] of Child, identifier: "ab12"),
|
] of Child),
|
||||||
] of Child
|
] of Child
|
||||||
)
|
)
|
||||||
|
|
||||||
html = PageContent.new(page: page).render_to_string
|
html = PageContent.new(page: page).render_to_string
|
||||||
|
|
||||||
html.should eq %(<h3 id="ab12">In Conclusion...</h3>)
|
html.should eq %(<h3>In Conclusion...</h3>)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "renders an image" do
|
it "renders an image" do
|
||||||
|
@ -249,7 +249,6 @@ describe PageContent do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "renders embedded content" do
|
it "renders embedded content" do
|
||||||
caption_children = [Text.new("Caption")] of Child
|
|
||||||
page = Page.new(
|
page = Page.new(
|
||||||
title: "Title",
|
title: "Title",
|
||||||
author: user_anchor_factory,
|
author: user_anchor_factory,
|
||||||
|
@ -259,7 +258,6 @@ describe PageContent do
|
||||||
src: "https://example.com",
|
src: "https://example.com",
|
||||||
originalWidth: 1000,
|
originalWidth: 1000,
|
||||||
originalHeight: 600,
|
originalHeight: 600,
|
||||||
caption: FigureCaption.new(children: caption_children)
|
|
||||||
),
|
),
|
||||||
] of Child
|
] of Child
|
||||||
)
|
)
|
||||||
|
@ -270,11 +268,6 @@ describe PageContent do
|
||||||
<figure>
|
<figure>
|
||||||
<iframe src="https://example.com" width="800" height="480" frameborder="0" allowfullscreen="true">
|
<iframe src="https://example.com" width="800" height="480" frameborder="0" allowfullscreen="true">
|
||||||
</iframe>
|
</iframe>
|
||||||
<label class="margin-toggle" for="#{caption_children.hash}">✍︎</label>
|
|
||||||
<input class="margin-toggle" type="checkbox" id="#{caption_children.hash}">
|
|
||||||
<span class="marginnote">
|
|
||||||
Caption
|
|
||||||
</span>
|
|
||||||
</figure>
|
</figure>
|
||||||
HTML
|
HTML
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,10 +4,10 @@
|
||||||
LuckyFlow.configure do |settings|
|
LuckyFlow.configure do |settings|
|
||||||
settings.stop_retrying_after = 200.milliseconds
|
settings.stop_retrying_after = 200.milliseconds
|
||||||
settings.base_uri = Lucky::RouteHelper.settings.base_uri
|
settings.base_uri = Lucky::RouteHelper.settings.base_uri
|
||||||
|
|
||||||
# By default, LuckyFlow is set in "headless" mode (no browser window shown).
|
# By default, LuckyFlow is set in "headless" mode (no browser window shown).
|
||||||
# Uncomment this to enable running `LuckyFlow` in a Google Chrome window instead.
|
# Uncomment this to enable running `LuckyFlow` in a Google Chrome window instead.
|
||||||
# Be sure to disable for CI.
|
# Be sure to disable for CI.
|
||||||
# settings.driver = LuckyFlow::Drivers::Chrome
|
# settings.driver = LuckyFlow::Drivers::Chrome
|
||||||
end
|
end
|
||||||
LuckyFlow::Spec.setup
|
Spec.before_each { LuckyFlow::Server::INSTANCE.reset }
|
||||||
|
|
|
@ -2,8 +2,6 @@ ENV["LUCKY_ENV"] = "test"
|
||||||
ENV["DEV_PORT"] = "5001"
|
ENV["DEV_PORT"] = "5001"
|
||||||
require "spec"
|
require "spec"
|
||||||
require "lucky_flow"
|
require "lucky_flow"
|
||||||
require "lucky_flow/ext/lucky"
|
|
||||||
require "lucky_flow/ext/avram"
|
|
||||||
require "../src/app"
|
require "../src/app"
|
||||||
require "./support/flows/base_flow"
|
require "./support/flows/base_flow"
|
||||||
require "./support/**"
|
require "./support/**"
|
||||||
|
|
56
src/actions/redirection_config/index.cr
Normal file
56
src/actions/redirection_config/index.cr
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
class RedirectionConfig::Index < Lucky::Action
|
||||||
|
include Lucky::ProtectFromForgery
|
||||||
|
include Lucky::EnforceUnderscoredRoute
|
||||||
|
include Lucky::SecureHeaders::DisableFLoC
|
||||||
|
|
||||||
|
default_format :json
|
||||||
|
|
||||||
|
get "/redirection_config" do
|
||||||
|
data(
|
||||||
|
data: config_json,
|
||||||
|
content_type: "application/json",
|
||||||
|
disposition: "attachment",
|
||||||
|
filename: "redirector-config.json"
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
private def config_json
|
||||||
|
double_escaped_pattern = "^https?://(?:.*\\\\.)*(?<!(link\\\\.|cdn\\\\-images\\\\-\\\\d+\\\\.))medium\\\\.com(/.*)?$"
|
||||||
|
<<-JSON
|
||||||
|
{
|
||||||
|
"createdBy": "Redirector v3.5.3",
|
||||||
|
"createdAt": "2022-07-17T00:00:00.000Z",
|
||||||
|
"redirects": [
|
||||||
|
{
|
||||||
|
"description": "Medium -> Scribe",
|
||||||
|
"exampleUrl": "https://medium.com/@user/post-123456abcdef",
|
||||||
|
"exampleResult": "https://#{app_domain}/@user/post-123456abcdef",
|
||||||
|
"error": null,
|
||||||
|
"includePattern": "#{double_escaped_pattern}",
|
||||||
|
"excludePattern": "",
|
||||||
|
"patternDesc": "",
|
||||||
|
"redirectUrl": "https://#{app_domain}$2",
|
||||||
|
"patternType": "R",
|
||||||
|
"processMatches": "noProcessing",
|
||||||
|
"disabled": false,
|
||||||
|
"grouped": false,
|
||||||
|
"appliesTo": [
|
||||||
|
"main_frame",
|
||||||
|
"sub_frame",
|
||||||
|
"xmlhttprequest",
|
||||||
|
"history",
|
||||||
|
"other"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
JSON
|
||||||
|
end
|
||||||
|
|
||||||
|
private def app_domain
|
||||||
|
URI.parse(Home::Index.url).normalize
|
||||||
|
.to_s
|
||||||
|
.sub(/\/$/, "")
|
||||||
|
.sub(/^https?:\/\//, "")
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,7 +1,7 @@
|
||||||
class ArticleIdParser
|
class ArticleIdParser
|
||||||
include Monads
|
include Monads
|
||||||
|
|
||||||
ID_REGEX = /[\/\-]([0-9a-f]+)\/?$/i
|
ID_REGEX = /[\/\-]([0-9a-f]+)$/i
|
||||||
|
|
||||||
def self.parse(request : HTTP::Request)
|
def self.parse(request : HTTP::Request)
|
||||||
new.parse(request)
|
new.parse(request)
|
||||||
|
@ -10,7 +10,7 @@ class ArticleIdParser
|
||||||
def parse(request : HTTP::Request) : Maybe
|
def parse(request : HTTP::Request) : Maybe
|
||||||
from_params = post_id_from_params(request.query_params)
|
from_params = post_id_from_params(request.query_params)
|
||||||
from_path = post_id_from_path(request.path)
|
from_path = post_id_from_path(request.path)
|
||||||
from_params.or(from_path)
|
from_path.or(from_params)
|
||||||
end
|
end
|
||||||
|
|
||||||
private def post_id_from_path(request_path : String)
|
private def post_id_from_path(request_path : String)
|
||||||
|
|
|
@ -34,19 +34,11 @@ class EmbeddedConverter
|
||||||
EmbeddedContent.new(
|
EmbeddedContent.new(
|
||||||
src: media.iframeSrc,
|
src: media.iframeSrc,
|
||||||
originalWidth: media.iframeWidth,
|
originalWidth: media.iframeWidth,
|
||||||
originalHeight: media.iframeHeight,
|
originalHeight: media.iframeHeight
|
||||||
caption: caption
|
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private def caption : FigureCaption?
|
|
||||||
if !paragraph.text.blank?
|
|
||||||
children = [Text.new(paragraph.text || "")] of Child
|
|
||||||
FigureCaption.new(children: children)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private def custom_embed(media : PostResponse::MediaResource) : Embedded
|
private def custom_embed(media : PostResponse::MediaResource) : Embedded
|
||||||
if media.href.starts_with?(GIST_HOST_AND_SCHEME)
|
if media.href.starts_with?(GIST_HOST_AND_SCHEME)
|
||||||
GithubGist.new(href: media.href, gist_store: gist_store)
|
GithubGist.new(href: media.href, gist_store: gist_store)
|
||||||
|
|
|
@ -16,15 +16,15 @@ class ParagraphConverter
|
||||||
when PostResponse::ParagraphType::H2
|
when PostResponse::ParagraphType::H2
|
||||||
paragraph = paragraphs.shift
|
paragraph = paragraphs.shift
|
||||||
children = MarkupConverter.convert(paragraph.text, paragraph.markups)
|
children = MarkupConverter.convert(paragraph.text, paragraph.markups)
|
||||||
node = Heading1.new(children: children, identifier: paragraph.name || "")
|
node = Heading1.new(children: children)
|
||||||
when PostResponse::ParagraphType::H3
|
when PostResponse::ParagraphType::H3
|
||||||
paragraph = paragraphs.shift
|
paragraph = paragraphs.shift
|
||||||
children = MarkupConverter.convert(paragraph.text, paragraph.markups)
|
children = MarkupConverter.convert(paragraph.text, paragraph.markups)
|
||||||
node = Heading2.new(children: children, identifier: paragraph.name || "")
|
node = Heading2.new(children: children)
|
||||||
when PostResponse::ParagraphType::H4
|
when PostResponse::ParagraphType::H4
|
||||||
paragraph = paragraphs.shift
|
paragraph = paragraphs.shift
|
||||||
children = MarkupConverter.convert(paragraph.text, paragraph.markups)
|
children = MarkupConverter.convert(paragraph.text, paragraph.markups)
|
||||||
node = Heading3.new(children: children, identifier: paragraph.name || "")
|
node = Heading3.new(children: children)
|
||||||
when PostResponse::ParagraphType::IFRAME
|
when PostResponse::ParagraphType::IFRAME
|
||||||
paragraph = paragraphs.shift
|
paragraph = paragraphs.shift
|
||||||
node = EmbeddedConverter.convert(paragraph, gist_store)
|
node = EmbeddedConverter.convert(paragraph, gist_store)
|
||||||
|
|
|
@ -27,7 +27,6 @@ class MediumClient
|
||||||
content {
|
content {
|
||||||
bodyModel {
|
bodyModel {
|
||||||
paragraphs {
|
paragraphs {
|
||||||
name
|
|
||||||
text
|
text
|
||||||
type
|
type
|
||||||
href
|
href
|
||||||
|
|
|
@ -40,9 +40,6 @@ class PageContent < BaseComponent
|
||||||
frameborder: "0",
|
frameborder: "0",
|
||||||
allowfullscreen: true,
|
allowfullscreen: true,
|
||||||
)
|
)
|
||||||
if caption = child.caption
|
|
||||||
render_child(caption)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -96,15 +93,15 @@ class PageContent < BaseComponent
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_child(node : Heading1)
|
def render_child(node : Heading1)
|
||||||
h1(id: node.identifier) { render_children(node.children) }
|
h1 { render_children(node.children) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_child(node : Heading2)
|
def render_child(node : Heading2)
|
||||||
h2(id: node.identifier) { render_children(node.children) }
|
h2 { render_children(node.children) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_child(node : Heading3)
|
def render_child(node : Heading3)
|
||||||
h3(id: node.identifier) { render_children(node.children) }
|
h3 { render_children(node.children) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_child(child : Image)
|
def render_child(child : Image)
|
||||||
|
|
|
@ -7,22 +7,13 @@ p.meta {
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre {
|
.gist {
|
||||||
background-color: rgba(127, 127, 127, 0.1);
|
width: 55%;
|
||||||
margin-right: 1em;
|
|
||||||
padding: 1em;
|
|
||||||
padding-left: 2em;
|
|
||||||
overflow-x: scroll;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre > code {
|
|
||||||
margin-left: 0;
|
|
||||||
width: 100%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 760px) {
|
@media (max-width: 760px) {
|
||||||
pre {
|
.gist {
|
||||||
margin-right: 0;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,3 +118,4 @@ code {
|
||||||
h1, .meta {
|
h1, .meta {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,24 +41,12 @@ module Nodes
|
||||||
end
|
end
|
||||||
|
|
||||||
class Heading1 < Container
|
class Heading1 < Container
|
||||||
getter identifier : String
|
|
||||||
|
|
||||||
def initialize(@children : Children, @identifier : String)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class Heading2 < Container
|
class Heading2 < Container
|
||||||
getter identifier : String
|
|
||||||
|
|
||||||
def initialize(@children : Children, @identifier : String)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class Heading3 < Container
|
class Heading3 < Container
|
||||||
getter identifier : String
|
|
||||||
|
|
||||||
def initialize(@children : Children, @identifier : String)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class ListItem < Container
|
class ListItem < Container
|
||||||
|
@ -147,14 +135,8 @@ module Nodes
|
||||||
MAX_WIDTH = 800
|
MAX_WIDTH = 800
|
||||||
|
|
||||||
getter src : String
|
getter src : String
|
||||||
getter caption : FigureCaption?
|
|
||||||
|
|
||||||
def initialize(
|
def initialize(@src : String, @originalWidth : Int32, @originalHeight : Int32)
|
||||||
@src : String,
|
|
||||||
@originalWidth : Int32,
|
|
||||||
@originalHeight : Int32,
|
|
||||||
@caption : FigureCaption? = nil
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def width
|
def width
|
||||||
|
@ -174,10 +156,7 @@ module Nodes
|
||||||
end
|
end
|
||||||
|
|
||||||
def ==(other : EmbeddedContent)
|
def ==(other : EmbeddedContent)
|
||||||
other.src == src &&
|
other.src == src && other.width == width && other.height == height
|
||||||
other.width == width &&
|
|
||||||
other.height == height &&
|
|
||||||
other.caption == caption
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def empty?
|
def empty?
|
||||||
|
|
|
@ -32,7 +32,6 @@ class PostResponse
|
||||||
end
|
end
|
||||||
|
|
||||||
class Paragraph < Base
|
class Paragraph < Base
|
||||||
property name : String?
|
|
||||||
property text : String?
|
property text : String?
|
||||||
property type : ParagraphType
|
property type : ParagraphType
|
||||||
property markups : Array(Markup)
|
property markups : Array(Markup)
|
||||||
|
@ -41,7 +40,6 @@ class PostResponse
|
||||||
property metadata : Metadata?
|
property metadata : Metadata?
|
||||||
|
|
||||||
def initialize(
|
def initialize(
|
||||||
@name : String,
|
|
||||||
@text : String?,
|
@text : String?,
|
||||||
@type : ParagraphType,
|
@type : ParagraphType,
|
||||||
@markups : Array(Markup),
|
@markups : Array(Markup),
|
||||||
|
|
|
@ -18,9 +18,19 @@ class Faq::IndexPage < MainLayout
|
||||||
section do
|
section do
|
||||||
h2 "How-to Automatically Redirect Medium Articles"
|
h2 "How-to Automatically Redirect Medium Articles"
|
||||||
para do
|
para do
|
||||||
text "If you don't want to manually change the URL every time, you can use an extension to do it for you. The "
|
text "If you don't want to manually change the URL every time, you can use an extension to do it for you. "
|
||||||
a "LibRedirect extention", href: "https://libredirect.github.io/"
|
a "This extension", href: "https://einaregilsson.com/redirector/"
|
||||||
text " works well across most browsers, and will also redirect to other alternative services."
|
text " works well across most browsers."
|
||||||
|
end
|
||||||
|
para do
|
||||||
|
text "Once installed download a configuration file by "
|
||||||
|
link "clicking here", to: RedirectionConfig::Index
|
||||||
|
text "."
|
||||||
|
end
|
||||||
|
para do
|
||||||
|
text "Install it by opening the extension preferences, editing redirects, clicking "
|
||||||
|
code "Import"
|
||||||
|
text " and selecting the downloaded file. This will add a new redirection and not overwrite any existing ones. Now visiting any medium.com site (including user.medium.com subdomains) should redirect to Scribe instead!"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
module Scribe
|
module Scribe
|
||||||
VERSION = "2023-05-06"
|
VERSION = "2022-07-19"
|
||||||
end
|
end
|
||||||
|
|
1
tasks.cr
1
tasks.cr
|
@ -7,6 +7,5 @@ require "lucky_task"
|
||||||
require "./tasks/**"
|
require "./tasks/**"
|
||||||
require "./db/migrations/**"
|
require "./db/migrations/**"
|
||||||
require "lucky/tasks/**"
|
require "lucky/tasks/**"
|
||||||
require "avram/lucky/tasks"
|
|
||||||
|
|
||||||
LuckyTask::Runner.run
|
LuckyTask::Runner.run
|
||||||
|
|
Loading…
Reference in a new issue