1- /*
2- * Copyright © 2024 by Luogu
3- */
4-
5- import remarkGfm from 'remark-gfm' ;
6- import remarkParse from 'remark-parse' ;
7- import remarkMath from './remarkMath.js' ;
8- import remarkRehype from 'remark-rehype' ;
9- import { PluggableList , unified } from 'unified' ;
10- import rehypeKatex from 'rehype-katex' ;
11- import rehypeReact from 'rehype-react' ;
12- import { visit } from 'unist-util-visit' ;
13- import parsePath from 'parse-path' ;
141import * as props from 'react/jsx-runtime' ;
2+ import rehypeReact from 'rehype-react' ;
3+ import rehypeHighlight from 'rehype-highlight' ;
4+ import { visit , SKIP } from 'unist-util-visit' ;
5+ import luoguMarkdownProcessor from 'lg-markdown-processor' ;
156
167const rehypeReactConfig : import ( 'hast-util-to-jsx-runtime' ) . Options = {
178 Fragment : 'article' ,
@@ -21,83 +12,42 @@ const rehypeReactConfig: import('hast-util-to-jsx-runtime').Options = {
2112 jsxs : props . jsxs
2213} ;
2314
24- export default function getProcessor ( {
25- remarkPlugins,
26- rehypePlugins
27- } : { remarkPlugins ?: PluggableList ; rehypePlugins ?: PluggableList } = { } ) {
28- return unified ( )
29- . use ( remarkParse )
30- . use ( remarkGfm )
31- . use ( remarkMath )
32- . use ( remarkPlugins || [ ] )
33- . use ( remarkRehype )
34- . use ( rehypeKatex )
35- . use ( hastBilibili )
36- . use ( rehypePlugins || [ ] )
15+ export default function getProcessor ( ) {
16+ return luoguMarkdownProcessor ( {
17+ rehypePlugins : [ hastHeilightSpace , rehypeHighlight ]
18+ } )
3719 . use ( rehypeReact , rehypeReactConfig )
3820 . freeze ( ) ;
3921}
40-
41- function hastBilibili ( ) {
22+ function hastHeilightSpace ( ) {
23+ const heilightSpaceElement : import ( 'hast' ) . Element = {
24+ type : 'element' ,
25+ tagName : 'span' ,
26+ properties : { className : [ 'articleViewer-heilightSpace' ] } ,
27+ children : [ { type : 'text' , value : ' ' } ]
28+ } ;
4229 return ( tree : import ( 'hast' ) . Root ) =>
43- visit ( tree , 'element' , function ( element ) {
44- if ( element . tagName !== 'img' || ! element . properties ) return ;
45- const src = element . properties . src ;
46- if ( typeof src !== 'string' ) return ;
47- if ( ! src . startsWith ( 'bilibili:' ) ) return ;
48- const parsedUrl = parsePath ( src ) ;
49- if ( ( parsedUrl . protocol as string ) !== 'bilibili' ) return ;
50- const query = parsedUrl . query ;
51- const r : {
52- aid ?: string ;
53- bvid ?: string ;
54- page ?: string ;
55- danmaku : string ;
56- autoplay : string ;
57- playlist : string ;
58- high_quality : string ;
59- } = {
60- danmaku : '0' ,
61- autoplay : '0' ,
62- playlist : '0' ,
63- high_quality : '1'
64- } ;
65- const pathname = parsedUrl . pathname ;
66- const match = pathname . match ( / ^ ( a v ) ? ( \d + ) $ / ) ;
67- if ( match ) r . aid = match [ 2 ] ;
68- else if ( pathname . toLowerCase ( ) . startsWith ( 'bv' ) ) r . bvid = pathname ;
69- else r . bvid = 'bv' + pathname ;
70-
71- const page = Number ( query . t || '' ) ;
72- if ( page ) r . page = String ( page ) ;
73-
74- element . tagName = 'div' ;
75- element . properties . style = 'position: relative; padding-bottom: 62.5%' ;
76-
77- element . children = [
78- {
79- type : 'element' ,
80- tagName : 'iframe' ,
81- properties : {
82- src :
83- 'https://www.bilibili.com/blackboard/webplayer/embed-old.html?' +
84- Object . entries ( r )
85- . filter ( ( [ _ , value ] ) => value !== undefined )
86- . map (
87- ( [ key , value ] ) =>
88- `${ encodeURIComponent ( String ( key ) ) } =${ encodeURIComponent ( String ( value ) ) } `
89- )
90- . join ( '&' ) ,
91- scrolling : 'no' ,
92- border : 0 ,
93- frameborder : 'no' ,
94- framespacing : 0 ,
95- allowfullscreen : true ,
96- style :
97- 'position: absolute; top: 0; left: 0; width: 100%; height: 100%;'
98- } ,
99- children : [ ]
30+ visit ( tree , 'element' , element => {
31+ if ( element === heilightSpaceElement ) return SKIP ;
32+ if ( element . tagName === 'code' ) return SKIP ;
33+ let className = element . properties [ 'className' ] ;
34+ if ( typeof className === 'string' ) className = [ className ] ;
35+ if (
36+ Array . isArray ( className ) &&
37+ ( className . includes ( 'katex' ) || className . includes ( 'katex-display' ) )
38+ )
39+ return SKIP ;
40+ const newChildren = new Array < import ( 'hast' ) . ElementContent > ( ) ;
41+ for ( let i of element . children ) {
42+ if ( i . type !== 'text' ) {
43+ newChildren . push ( i ) ;
44+ continue ;
10045 }
101- ] ;
46+ i . value . split ( ' ' ) . forEach ( ( s , i ) => {
47+ if ( i ) newChildren . push ( heilightSpaceElement ) ;
48+ newChildren . push ( { type : 'text' , value : s } ) ;
49+ } ) ;
50+ }
51+ element . children = newChildren ;
10252 } ) ;
10353}
0 commit comments