@portabletext/plugin-typography 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,190 @@
1
+ import {
2
+ defineTextTransformRule,
3
+ type InputRule,
4
+ } from '@portabletext/plugin-input-rule'
5
+
6
+ /**
7
+ * @public
8
+ */
9
+ export const emDashRule = defineTextTransformRule({
10
+ on: /--/,
11
+ transform: () => '—',
12
+ })
13
+
14
+ /**
15
+ * @public
16
+ */
17
+ export const ellipsisRule = defineTextTransformRule({
18
+ on: /\.\.\./,
19
+ transform: () => '…',
20
+ })
21
+
22
+ /**
23
+ * @public
24
+ */
25
+ export const openingDoubleQuoteRule = defineTextTransformRule({
26
+ on: /(?:^|(?<=[\s{[(<'"\u2018\u201C]))"/g,
27
+ transform: () => '“',
28
+ })
29
+
30
+ /**
31
+ * @public
32
+ */
33
+ export const closingDoubleQuoteRule = defineTextTransformRule({
34
+ on: /"/g,
35
+ transform: () => '”',
36
+ })
37
+
38
+ /**
39
+ * @public
40
+ */
41
+ export const openingSingleQuoteRule = defineTextTransformRule({
42
+ on: /(?:^|(?<=[\s{[(<'"\u2018\u201C]))'/g,
43
+ transform: () => '‘',
44
+ })
45
+
46
+ /**
47
+ * @public
48
+ */
49
+ export const closingSingleQuoteRule = defineTextTransformRule({
50
+ on: /'/g,
51
+ transform: () => '’',
52
+ })
53
+
54
+ /**
55
+ * @public
56
+ */
57
+ export const smartQuotesRules: Array<InputRule> = [
58
+ openingDoubleQuoteRule,
59
+ closingDoubleQuoteRule,
60
+ openingSingleQuoteRule,
61
+ closingSingleQuoteRule,
62
+ ]
63
+
64
+ /**
65
+ * @public
66
+ */
67
+ export const leftArrowRule = defineTextTransformRule({
68
+ on: /<-/,
69
+ transform: () => '←',
70
+ })
71
+
72
+ /**
73
+ * @public
74
+ */
75
+ export const rightArrowRule = defineTextTransformRule({
76
+ on: /->/,
77
+ transform: () => '→',
78
+ })
79
+
80
+ /**
81
+ * @public
82
+ */
83
+ export const copyrightRule = defineTextTransformRule({
84
+ on: /\(c\)/,
85
+ transform: () => '©',
86
+ })
87
+
88
+ /**
89
+ * @public
90
+ */
91
+ export const servicemarkRule = defineTextTransformRule({
92
+ on: /\(sm\)/,
93
+ transform: () => '℠',
94
+ })
95
+
96
+ /**
97
+ * @public
98
+ */
99
+ export const trademarkRule = defineTextTransformRule({
100
+ on: /\(tm\)/,
101
+ transform: () => '™',
102
+ })
103
+
104
+ /**
105
+ * @beta
106
+ */
107
+ export const registeredTrademarkRule = defineTextTransformRule({
108
+ on: /\(r\)/,
109
+ transform: () => '®',
110
+ })
111
+
112
+ /**
113
+ * @public
114
+ */
115
+ export const oneHalfRule = defineTextTransformRule({
116
+ on: /(?:^|\s)(1\/2)\s/,
117
+ transform: () => '½',
118
+ })
119
+
120
+ /**
121
+ * @public
122
+ */
123
+ export const plusMinusRule = defineTextTransformRule({
124
+ on: /\+\/-/,
125
+ transform: () => '±',
126
+ })
127
+
128
+ /**
129
+ * @public
130
+ */
131
+ export const notEqualRule = defineTextTransformRule({
132
+ on: /!=/,
133
+ transform: () => '≠',
134
+ })
135
+
136
+ /**
137
+ * @public
138
+ */
139
+ export const laquoRule = defineTextTransformRule({
140
+ on: /<</,
141
+ transform: () => '«',
142
+ })
143
+
144
+ /**
145
+ * @public
146
+ */
147
+ export const raquoRule = defineTextTransformRule({
148
+ on: />>/,
149
+ transform: () => '»',
150
+ })
151
+
152
+ /**
153
+ * @public
154
+ */
155
+ export const multiplicationRule = defineTextTransformRule({
156
+ on: /\d+\s?([*x])\s?\d+/,
157
+ transform: () => '×',
158
+ })
159
+
160
+ /**
161
+ * @public
162
+ */
163
+ export const superscriptTwoRule = defineTextTransformRule({
164
+ on: /\^2/,
165
+ transform: () => '²',
166
+ })
167
+
168
+ /**
169
+ * @public
170
+ */
171
+ export const superscriptThreeRule = defineTextTransformRule({
172
+ on: /\^3/,
173
+ transform: () => '³',
174
+ })
175
+
176
+ /**
177
+ * @public
178
+ */
179
+ export const oneQuarterRule = defineTextTransformRule({
180
+ on: /(?:^|\s)(1\/4)\s/,
181
+ transform: () => '¼',
182
+ })
183
+
184
+ /**
185
+ * @public
186
+ */
187
+ export const threeQuartersRule = defineTextTransformRule({
188
+ on: /(?:^|\s)(3\/4)\s/,
189
+ transform: () => '¾',
190
+ })
@@ -0,0 +1,182 @@
1
+ import {
2
+ InputRulePlugin,
3
+ type InputRule,
4
+ type InputRuleGuard,
5
+ } from '@portabletext/plugin-input-rule'
6
+ import {useMemo} from 'react'
7
+ import {
8
+ closingDoubleQuoteRule,
9
+ closingSingleQuoteRule,
10
+ copyrightRule,
11
+ ellipsisRule,
12
+ emDashRule,
13
+ laquoRule,
14
+ leftArrowRule,
15
+ multiplicationRule,
16
+ notEqualRule,
17
+ oneHalfRule,
18
+ oneQuarterRule,
19
+ openingDoubleQuoteRule,
20
+ openingSingleQuoteRule,
21
+ plusMinusRule,
22
+ raquoRule,
23
+ registeredTrademarkRule,
24
+ rightArrowRule,
25
+ servicemarkRule,
26
+ superscriptThreeRule,
27
+ superscriptTwoRule,
28
+ threeQuartersRule,
29
+ trademarkRule,
30
+ } from './input-rules.typography'
31
+
32
+ /**
33
+ * @public
34
+ */
35
+ export type TypographyPluginProps = {
36
+ guard?: InputRuleGuard
37
+ /**
38
+ * Configure which rules to enable or disable. Ordinary rules like `emDash` and `ellipsis` are enabled by default.
39
+ * Less common rules like `multiplication` are disabled by default.
40
+ */
41
+ rules?: {
42
+ /**
43
+ * @defaultValue 'on'
44
+ */
45
+ emDash?: 'on' | 'off'
46
+ /**
47
+ * @defaultValue 'on'
48
+ */
49
+ ellipsis?: 'on' | 'off'
50
+ /**
51
+ * @defaultValue 'on'
52
+ */
53
+ openingDoubleQuote?: 'on' | 'off'
54
+ /**
55
+ * @defaultValue 'on'
56
+ */
57
+ closingDoubleQuote?: 'on' | 'off'
58
+ /**
59
+ * @defaultValue 'on'
60
+ */
61
+ openingSingleQuote?: 'on' | 'off'
62
+ /**
63
+ * @defaultValue 'on'
64
+ */
65
+ closingSingleQuote?: 'on' | 'off'
66
+ /**
67
+ * @defaultValue 'on'
68
+ */
69
+ leftArrow?: 'on' | 'off'
70
+ /**
71
+ * @defaultValue 'on'
72
+ */
73
+ rightArrow?: 'on' | 'off'
74
+ /**
75
+ * @defaultValue 'on'
76
+ */
77
+ copyright?: 'on' | 'off'
78
+ /**
79
+ * @defaultValue 'on'
80
+ */
81
+ trademark?: 'on' | 'off'
82
+ /**
83
+ * @defaultValue 'on'
84
+ */
85
+ servicemark?: 'on' | 'off'
86
+ /**
87
+ * @defaultValue 'on'
88
+ */
89
+ registeredTrademark?: 'on' | 'off'
90
+ /**
91
+ * @defaultValue 'off'
92
+ */
93
+ oneHalf?: 'on' | 'off'
94
+ /**
95
+ * @defaultValue 'off'
96
+ */
97
+ plusMinus?: 'on' | 'off'
98
+ /**
99
+ * @defaultValue 'off'
100
+ */
101
+ notEqual?: 'on' | 'off'
102
+ /**
103
+ * @defaultValue 'off'
104
+ */
105
+ laquo?: 'on' | 'off'
106
+ /**
107
+ * @defaultValue 'off'
108
+ */
109
+ raquo?: 'on' | 'off'
110
+ /**
111
+ * @defaultValue 'off'
112
+ */
113
+ multiplication?: 'on' | 'off'
114
+ /**
115
+ * @defaultValue 'off'
116
+ */
117
+ superscriptTwo?: 'on' | 'off'
118
+ /**
119
+ * @defaultValue 'off'
120
+ */
121
+ superscriptThree?: 'on' | 'off'
122
+ /**
123
+ * @defaultValue 'off'
124
+ */
125
+ oneQuarter?: 'on' | 'off'
126
+ /**
127
+ * @defaultValue 'off'
128
+ */
129
+ threeQuarters?: 'on' | 'off'
130
+ }
131
+ }
132
+
133
+ type RuleName = keyof NonNullable<TypographyPluginProps['rules']>
134
+
135
+ const defaultRuleConfig: Array<{
136
+ name: RuleName
137
+ rule: InputRule
138
+ state: 'on' | 'off'
139
+ }> = [
140
+ {name: 'emDash', rule: emDashRule, state: 'on'},
141
+ {name: 'ellipsis', rule: ellipsisRule, state: 'on'},
142
+ {name: 'openingDoubleQuote', rule: openingDoubleQuoteRule, state: 'on'},
143
+ {name: 'closingDoubleQuote', rule: closingDoubleQuoteRule, state: 'on'},
144
+ {name: 'openingSingleQuote', rule: openingSingleQuoteRule, state: 'on'},
145
+ {name: 'closingSingleQuote', rule: closingSingleQuoteRule, state: 'on'},
146
+ {name: 'leftArrow', rule: leftArrowRule, state: 'on'},
147
+ {name: 'rightArrow', rule: rightArrowRule, state: 'on'},
148
+ {name: 'copyright', rule: copyrightRule, state: 'on'},
149
+ {name: 'trademark', rule: trademarkRule, state: 'on'},
150
+ {name: 'servicemark', rule: servicemarkRule, state: 'on'},
151
+ {name: 'registeredTrademark', rule: registeredTrademarkRule, state: 'on'},
152
+ {name: 'oneHalf', rule: oneHalfRule, state: 'off'},
153
+ {name: 'plusMinus', rule: plusMinusRule, state: 'off'},
154
+ {name: 'laquo', rule: laquoRule, state: 'off'},
155
+ {name: 'notEqual', rule: notEqualRule, state: 'off'},
156
+ {name: 'raquo', rule: raquoRule, state: 'off'},
157
+ {name: 'multiplication', rule: multiplicationRule, state: 'off'},
158
+ {name: 'superscriptTwo', rule: superscriptTwoRule, state: 'off'},
159
+ {name: 'superscriptThree', rule: superscriptThreeRule, state: 'off'},
160
+ {name: 'oneQuarter', rule: oneQuarterRule, state: 'off'},
161
+ {name: 'threeQuarters', rule: threeQuartersRule, state: 'off'},
162
+ ]
163
+
164
+ /**
165
+ * @public
166
+ */
167
+ export function TypographyPlugin(props: TypographyPluginProps) {
168
+ const configuredInputRules = useMemo(
169
+ () =>
170
+ defaultRuleConfig.flatMap((rule) =>
171
+ props.rules && props.rules[rule.name] === 'on'
172
+ ? {...rule.rule, guard: props.guard ?? (() => true)}
173
+ : (props.rules && props.rules[rule.name] === 'off') ||
174
+ rule.state === 'off'
175
+ ? []
176
+ : {...rule.rule, guard: props.guard ?? (() => true)},
177
+ ),
178
+ [props.guard, props.rules],
179
+ )
180
+
181
+ return <InputRulePlugin {...props} rules={configuredInputRules} />
182
+ }