11import type { Root , Parent } from "hast" ;
2+ import { h } from "hastscript" ;
23import { visit } from "unist-util-visit" ;
34import { getFirstAndLastText , addClass } from "./ast.js" ;
45// This is required to augment the AST type, but unfortunately can’t
@@ -8,6 +9,23 @@ import { getFirstAndLastText, addClass } from "./ast.js";
89const OPENING_QUOTE = / ^ (?: ‘ | “ | ’ | ” ) / ;
910const CLOSING_QUOTE = / (?: ‘ | “ | ’ | ” ) $ / ;
1011
12+ const YEAR_SPACE = Object . freeze ( { type : "text" , value : " " } ) ;
13+
14+ const QUOTE_SPACE = Object . freeze ( {
15+ type : "text" ,
16+ value : "\u202F" ,
17+ } ) ;
18+
19+ const OPENING_QUOTE_AST = Object . freeze ( {
20+ type : "text" ,
21+ value : "‘" ,
22+ } ) ;
23+
24+ const CLOSING_QUOTE_AST = Object . freeze ( {
25+ type : "text" ,
26+ value : "’" ,
27+ } ) ;
28+
1129export function textrasPlugin ( ) {
1230 return transformer ;
1331
@@ -44,9 +62,56 @@ export function textrasPlugin() {
4462 }
4563 }
4664
65+ function transformWorkTitle ( node : Parent ) {
66+ node . data = {
67+ ...node . data ,
68+ hName : "cite" ,
69+ hProperties : { class : "work-title" } ,
70+ } ;
71+
72+ const { year, quoted } = ( node as any ) . attributes || { } ;
73+
74+ if ( quoted !== undefined ) {
75+ const [ first , last ] = getFirstAndLastText ( node ) ;
76+
77+ if ( OPENING_QUOTE . test ( first ?? "" ) ) {
78+ node . children . unshift ( QUOTE_SPACE ) ;
79+ }
80+
81+ node . children . unshift ( OPENING_QUOTE_AST ) ;
82+
83+ if ( CLOSING_QUOTE . test ( last ?? "" ) ) {
84+ node . children . push ( QUOTE_SPACE ) ;
85+ }
86+
87+ node . children . push ( CLOSING_QUOTE_AST ) ;
88+ }
89+
90+ if ( year !== undefined ) {
91+ const time = h ( "time" ) ;
92+ time . data = {
93+ hName : "time" ,
94+ hProperties : {
95+ class : "work-vintage" ,
96+ datetime : year ,
97+ } ,
98+ } ;
99+
100+ time . children = [
101+ {
102+ type : "text" ,
103+ value : `(${ year } )` ,
104+ } ,
105+ ] ;
106+ node . children . push ( YEAR_SPACE ) ;
107+ node . children . push ( time ) ;
108+ }
109+ }
110+
47111 function transformer ( tree : Root , _file : unknown ) {
48112 visit ( tree , { type : "textDirective" , name : "ordinal" } , ordinalVisitor ) ;
49113 visit ( tree , { type : "textDirective" , name : "quote" } , quoteVisitor ) ;
114+ visit ( tree , { type : "textDirective" , name : "work" } , transformWorkTitle ) ;
50115
51116 for ( const [ name , element ] of Object . entries ( {
52117 var : "var" ,
0 commit comments