1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
/*
* @copyright Copyright (c) 2022 Vinicius Reis <vinicius@nextcloud.com>
*
* @author Vinicius Reis <vinicius@nextcloud.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
import { Node, isNodeActive, mergeAttributes } from '@tiptap/core'
import { VueNodeViewRenderer } from '@tiptap/vue-2'
import { typesAvailable } from './../markdownit/callouts.js'
import Callout from './Callout.vue'
export default Node.create({
name: 'callout',
content: 'paragraph+',
group: 'block',
defining: true,
addOptions() {
return {
types: typesAvailable,
HTMLAttributes: {
class: 'callout',
},
}
},
addAttributes() {
return {
type: {
default: 'info',
rendered: false,
parseHTML: element => {
return element.getAttribute('data-callout')
|| typesAvailable.find((type) => element.classList.contains(type))
|| (element.classList.contains('warning') && 'warn')
},
renderHTML: attributes => {
return {
'data-callout': attributes.type,
class: `callout-${attributes.type}`,
}
},
},
}
},
parseHTML() {
return [
{
tag: 'div.callout',
},
{
tag: 'p.callout',
priority: 1001,
},
]
},
renderHTML({ node, HTMLAttributes }) {
const { class: classy } = this.options.HTMLAttributes
const attributes = {
...this.options.HTMLAttributes,
'data-callout': node.attrs.type,
class: `${classy} ${classy}-${node.attrs.type}`,
}
return ['div', mergeAttributes(attributes, HTMLAttributes), 0]
},
toMarkdown: (state, node) => {
state.write('::: ' + (node.attrs.type || 'info') + '\n')
state.renderContent(node)
state.ensureNewLine()
state.write(':::')
state.closeBlock(node)
},
addNodeView() {
return VueNodeViewRenderer(Callout)
},
addCommands() {
return {
setCallout: attributes => ({ commands }) => {
return commands.wrapIn(this.name, attributes)
},
toggleCallout: attributes => ({ commands, state }) => {
if (!isNodeActive(state, this.name)) {
return commands.setCallout(attributes)
}
if (!isNodeActive(state, this.name, attributes)) {
return commands.updateAttributes(this.name, attributes)
}
return commands.unsetCallout()
},
unsetCallout: () => ({ commands }) => {
return commands.lift(this.name)
},
}
},
})
|