@@ -35,6 +35,167 @@ const PostBody = ({ content, tags, loading }: Props) => {
3535 }
3636 }
3737 } ;
38+
39+ const renderOpenGraph = ( node : any , index ?: number , parent ?: Element ) => {
40+ if ( node . type === 'element' && node . tagName === 'p' && node . children ) {
41+ const aTag = node . children . find (
42+ ( node : any ) => node . type === 'element' && node . tagName === 'a'
43+ ) ;
44+ if ( ! aTag ) return ;
45+
46+ const href = aTag . properties ?. href ;
47+ if ( href && href . startsWith ( '/' ) ) {
48+ // 부모가 존재하고 children 배열이 있는 경우
49+ const opengraph = createOpenGraph ( href ) ;
50+ if (
51+ index !== undefined &&
52+ parent &&
53+ parent . children &&
54+ Array . isArray ( parent . children )
55+ ) {
56+ // 현재 a 태그 다음 위치에 div 삽입 s
57+ parent . children . splice ( index + 1 , 0 , opengraph ) ;
58+ } else return ;
59+ }
60+ }
61+ } ;
62+
63+ const renderYoutubeEmbed = ( node : any , index ?: number , parent ?: Element ) => {
64+ if ( node . type === 'element' && node . tagName === 'p' && node . children ) {
65+ const aTag = node . children . find (
66+ ( node : any ) => node . type === 'element' && node . tagName === 'a'
67+ ) ;
68+ if ( ! aTag ) return ;
69+
70+ const href = aTag . properties ?. href ;
71+ const isYoutubeLink =
72+ href &&
73+ ( href . startsWith ( 'https://www.youtube.com/watch' ) ||
74+ href . startsWith ( 'https://youtu.be/' ) ) ;
75+
76+ if ( isYoutubeLink ) {
77+ const urlType = href . startsWith ( 'https://www.youtube.com/watch' )
78+ ? 'watch'
79+ : 'be' ;
80+
81+ const videoId =
82+ urlType === 'watch'
83+ ? new URL ( href ) . searchParams . get ( 'v' )
84+ : href . split ( '/' ) . pop ( ) ;
85+
86+ if ( videoId ) {
87+ const youtubeEmbed = createYoutubeIframe ( videoId , 736 , 414 ) ;
88+ // 부모가 존재하고 children 배열이 있는 경우
89+ if (
90+ index &&
91+ parent &&
92+ parent . children &&
93+ Array . isArray ( parent . children )
94+ ) {
95+ parent . children . splice ( index + 1 , 0 , youtubeEmbed ) ;
96+ } else return ;
97+ }
98+ }
99+ }
100+ } ;
101+
102+ const createYoutubeIframe = (
103+ videoId : string ,
104+ width : number ,
105+ height : number
106+ ) => {
107+ return {
108+ type : 'element' ,
109+ tagName : 'iframe' ,
110+ properties : {
111+ src : `https://www.youtube.com/embed/${ videoId } ` ,
112+ width : width . toString ( ) ,
113+ height : height . toString ( ) ,
114+ frameBorder : '0' ,
115+ allowFullScreen : true ,
116+ className : 'youtube-embed' ,
117+ } ,
118+ children : [ ] ,
119+ } ;
120+ } ;
121+
122+ const createOpenGraph = ( href : string ) => {
123+ return {
124+ type : 'element' ,
125+ tagName : 'a' ,
126+ properties : {
127+ className : 'open-graph' ,
128+ href : href ,
129+ } ,
130+ children : [
131+ {
132+ type : 'element' ,
133+ tagName : 'img' ,
134+ properties : {
135+ src : `${ href } ` ,
136+ alt : 'Open Graph Image' ,
137+ className : 'og-image' ,
138+ } ,
139+ children : [ ] ,
140+ } ,
141+ {
142+ type : 'element' ,
143+ tagName : 'div' ,
144+ properties : {
145+ className : 'og-container' ,
146+ } ,
147+ children : [
148+ {
149+ type : 'element' ,
150+ tagName : 'h4' ,
151+ properties : {
152+ className : 'og-title' ,
153+ } ,
154+ children : [
155+ {
156+ type : 'text' ,
157+ value : decodeURIComponent ( href . split ( '/' ) . pop ( ) ! ) . replaceAll (
158+ '-' ,
159+ ' '
160+ ) ,
161+ } ,
162+ ] ,
163+ } ,
164+ {
165+ type : 'element' ,
166+ tagName : 'span' ,
167+ properties : {
168+ className : 'og-content' ,
169+ } ,
170+ children : [
171+ // {
172+ // type: 'text',
173+ // value: decodeURIComponent(href.split('/').pop()!).replaceAll(
174+ // '-',
175+ // ' '
176+ // ),
177+ // },
178+ ] ,
179+ } ,
180+ {
181+ type : 'element' ,
182+ tagName : 'span' ,
183+ properties : {
184+ className : 'og-domain' ,
185+ } ,
186+ children : [
187+ {
188+ type : 'text' ,
189+ value : '' ,
190+ } ,
191+ ] ,
192+ } ,
193+ ] ,
194+ } ,
195+ ] ,
196+ } ;
197+ } ;
198+
38199 return (
39200 < div
40201 className = {
@@ -58,8 +219,14 @@ const PostBody = ({ content, tags, loading }: Props) => {
58219 wrapperElement = { {
59220 'data-color-mode' : theme ,
60221 } }
61- rehypeRewrite = { ( node ) => {
222+ rehypeRewrite = { ( node , index ? , parent ? ) => {
62223 asideStyleRewrite ( node ) ;
224+ // renderOpenGraph(node, index || 0, parent as Element | undefined);
225+ renderYoutubeEmbed (
226+ node ,
227+ index || 0 ,
228+ parent as Element | undefined
229+ ) ;
63230 } }
64231 />
65232 </ >
0 commit comments