Skip to content

Commit 5d09e71

Browse files
authored
Merge pull request #95 from takker99/extentional-parser
Extentional parser
2 parents 31cedad + c982433 commit 5d09e71

18 files changed

+588
-34
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@ jobs:
1717
- name: Run type check
1818
run: deno check --remote ./**/*.ts
1919
- name: Run test
20-
run: deno test
20+
run: deno test --allow-read --allow-write

.github/workflows/udd.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
run: >
1818
deno run --allow-net --allow-read --allow-write=deps/
1919
--allow-run=deno https://deno.land/x/[email protected]/main.ts deps/*.ts
20-
--test="deno test"
20+
--test="deno test --allow-read --allow-write"
2121
- name: Create Pull Request
2222
uses: peter-evans/create-pull-request@v3
2323
with:

browser/websocket/makeChanges.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
import type { Change } from "../../deps/socket.ts";
1111
import type { HeadData } from "./pull.ts";
1212
import { toTitleLc } from "../../title.ts";
13-
import { parseYoutube } from "../../parseYoutube.ts";
13+
import { parseYoutube } from "../../parser/youtube.ts";
1414

1515
export interface Init {
1616
userId: string;
@@ -95,7 +95,7 @@ const findLinksAndImage = (text: string): [string[], string | null] => {
9595
return;
9696
case "absolute": {
9797
const props = parseYoutube(node.href);
98-
if (!props) return;
98+
if (!props || props.pathType === "list") return;
9999
image ??= `https://i.ytimg.com/vi/${props.videoId}/mqdefault.jpg`;
100100
return;
101101
}

deps/testing.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export * from "https://deno.land/[email protected]/testing/asserts.ts";
2+
export * from "https://deno.land/[email protected]/testing/snapshot.ts";

mod.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export * from "./rest/mod.ts";
22
export * from "./browser/mod.ts";
33
export * from "./title.ts";
4+
export * from "./parseAbsoluteLink.ts";

parseAbsoluteLink.ts

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import type { LinkNode } from "./deps/scrapbox.ts";
2+
import { parseYoutube } from "./parser/youtube.ts";
3+
import { parseVimeo } from "./parser/vimeo.ts";
4+
import { parseSpotify } from "./parser/spotify.ts";
5+
import { parseAnchorFM } from "./parser/anchor-fm.ts";
6+
7+
export type { LinkNode };
8+
9+
export interface AbsoluteLinkNode {
10+
type: "absoluteLink";
11+
content: string;
12+
href: string;
13+
raw: string;
14+
}
15+
16+
/** Youtube埋め込み */
17+
export interface YoutubeNode {
18+
type: "youtube";
19+
videoId: string;
20+
pathType: "com" | "dotbe" | "short";
21+
params: URLSearchParams;
22+
href: string;
23+
raw: string;
24+
}
25+
26+
/** Youtube List埋め込み */
27+
export interface YoutubeListNode {
28+
type: "youtube";
29+
listId: string;
30+
pathType: "list";
31+
params: URLSearchParams;
32+
href: string;
33+
raw: string;
34+
}
35+
36+
/** Vimeo埋め込み */
37+
export interface VimeoNode {
38+
type: "vimeo";
39+
videoId: string;
40+
href: string;
41+
raw: string;
42+
}
43+
44+
/** Spotify埋め込み */
45+
export interface SpotifyNode {
46+
type: "spotify";
47+
videoId: string;
48+
pathType: "track" | "artist" | "playlist" | "album" | "episode" | "show";
49+
href: string;
50+
raw: string;
51+
}
52+
53+
/** Anchor FM埋め込み */
54+
export interface AnchorFMNode {
55+
type: "anchor-fm";
56+
videoId: string;
57+
href: string;
58+
raw: string;
59+
}
60+
61+
/** 動画埋め込み */
62+
export interface VideoNode {
63+
type: "video";
64+
href: VideoURL;
65+
raw: string;
66+
}
67+
68+
/** 音声埋め込み */
69+
export interface AudioNode {
70+
type: "audio";
71+
content: string;
72+
href: AudioURL;
73+
raw: string;
74+
}
75+
76+
/** scrapbox-parserで解析した外部リンク記法を、埋め込み形式ごとに細かく解析する
77+
*
78+
* @param link scrapbox-parserで解析した外部リンク記法のobject
79+
* @return 解析した記法のobject
80+
*/
81+
export const parseAbsoluteLink = (
82+
link: LinkNode & { pathType: "absolute" },
83+
):
84+
| AbsoluteLinkNode
85+
| VideoNode
86+
| AudioNode
87+
| YoutubeNode
88+
| YoutubeListNode
89+
| VimeoNode
90+
| SpotifyNode
91+
| AnchorFMNode => {
92+
const { type: _, pathType: __, content, href, ...baseLink } = link;
93+
if (content === "") {
94+
const youtube = parseYoutube(href);
95+
if (youtube) return { type: "youtube", href, ...youtube, ...baseLink };
96+
97+
const vimeoId = parseVimeo(href);
98+
if (vimeoId) return { type: "vimeo", videoId: vimeoId, href, ...baseLink };
99+
100+
const spotify = parseSpotify(href);
101+
if (spotify) return { type: "spotify", href, ...spotify, ...baseLink };
102+
103+
const anchorFMId = parseAnchorFM(href);
104+
if (anchorFMId) {
105+
return { type: "anchor-fm", videoId: anchorFMId, href, ...baseLink };
106+
}
107+
108+
if (isVideoURL(href)) return { type: "video", href, ...baseLink };
109+
}
110+
if (isAudioURL(href)) return { type: "audio", content, href, ...baseLink };
111+
112+
return { type: "absoluteLink", content, href, ...baseLink };
113+
};
114+
115+
type AudioURL = `${string}.${"mp3" | "ogg" | "wav" | "acc"}`;
116+
const isAudioURL = (url: string): url is AudioURL =>
117+
/\.(?:mp3|ogg|wav|aac)$/.test(url);
118+
119+
type VideoURL = `${string}.${"mp4" | "webm"}`;
120+
const isVideoURL = (url: string): url is VideoURL =>
121+
/\.(?:mp4|webm)$/.test(url);
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export const snapshot = {};
2+
3+
snapshot[`spotify links > is 1`] = `"1-FM-e1gh6a7/a-a7m2veg"`;
4+
5+
snapshot[`spotify links > is not 1`] = `undefined`;
6+
7+
snapshot[`spotify links > is not 2`] = `undefined`;
8+
9+
snapshot[`spotify links > is not 3`] = `undefined`;
10+
11+
snapshot[`spotify links > is not 4`] = `undefined`;
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
export const snapshot = {};
2+
3+
snapshot[`spotify links > is 1`] = `
4+
{
5+
pathType: "track",
6+
videoId: "0rlYL6IQIwLZwYIguyy3l0",
7+
}
8+
`;
9+
10+
snapshot[`spotify links > is 2`] = `
11+
{
12+
pathType: "album",
13+
videoId: "1bgUOjg3V0a7tvEfF1N6Kk",
14+
}
15+
`;
16+
17+
snapshot[`spotify links > is 3`] = `
18+
{
19+
pathType: "episode",
20+
videoId: "0JtPGoprZK2WlYMjhFF2xD",
21+
}
22+
`;
23+
24+
snapshot[`spotify links > is 4`] = `
25+
{
26+
pathType: "playlist",
27+
videoId: "2uOyQytSjDq9GF5z1RJj5w",
28+
}
29+
`;
30+
31+
snapshot[`spotify links > is not 1`] = `undefined`;
32+
33+
snapshot[`spotify links > is not 2`] = `undefined`;
34+
35+
snapshot[`spotify links > is not 3`] = `undefined`;
36+
37+
snapshot[`spotify links > is not 4`] = `undefined`;
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export const snapshot = {};
2+
3+
snapshot[`vimeo links > is 1`] = `"121284607"`;
4+
5+
snapshot[`vimeo links > is not 1`] = `undefined`;
6+
7+
snapshot[`vimeo links > is not 2`] = `undefined`;
8+
9+
snapshot[`vimeo links > is not 3`] = `undefined`;
10+
11+
snapshot[`vimeo links > is not 4`] = `undefined`;
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
export const snapshot = {};
2+
3+
snapshot[`youtube links > is 1`] = `
4+
{
5+
params: URLSearchParams {
6+
[Symbol("[[webidl.brand]]")]: Symbol("[[webidl.brand]]"),
7+
[Symbol(list)]: [
8+
[
9+
"v",
10+
"LSvaOcaUQ3Y",
11+
],
12+
],
13+
[Symbol("url object")]: URL {
14+
hash: "",
15+
host: "www.youtube.com",
16+
hostname: "www.youtube.com",
17+
href: "https://www.youtube.com/watch?v=LSvaOcaUQ3Y",
18+
origin: "https://www.youtube.com",
19+
password: "",
20+
pathname: "/watch",
21+
port: "",
22+
protocol: "https:",
23+
search: "?v=LSvaOcaUQ3Y",
24+
username: "",
25+
},
26+
},
27+
pathType: "com",
28+
videoId: "LSvaOcaUQ3Y",
29+
}
30+
`;
31+
32+
snapshot[`youtube links > is 2`] = `
33+
{
34+
listId: "PLmoRDY8IgE2Okxy4WWdP95RHXOTGzJfQs",
35+
params: URLSearchParams {
36+
[Symbol("[[webidl.brand]]")]: Symbol("[[webidl.brand]]"),
37+
[Symbol(list)]: [
38+
[
39+
"list",
40+
"PLmoRDY8IgE2Okxy4WWdP95RHXOTGzJfQs",
41+
],
42+
],
43+
[Symbol("url object")]: null,
44+
},
45+
pathType: "list",
46+
}
47+
`;
48+
49+
snapshot[`youtube links > is 3`] = `
50+
{
51+
params: URLSearchParams {
52+
[Symbol("[[webidl.brand]]")]: Symbol("[[webidl.brand]]"),
53+
[Symbol(list)]: [
54+
[
55+
"v",
56+
"57rdbK4vmKE",
57+
],
58+
[
59+
"list",
60+
"PLmoRDY8IgE2Okxy4WWdP95RHXOTGzJfQs",
61+
],
62+
],
63+
[Symbol("url object")]: URL {
64+
hash: "",
65+
host: "www.youtube.com",
66+
hostname: "www.youtube.com",
67+
href: "https://www.youtube.com/watch?v=57rdbK4vmKE&list=PLmoRDY8IgE2Okxy4WWdP95RHXOTGzJfQs",
68+
origin: "https://www.youtube.com",
69+
password: "",
70+
pathname: "/watch",
71+
port: "",
72+
protocol: "https:",
73+
search: "?v=57rdbK4vmKE&list=PLmoRDY8IgE2Okxy4WWdP95RHXOTGzJfQs",
74+
username: "",
75+
},
76+
},
77+
pathType: "com",
78+
videoId: "57rdbK4vmKE",
79+
}
80+
`;
81+
82+
snapshot[`youtube links > is 4`] = `
83+
{
84+
params: URLSearchParams {
85+
[Symbol("[[webidl.brand]]")]: Symbol("[[webidl.brand]]"),
86+
[Symbol(list)]: [
87+
[
88+
"v",
89+
"nj1cre2e6t0",
90+
],
91+
],
92+
[Symbol("url object")]: URL {
93+
hash: "",
94+
host: "music.youtube.com",
95+
hostname: "music.youtube.com",
96+
href: "https://music.youtube.com/watch?v=nj1cre2e6t0",
97+
origin: "https://music.youtube.com",
98+
password: "",
99+
pathname: "/watch",
100+
port: "",
101+
protocol: "https:",
102+
search: "?v=nj1cre2e6t0",
103+
username: "",
104+
},
105+
},
106+
pathType: "com",
107+
videoId: "nj1cre2e6t0",
108+
}
109+
`;
110+
111+
snapshot[`youtube links > is 5`] = `
112+
{
113+
params: URLSearchParams {
114+
[Symbol("[[webidl.brand]]")]: Symbol("[[webidl.brand]]"),
115+
[Symbol(list)]: [
116+
],
117+
[Symbol("url object")]: null,
118+
},
119+
pathType: "dotbe",
120+
videoId: "nj1cre2e6t0",
121+
}
122+
`;
123+
124+
snapshot[`youtube links > is not 1`] = `undefined`;
125+
126+
snapshot[`youtube links > is not 2`] = `undefined`;
127+
128+
snapshot[`youtube links > is not 3`] = `undefined`;
129+
130+
snapshot[`youtube links > is not 4`] = `undefined`;

0 commit comments

Comments
 (0)