@@ -6,8 +6,16 @@ import {
66 Notice ,
77 Plugin
88} from "obsidian" ;
9- import { Admonition , ObsidianAdmonitionPlugin } from "../@types/types" ;
10- import { getAdmonitionElement } from "./util" ;
9+ import {
10+ Admonition ,
11+ INestedAdmonition ,
12+ ObsidianAdmonitionPlugin
13+ } from "../@types/types" ;
14+ import {
15+ getAdmonitionElement ,
16+ getMatches ,
17+ getParametersFromSource
18+ } from "./util" ;
1119
1220import * as CodeMirror from "./codemirror" ;
1321
@@ -100,6 +108,9 @@ export default class ObsidianAdmonition
100108 admonitions : { [ admonitionType : string ] : Admonition } = { } ;
101109 userAdmonitions : { [ admonitionType : string ] : Admonition } = { } ;
102110 syntaxHighlight : boolean ;
111+ get types ( ) {
112+ return Object . keys ( this . admonitions ) ;
113+ }
103114 async saveSettings ( ) {
104115 await this . saveData ( {
105116 syntaxHighlight : this . syntaxHighlight || false ,
@@ -260,63 +271,40 @@ export default class ObsidianAdmonition
260271 return ;
261272 }
262273 try {
263- /**
264- * Find title and collapse parameters.
265- */
266- let matchedParameters =
267- src . match ( / ^ \b ( t i t l e | c o l l a p s e ) \b : ( [ \s \S ] * ?) $ / gm) || [ ] ;
268-
269- let params = Object . fromEntries (
270- matchedParameters . map ( ( p ) => {
271- let [ , param , rest ] = p . match (
272- / ^ \b ( t i t l e | c o l l a p s e ) \b : ( [ \s \S ] * ?) $ /
273- ) ;
274- return [ param . trim ( ) , rest . trim ( ) ] ;
275- } )
276- ) ;
277-
278274 let {
279275 title = type [ 0 ] . toUpperCase ( ) + type . slice ( 1 ) . toLowerCase ( ) ,
280- collapse
281- } = params ;
276+ collapse,
277+ content
278+ } = getParametersFromSource ( type , src ) ;
279+
280+ let match = new RegExp ( `^!!! ad-(${ this . types . join ( "|" ) } )$` , "gm" ) ;
281+
282+ let nestedAdmonitions = content . match ( match ) || [ ] ;
283+
284+ if ( nestedAdmonitions . length ) {
285+ let matches = [ getMatches ( content , 0 , nestedAdmonitions [ 0 ] ) ] ;
286+ for ( let i = 1 ; i < nestedAdmonitions . length ; i ++ ) {
287+ matches . push (
288+ getMatches (
289+ content ,
290+ matches [ i - 1 ] . end ,
291+ nestedAdmonitions [ i ]
292+ )
293+ ) ;
294+ }
282295
283- /**
284- * Get the content. Content should be everything that is not the title or collapse parameters.
285- * Remove any "content: " fields (legacy from < v0.2.0)
286- */
287- let content = src
288- . replace ( / ^ \b ( t i t l e | c o l l a p s e ) \b : ( [ \s \S ] * ?) $ / gm, "" )
289- . replace ( / ^ \b c o n t e n t \b : \s ? / gm, "" ) ;
290- /**
291- * If the admonition should collapse, but something other than open or closed was provided, set to closed.
292- */
293- if (
294- Object . prototype . hasOwnProperty . call ( params , "collapse" ) &&
295- ( params . collapse . length == 0 ||
296- params . collapse === undefined ||
297- collapse !== "open" )
298- ) {
299- collapse = "closed" ;
300- }
301- /**
302- * If the admonition should collapse, but title was blanked, set the default title.
303- */
304- if (
305- Object . prototype . hasOwnProperty . call ( params , "title" ) &&
306- ( params . title === undefined || params . title . length === 0 ) &&
307- collapse
308- ) {
309- title = type [ 0 ] . toUpperCase ( ) + type . slice ( 1 ) . toLowerCase ( ) ;
310- new Notice (
311- "An admonition must have a title if it is collapsible."
312- ) ;
296+ let split = content . split ( "\n" ) ;
297+
298+ for ( let m of matches . reverse ( ) ) {
299+ split . splice (
300+ m . start ,
301+ m . end - m . start + 1 ,
302+ `\`\`\`ad-${ m . type } \n${ m . src } \n\`\`\``
303+ ) ;
304+ }
305+ content = split . join ( "\n" ) ;
313306 }
314307
315- /**
316- * Build the correct admonition element.
317- * Collapsible -> <details> <summary> Title </summary> <div> Content </div> </details>
318- * Regular -> <div> <div> Title </div> <div> Content </div> </div>
319- */
320308 let admonitionElement = getAdmonitionElement (
321309 type ,
322310 title ,
0 commit comments