autoformat.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /**
  2. * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. /**
  6. * @module autoformat/autoformat
  7. */
  8. import BlockAutoformatEditing from './blockautoformatediting';
  9. import InlineAutoformatEditing from './inlineautoformatediting';
  10. import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
  11. /**
  12. * Includes a set of predefined autoformatting actions. For a detailed overview, check
  13. * the {@glink features/autoformat Autoformatting feature documentation}.
  14. *
  15. * @extends module:core/plugin~Plugin
  16. */
  17. export default class Autoformat extends Plugin {
  18. /**
  19. * @inheritDoc
  20. */
  21. static get pluginName() {
  22. return 'Autoformat';
  23. }
  24. /**
  25. * @inheritDoc
  26. */
  27. afterInit() {
  28. this._addListAutoformats();
  29. this._addBasicStylesAutoformats();
  30. this._addHeadingAutoformats();
  31. this._addBlockQuoteAutoformats();
  32. }
  33. /**
  34. * Adds autoformatting related to the {@link module:list/list~List}.
  35. *
  36. * When typed:
  37. * - `* ` or `- ` – A paragraph will be changed to a bulleted list.
  38. * - `1. ` or `1) ` – A paragraph will be changed to a numbered list ("1" can be any digit or a list of digits).
  39. *
  40. * @private
  41. */
  42. _addListAutoformats() {
  43. const commands = this.editor.commands;
  44. if ( commands.get( 'bulletedList' ) ) {
  45. // eslint-disable-next-line no-new
  46. new BlockAutoformatEditing( this.editor, /^[*-]\s$/, 'bulletedList' );
  47. }
  48. if ( commands.get( 'numberedList' ) ) {
  49. // eslint-disable-next-line no-new
  50. new BlockAutoformatEditing( this.editor, /^\d+[.|)]\s$/, 'numberedList' );
  51. }
  52. }
  53. /**
  54. * Adds autoformatting related to the {@link module:basic-styles/bold~Bold},
  55. * {@link module:basic-styles/italic~Italic} and {@link module:basic-styles/code~Code}.
  56. *
  57. * When typed:
  58. * - `**foobar**` – `**` characters are removed and `foobar` is set to bold,
  59. * - `__foobar__` – `__` characters are removed and `foobar` is set to bold,
  60. * - `*foobar*` – `*` characters are removed and `foobar` is set to italic,
  61. * - `_foobar_` – `_` characters are removed and `foobar` is set to italic,
  62. * - ``` `foobar` – ``` ` ``` characters are removed and `foobar` is set to code.
  63. *
  64. * @private
  65. */
  66. _addBasicStylesAutoformats() {
  67. const commands = this.editor.commands;
  68. if ( commands.get( 'bold' ) ) {
  69. /* eslint-disable no-new */
  70. new InlineAutoformatEditing( this.editor, /(\*\*)([^*]+)(\*\*)$/g, 'bold' );
  71. new InlineAutoformatEditing( this.editor, /(__)([^_]+)(__)$/g, 'bold' );
  72. /* eslint-enable no-new */
  73. }
  74. if ( commands.get( 'italic' ) ) {
  75. // The italic autoformatter cannot be triggered by the bold markers, so we need to check the
  76. // text before the pattern (e.g. `(?:^|[^\*])`).
  77. /* eslint-disable no-new */
  78. new InlineAutoformatEditing( this.editor, /(?:^|[^*])(\*)([^*_]+)(\*)$/g, 'italic' );
  79. new InlineAutoformatEditing( this.editor, /(?:^|[^_])(_)([^_]+)(_)$/g, 'italic' );
  80. /* eslint-enable no-new */
  81. }
  82. if ( commands.get( 'code' ) ) {
  83. /* eslint-disable no-new */
  84. new InlineAutoformatEditing( this.editor, /(`)([^`]+)(`)$/g, 'code' );
  85. /* eslint-enable no-new */
  86. }
  87. }
  88. /**
  89. * Adds autoformatting related to {@link module:heading/heading~Heading}.
  90. *
  91. * It is using a number at the end of the command name to associate it with the proper trigger:
  92. *
  93. * * `heading` with value `heading1` will be executed when typing `#`,
  94. * * `heading` with value `heading2` will be executed when typing `##`,
  95. * * ... up to `heading6` and `######`.
  96. *
  97. * @private
  98. */
  99. _addHeadingAutoformats() {
  100. const command = this.editor.commands.get( 'heading' );
  101. if ( command ) {
  102. command.modelElements
  103. .filter( name => name.match( /^heading[1-6]$/ ) )
  104. .forEach( commandValue => {
  105. const level = commandValue[ 7 ];
  106. const pattern = new RegExp( `^(#{${ level }})\\s$` );
  107. // eslint-disable-next-line no-new
  108. new BlockAutoformatEditing( this.editor, pattern, () => {
  109. this.editor.execute( 'heading', { value: commandValue } );
  110. } );
  111. } );
  112. }
  113. }
  114. /**
  115. * Adds autoformatting related to {@link module:block-quote/blockquote~BlockQuote}.
  116. *
  117. * When typed:
  118. * * `> ` – A paragraph will be changed to a block quote.
  119. *
  120. * @private
  121. */
  122. _addBlockQuoteAutoformats() {
  123. if ( this.editor.commands.get( 'blockQuote' ) ) {
  124. // eslint-disable-next-line no-new
  125. new BlockAutoformatEditing( this.editor, /^>\s$/, 'blockQuote' );
  126. }
  127. }
  128. }