mdast-util-growi-plugin.test.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914
  1. import { fromMarkdown } from 'mdast-util-from-markdown';
  2. import { toMarkdown } from 'mdast-util-to-markdown';
  3. import test from 'tape';
  4. import { removePosition } from 'unist-util-remove-position';
  5. import { directiveFromMarkdown, directiveToMarkdown } from '../src/mdast-util-growi-plugin/index.js';
  6. import { directive } from '../src/micromark-extension-growi-plugin/index.js';
  7. test('markdown -> mdast', (t) => {
  8. t.deepEqual(
  9. fromMarkdown('a :b[c]{d} e.', {
  10. extensions: [directive()],
  11. mdastExtensions: [directiveFromMarkdown],
  12. }).children[0],
  13. {
  14. type: 'paragraph',
  15. children: [
  16. {
  17. type: 'text',
  18. value: 'a ',
  19. position: {
  20. start: { line: 1, column: 1, offset: 0 },
  21. end: { line: 1, column: 3, offset: 2 },
  22. },
  23. },
  24. {
  25. type: 'textGrowiPluginDirective',
  26. name: 'b',
  27. attributes: { d: '' },
  28. children: [
  29. {
  30. type: 'text',
  31. value: 'c',
  32. position: {
  33. start: { line: 1, column: 6, offset: 5 },
  34. end: { line: 1, column: 7, offset: 6 },
  35. },
  36. },
  37. ],
  38. position: {
  39. start: { line: 1, column: 3, offset: 2 },
  40. end: { line: 1, column: 11, offset: 10 },
  41. },
  42. },
  43. {
  44. type: 'text',
  45. value: ' e.',
  46. position: {
  47. start: { line: 1, column: 11, offset: 10 },
  48. end: { line: 1, column: 14, offset: 13 },
  49. },
  50. },
  51. ],
  52. position: {
  53. start: { line: 1, column: 1, offset: 0 },
  54. end: { line: 1, column: 14, offset: 13 },
  55. },
  56. },
  57. 'should support directives (text)',
  58. );
  59. t.deepEqual(
  60. fromMarkdown('::a[b]{c}', {
  61. extensions: [directive()],
  62. mdastExtensions: [directiveFromMarkdown],
  63. }).children[0],
  64. {
  65. type: 'leafGrowiPluginDirective',
  66. name: 'a',
  67. attributes: { c: '' },
  68. children: [
  69. {
  70. type: 'text',
  71. value: 'b',
  72. position: {
  73. start: { line: 1, column: 5, offset: 4 },
  74. end: { line: 1, column: 6, offset: 5 },
  75. },
  76. },
  77. ],
  78. position: {
  79. start: { line: 1, column: 1, offset: 0 },
  80. end: { line: 1, column: 10, offset: 9 },
  81. },
  82. },
  83. 'should support directives (leaf)',
  84. );
  85. t.deepEqual(
  86. fromMarkdown(':::a[b]{c}\nd', {
  87. extensions: [directive()],
  88. mdastExtensions: [directiveFromMarkdown],
  89. }).children[0],
  90. {
  91. type: 'containerGrowiPluginDirective',
  92. name: 'a',
  93. attributes: { c: '' },
  94. children: [
  95. {
  96. type: 'paragraph',
  97. data: { directiveLabel: true },
  98. children: [
  99. {
  100. type: 'text',
  101. value: 'b',
  102. position: {
  103. start: { line: 1, column: 6, offset: 5 },
  104. end: { line: 1, column: 7, offset: 6 },
  105. },
  106. },
  107. ],
  108. position: {
  109. start: { line: 1, column: 5, offset: 4 },
  110. end: { line: 1, column: 8, offset: 7 },
  111. },
  112. },
  113. {
  114. type: 'paragraph',
  115. children: [
  116. {
  117. type: 'text',
  118. value: 'd',
  119. position: {
  120. start: { line: 2, column: 1, offset: 11 },
  121. end: { line: 2, column: 2, offset: 12 },
  122. },
  123. },
  124. ],
  125. position: {
  126. start: { line: 2, column: 1, offset: 11 },
  127. end: { line: 2, column: 2, offset: 12 },
  128. },
  129. },
  130. ],
  131. position: {
  132. start: { line: 1, column: 1, offset: 0 },
  133. end: { line: 2, column: 2, offset: 12 },
  134. },
  135. },
  136. 'should support directives (container)',
  137. );
  138. t.deepEqual(
  139. removePosition(
  140. fromMarkdown(':a[b *c*\nd]', {
  141. extensions: [directive()],
  142. mdastExtensions: [directiveFromMarkdown],
  143. }),
  144. true,
  145. ),
  146. {
  147. type: 'root',
  148. children: [
  149. {
  150. type: 'paragraph',
  151. children: [
  152. {
  153. type: 'textGrowiPluginDirective',
  154. name: 'a',
  155. attributes: {},
  156. children: [
  157. { type: 'text', value: 'b ' },
  158. { type: 'emphasis', children: [{ type: 'text', value: 'c' }] },
  159. { type: 'text', value: '\nd' },
  160. ],
  161. },
  162. ],
  163. },
  164. ],
  165. },
  166. 'should support content in a label',
  167. );
  168. t.deepEqual(
  169. removePosition(
  170. fromMarkdown(':a{#b.c.d e=f g="h&i&unknown;j"}', {
  171. extensions: [directive()],
  172. mdastExtensions: [directiveFromMarkdown],
  173. }),
  174. true,
  175. ),
  176. {
  177. type: 'root',
  178. children: [
  179. {
  180. type: 'paragraph',
  181. children: [
  182. {
  183. type: 'textGrowiPluginDirective',
  184. name: 'a',
  185. attributes: {
  186. id: 'b', class: 'c d', e: 'f', g: 'h&i&unknown;j',
  187. },
  188. children: [],
  189. },
  190. ],
  191. },
  192. ],
  193. },
  194. 'should support attributes',
  195. );
  196. t.deepEqual(
  197. removePosition(
  198. fromMarkdown(':a{b\nc="d\ne"}', {
  199. extensions: [directive()],
  200. mdastExtensions: [directiveFromMarkdown],
  201. }),
  202. true,
  203. ),
  204. {
  205. type: 'root',
  206. children: [
  207. {
  208. type: 'paragraph',
  209. children: [
  210. {
  211. type: 'textGrowiPluginDirective',
  212. name: 'a',
  213. attributes: { b: '', c: 'd\ne' },
  214. children: [],
  215. },
  216. ],
  217. },
  218. ],
  219. },
  220. 'should support EOLs in attributes',
  221. );
  222. t.deepEqual(
  223. removePosition(
  224. fromMarkdown('::::a\n:::b\n:c\n:::\n::::', {
  225. extensions: [directive()],
  226. mdastExtensions: [directiveFromMarkdown],
  227. }),
  228. true,
  229. ),
  230. {
  231. type: 'root',
  232. children: [
  233. {
  234. type: 'containerGrowiPluginDirective',
  235. name: 'a',
  236. attributes: {},
  237. children: [
  238. {
  239. type: 'containerGrowiPluginDirective',
  240. name: 'b',
  241. attributes: {},
  242. children: [
  243. {
  244. type: 'paragraph',
  245. children: [
  246. {
  247. type: 'textGrowiPluginDirective',
  248. name: 'c',
  249. attributes: {},
  250. children: [],
  251. },
  252. ],
  253. },
  254. ],
  255. },
  256. ],
  257. },
  258. ],
  259. },
  260. 'should support directives in directives',
  261. );
  262. t.end();
  263. });
  264. test('mdast -> markdown', (t) => {
  265. t.deepEqual(
  266. toMarkdown(
  267. {
  268. type: 'paragraph',
  269. children: [
  270. { type: 'text', value: 'a ' },
  271. // @ts-expect-error: `children`, `name` missing.
  272. { type: 'textGrowiPluginDirective' },
  273. { type: 'text', value: ' b.' },
  274. ],
  275. },
  276. { extensions: [directiveToMarkdown] },
  277. ),
  278. 'a : b.\n',
  279. 'should try to serialize a directive (text) w/o `name`',
  280. );
  281. t.deepEqual(
  282. toMarkdown(
  283. {
  284. type: 'paragraph',
  285. children: [
  286. { type: 'text', value: 'a ' },
  287. // @ts-expect-error: `children` missing.
  288. { type: 'textGrowiPluginDirective', name: 'b' },
  289. { type: 'text', value: ' c.' },
  290. ],
  291. },
  292. { extensions: [directiveToMarkdown] },
  293. ),
  294. 'a :b c.\n',
  295. 'should serialize a directive (text) w/ `name`',
  296. );
  297. t.deepEqual(
  298. toMarkdown(
  299. {
  300. type: 'paragraph',
  301. children: [
  302. { type: 'text', value: 'a ' },
  303. {
  304. type: 'textGrowiPluginDirective',
  305. name: 'b',
  306. children: [{ type: 'text', value: 'c' }],
  307. },
  308. { type: 'text', value: ' d.' },
  309. ],
  310. },
  311. { extensions: [directiveToMarkdown] },
  312. ),
  313. 'a :b[c] d.\n',
  314. 'should serialize a directive (text) w/ `children`',
  315. );
  316. t.deepEqual(
  317. toMarkdown(
  318. {
  319. type: 'paragraph',
  320. children: [
  321. { type: 'text', value: 'a ' },
  322. {
  323. type: 'textGrowiPluginDirective',
  324. name: 'b',
  325. children: [{ type: 'text', value: 'c[d]e' }],
  326. },
  327. { type: 'text', value: ' f.' },
  328. ],
  329. },
  330. { extensions: [directiveToMarkdown] },
  331. ),
  332. 'a :b[c\\[d\\]e] f.\n',
  333. 'should escape brackets in a directive (text) label',
  334. );
  335. t.deepEqual(
  336. toMarkdown(
  337. {
  338. type: 'paragraph',
  339. children: [
  340. { type: 'text', value: 'a ' },
  341. {
  342. type: 'textGrowiPluginDirective',
  343. name: 'b',
  344. children: [{ type: 'text', value: 'c\nd' }],
  345. },
  346. { type: 'text', value: ' e.' },
  347. ],
  348. },
  349. { extensions: [directiveToMarkdown] },
  350. ),
  351. 'a :b[c\nd] e.\n',
  352. 'should support EOLs in a directive (text) label',
  353. );
  354. t.deepEqual(
  355. toMarkdown(
  356. {
  357. type: 'paragraph',
  358. children: [
  359. { type: 'text', value: 'a ' },
  360. {
  361. type: 'textGrowiPluginDirective',
  362. name: 'b',
  363. // @ts-expect-error: should contain only `string`s
  364. attributes: {
  365. c: 'd', e: 'f', g: '', h: null, i: undefined, j: 2,
  366. },
  367. children: [],
  368. },
  369. { type: 'text', value: ' k.' },
  370. ],
  371. },
  372. { extensions: [directiveToMarkdown] },
  373. ),
  374. 'a :b{c="d" e="f" g j="2"} k.\n',
  375. 'should serialize a directive (text) w/ `attributes`',
  376. );
  377. t.deepEqual(
  378. toMarkdown(
  379. {
  380. type: 'paragraph',
  381. children: [
  382. { type: 'text', value: 'a ' },
  383. {
  384. type: 'textGrowiPluginDirective',
  385. name: 'b',
  386. attributes: { class: 'a b\nc', id: 'd', key: 'value' },
  387. children: [],
  388. },
  389. { type: 'text', value: ' k.' },
  390. ],
  391. },
  392. { extensions: [directiveToMarkdown] },
  393. ),
  394. 'a :b{#d .a.b.c key="value"} k.\n',
  395. 'should serialize a directive (text) w/ `id`, `class` attributes',
  396. );
  397. t.deepEqual(
  398. toMarkdown(
  399. {
  400. type: 'paragraph',
  401. children: [
  402. { type: 'text', value: 'a ' },
  403. {
  404. type: 'textGrowiPluginDirective',
  405. name: 'b',
  406. attributes: { x: 'y"\'\r\nz' },
  407. children: [],
  408. },
  409. { type: 'text', value: ' k.' },
  410. ],
  411. },
  412. { extensions: [directiveToMarkdown] },
  413. ),
  414. 'a :b{x="y"\'\r\nz"} k.\n',
  415. 'should encode the quote in an attribute value (text)',
  416. );
  417. t.deepEqual(
  418. toMarkdown(
  419. {
  420. type: 'paragraph',
  421. children: [
  422. { type: 'text', value: 'a ' },
  423. {
  424. type: 'textGrowiPluginDirective',
  425. name: 'b',
  426. attributes: { x: 'y"\'\r\nz' },
  427. children: [],
  428. },
  429. { type: 'text', value: ' k.' },
  430. ],
  431. },
  432. { extensions: [directiveToMarkdown] },
  433. ),
  434. 'a :b{x="y"\'\r\nz"} k.\n',
  435. 'should encode the quote in an attribute value (text)',
  436. );
  437. t.deepEqual(
  438. toMarkdown(
  439. {
  440. type: 'paragraph',
  441. children: [
  442. { type: 'text', value: 'a ' },
  443. {
  444. type: 'textGrowiPluginDirective',
  445. name: 'b',
  446. attributes: { id: 'c#d' },
  447. children: [],
  448. },
  449. { type: 'text', value: ' e.' },
  450. ],
  451. },
  452. { extensions: [directiveToMarkdown] },
  453. ),
  454. 'a :b{id="c#d"} e.\n',
  455. 'should not use the `id` shortcut if impossible characters exist',
  456. );
  457. t.deepEqual(
  458. toMarkdown(
  459. {
  460. type: 'paragraph',
  461. children: [
  462. { type: 'text', value: 'a ' },
  463. {
  464. type: 'textGrowiPluginDirective',
  465. name: 'b',
  466. attributes: { class: 'c.d e<f' },
  467. children: [],
  468. },
  469. { type: 'text', value: ' g.' },
  470. ],
  471. },
  472. { extensions: [directiveToMarkdown] },
  473. ),
  474. 'a :b{class="c.d e<f"} g.\n',
  475. 'should not use the `class` shortcut if impossible characters exist',
  476. );
  477. t.deepEqual(
  478. toMarkdown(
  479. {
  480. type: 'paragraph',
  481. children: [
  482. { type: 'text', value: 'a ' },
  483. {
  484. type: 'textGrowiPluginDirective',
  485. name: 'b',
  486. attributes: { class: 'c.d e f<g hij' },
  487. children: [],
  488. },
  489. { type: 'text', value: ' k.' },
  490. ],
  491. },
  492. { extensions: [directiveToMarkdown] },
  493. ),
  494. 'a :b{.e.hij class="c.d f<g"} k.\n',
  495. 'should not use the `class` shortcut if impossible characters exist (but should use it for classes that don’t)',
  496. );
  497. t.deepEqual(
  498. // @ts-expect-error: `children`, `name` missing.
  499. toMarkdown({ type: 'leafGrowiPluginDirective' }, { extensions: [directiveToMarkdown] }),
  500. '::\n',
  501. 'should try to serialize a directive (leaf) w/o `name`',
  502. );
  503. t.deepEqual(
  504. toMarkdown(
  505. // @ts-expect-error: `children` missing.
  506. { type: 'leafGrowiPluginDirective', name: 'a' },
  507. { extensions: [directiveToMarkdown] },
  508. ),
  509. '::a\n',
  510. 'should serialize a directive (leaf) w/ `name`',
  511. );
  512. t.deepEqual(
  513. toMarkdown(
  514. {
  515. type: 'leafGrowiPluginDirective',
  516. name: 'a',
  517. children: [{ type: 'text', value: 'b' }],
  518. },
  519. { extensions: [directiveToMarkdown] },
  520. ),
  521. '::a[b]\n',
  522. 'should serialize a directive (leaf) w/ `children`',
  523. );
  524. t.deepEqual(
  525. toMarkdown(
  526. {
  527. type: 'leafGrowiPluginDirective',
  528. name: 'a',
  529. children: [{ type: 'text', value: 'b' }],
  530. },
  531. { extensions: [directiveToMarkdown] },
  532. ),
  533. '::a[b]\n',
  534. 'should serialize a directive (leaf) w/ `children`',
  535. );
  536. t.deepEqual(
  537. toMarkdown(
  538. {
  539. type: 'leafGrowiPluginDirective',
  540. name: 'a',
  541. children: [{ type: 'text', value: 'b\nc' }],
  542. },
  543. { extensions: [directiveToMarkdown] },
  544. ),
  545. '::a[b&#xA;c]\n',
  546. 'should serialize a directive (leaf) w/ EOLs in `children`',
  547. );
  548. t.deepEqual(
  549. toMarkdown(
  550. {
  551. type: 'leafGrowiPluginDirective',
  552. name: 'a',
  553. attributes: { id: 'b', class: 'c d', key: 'e\nf' },
  554. children: [],
  555. },
  556. { extensions: [directiveToMarkdown] },
  557. ),
  558. '::a{#b .c.d key="e&#xA;f"}\n',
  559. 'should serialize a directive (leaf) w/ EOLs in `attributes`',
  560. );
  561. t.deepEqual(
  562. toMarkdown(
  563. // @ts-expect-error: `children`, `name` missing.
  564. { type: 'containerGrowiPluginDirective' },
  565. { extensions: [directiveToMarkdown] },
  566. ),
  567. ':::\n:::\n',
  568. 'should try to serialize a directive (container) w/o `name`',
  569. );
  570. t.deepEqual(
  571. toMarkdown(
  572. // @ts-expect-error: `children` missing.
  573. { type: 'containerGrowiPluginDirective', name: 'a' },
  574. { extensions: [directiveToMarkdown] },
  575. ),
  576. ':::a\n:::\n',
  577. 'should serialize a directive (container) w/ `name`',
  578. );
  579. t.deepEqual(
  580. toMarkdown(
  581. {
  582. type: 'containerGrowiPluginDirective',
  583. name: 'a',
  584. children: [{ type: 'paragraph', children: [{ type: 'text', value: 'b' }] }],
  585. },
  586. { extensions: [directiveToMarkdown] },
  587. ),
  588. ':::a\nb\n:::\n',
  589. 'should serialize a directive (container) w/ `children`',
  590. );
  591. t.deepEqual(
  592. toMarkdown(
  593. {
  594. type: 'containerGrowiPluginDirective',
  595. name: 'a',
  596. children: [
  597. { type: 'heading', depth: 1, children: [{ type: 'text', value: 'b' }] },
  598. ],
  599. },
  600. { extensions: [directiveToMarkdown] },
  601. ),
  602. ':::a\n# b\n:::\n',
  603. 'should serialize a directive (container) w/ `children` (heading)',
  604. );
  605. t.deepEqual(
  606. toMarkdown(
  607. {
  608. type: 'containerGrowiPluginDirective',
  609. name: 'a',
  610. children: [
  611. { type: 'paragraph', children: [{ type: 'text', value: 'b\nc' }] },
  612. ],
  613. },
  614. { extensions: [directiveToMarkdown] },
  615. ),
  616. ':::a\nb\nc\n:::\n',
  617. 'should serialize a directive (container) w/ EOLs in `children`',
  618. );
  619. t.deepEqual(
  620. toMarkdown(
  621. {
  622. type: 'containerGrowiPluginDirective',
  623. name: 'a',
  624. attributes: { id: 'b', class: 'c d', key: 'e\nf' },
  625. children: [],
  626. },
  627. { extensions: [directiveToMarkdown] },
  628. ),
  629. ':::a{#b .c.d key="e&#xA;f"}\n:::\n',
  630. 'should serialize a directive (container) w/ EOLs in `attributes`',
  631. );
  632. t.deepEqual(
  633. toMarkdown(
  634. {
  635. type: 'containerGrowiPluginDirective',
  636. name: 'a',
  637. children: [
  638. {
  639. type: 'paragraph',
  640. data: { directiveLabel: true },
  641. children: [{ type: 'text', value: 'b' }],
  642. },
  643. ],
  644. },
  645. { extensions: [directiveToMarkdown] },
  646. ),
  647. ':::a[b]\n:::\n',
  648. 'should serialize the first paragraph w/ `data.directiveLabel` as a label in a directive (container)',
  649. );
  650. t.deepEqual(
  651. toMarkdown(
  652. {
  653. type: 'containerGrowiPluginDirective',
  654. name: 'a',
  655. children: [
  656. {
  657. type: 'containerGrowiPluginDirective',
  658. name: 'b',
  659. children: [
  660. {
  661. type: 'paragraph',
  662. children: [{ type: 'text', value: 'c' }],
  663. },
  664. ],
  665. },
  666. ],
  667. },
  668. { extensions: [directiveToMarkdown] },
  669. ),
  670. '::::a\n:::b\nc\n:::\n::::\n',
  671. 'should serialize the outer containers w/ more colons than inner containers',
  672. );
  673. t.deepEqual(
  674. toMarkdown(
  675. {
  676. type: 'containerGrowiPluginDirective',
  677. name: 'a',
  678. children: [
  679. {
  680. type: 'containerGrowiPluginDirective',
  681. name: 'b',
  682. children: [
  683. {
  684. type: 'paragraph',
  685. children: [{ type: 'text', value: 'c' }],
  686. },
  687. ],
  688. },
  689. {
  690. type: 'containerGrowiPluginDirective',
  691. name: 'd',
  692. children: [
  693. {
  694. type: 'paragraph',
  695. children: [{ type: 'text', value: 'e' }],
  696. },
  697. ],
  698. },
  699. ],
  700. },
  701. { extensions: [directiveToMarkdown] },
  702. ),
  703. '::::a\n:::b\nc\n:::\n\n:::d\ne\n:::\n::::\n',
  704. 'should serialize w/ `3 + nesting`, not the total count (1)',
  705. );
  706. t.deepEqual(
  707. toMarkdown(
  708. {
  709. type: 'containerGrowiPluginDirective',
  710. name: 'a',
  711. children: [
  712. {
  713. type: 'containerGrowiPluginDirective',
  714. name: 'b',
  715. children: [
  716. {
  717. type: 'containerGrowiPluginDirective',
  718. name: 'c',
  719. children: [
  720. {
  721. type: 'paragraph',
  722. children: [{ type: 'text', value: 'd' }],
  723. },
  724. ],
  725. },
  726. ],
  727. },
  728. ],
  729. },
  730. { extensions: [directiveToMarkdown] },
  731. ),
  732. ':::::a\n::::b\n:::c\nd\n:::\n::::\n:::::\n',
  733. 'should serialize w/ `3 + nesting`, not the total count (2)',
  734. );
  735. t.deepEqual(
  736. toMarkdown(
  737. {
  738. type: 'containerGrowiPluginDirective',
  739. name: 'a',
  740. children: [
  741. {
  742. type: 'blockquote',
  743. children: [
  744. {
  745. type: 'containerGrowiPluginDirective',
  746. name: 'b',
  747. children: [
  748. {
  749. type: 'paragraph',
  750. children: [{ type: 'text', value: 'c' }],
  751. },
  752. ],
  753. },
  754. ],
  755. },
  756. ],
  757. },
  758. { extensions: [directiveToMarkdown] },
  759. ),
  760. '::::a\n> :::b\n> c\n> :::\n::::\n',
  761. 'should serialize w/ `3 + nesting`, not the total count (3)',
  762. );
  763. t.deepEqual(
  764. toMarkdown(
  765. {
  766. type: 'paragraph',
  767. children: [{ type: 'text', value: 'a:b' }],
  768. },
  769. { extensions: [directiveToMarkdown] },
  770. ),
  771. 'a\\:b\n',
  772. 'should escape a `:` in phrasing when followed by an alpha',
  773. );
  774. t.deepEqual(
  775. toMarkdown(
  776. {
  777. type: 'paragraph',
  778. children: [{ type: 'text', value: 'a:9' }],
  779. },
  780. { extensions: [directiveToMarkdown] },
  781. ),
  782. 'a:9\n',
  783. 'should not escape a `:` in phrasing when followed by a non-alpha',
  784. );
  785. t.deepEqual(
  786. toMarkdown(
  787. {
  788. type: 'paragraph',
  789. children: [{ type: 'text', value: 'a::c' }],
  790. },
  791. { extensions: [directiveToMarkdown] },
  792. ),
  793. 'a::c\n',
  794. 'should not escape a `:` in phrasing when preceded by a colon',
  795. );
  796. t.deepEqual(
  797. toMarkdown(
  798. {
  799. type: 'paragraph',
  800. children: [{ type: 'text', value: ':\na' }],
  801. },
  802. { extensions: [directiveToMarkdown] },
  803. ),
  804. ':\na\n',
  805. 'should not escape a `:` at a break',
  806. );
  807. t.deepEqual(
  808. toMarkdown(
  809. {
  810. type: 'paragraph',
  811. children: [{ type: 'text', value: ':a' }],
  812. },
  813. { extensions: [directiveToMarkdown] },
  814. ),
  815. '\\:a\n',
  816. 'should not escape a `:` at a break when followed by an alpha',
  817. );
  818. t.deepEqual(
  819. toMarkdown(
  820. {
  821. type: 'paragraph',
  822. children: [{ type: 'text', value: '::\na' }],
  823. },
  824. { extensions: [directiveToMarkdown] },
  825. ),
  826. '\\::\na\n',
  827. 'should escape a `:` at a break when followed by a colon',
  828. );
  829. t.deepEqual(
  830. toMarkdown(
  831. {
  832. type: 'paragraph',
  833. children: [{ type: 'text', value: ':::\na' }],
  834. },
  835. { extensions: [directiveToMarkdown] },
  836. ),
  837. '\\:::\na\n',
  838. 'should escape a `:` at a break when followed by two colons',
  839. );
  840. t.deepEqual(
  841. toMarkdown(
  842. {
  843. type: 'paragraph',
  844. children: [{ type: 'text', value: ':::\na' }],
  845. },
  846. { extensions: [directiveToMarkdown] },
  847. ),
  848. '\\:::\na\n',
  849. 'should escape a `:` at a break when followed by two colons',
  850. );
  851. t.deepEqual(
  852. toMarkdown(
  853. {
  854. type: 'paragraph',
  855. children: [
  856. { type: 'textGrowiPluginDirective', name: 'red', children: [] },
  857. { type: 'text', value: ':' },
  858. ],
  859. },
  860. { extensions: [directiveToMarkdown] },
  861. ),
  862. ':red:\n',
  863. 'should escape a `:` after a text directive',
  864. );
  865. t.end();
  866. });