CodeMirror

Summary: An enhanced page editor for PmWiki
Version: 2021-04-08
Status: Stable
Prerequisites: pmwiki-2.2+, CodeMirror v4.8+ (defaults to v5.60.0), PHP 5.2+ and a recent browser
Maintainer: Dfaure (helped by Simon)
Download: cm4pm.zipΔ
Users: +4 -2 (view / edit)
Discussion: CodeMirror-Talk

Description

Example of CodeMirror PmWiki markup highlighting

This recipe provides the CodeMirror JavaScript text editor component to PmWiki, enabling both:

  • An enhanced page editing experience with pmwiki syntax highlighting, line numbers and line wrapping,
  • A generic syntax highlighting renderer for your source code excerpts, including PmWiki's own while using (:markup:)...(:markupend:) directives.

Installation

  1. Download the CodeMirror archive from its distribution site
  2. Extract it as a folder in your pub/ directory, e.g. codemirror-5.60.0/.
  3. Extract the recipe archive at the root of your PmWiki installation, putting the two php files in the cookbook/ directory and the cm/ folder containing js/css files in the pub/ directory. This should end with something like:
 cookbook/
  +- codemirror.php      <--+
  +- cm-sourceblock.php  <--+--[recipe stuff]
  +- cm-modes-compat.php <--+
  pub/                      |
  +- cm/                 <--+
  |   +- ...
  +- codemirror-5.60.0   <-----[CodeMirror distribution]
      +- bin/
      +- lib/
      +- ...
  1. Enable the recipe in your Local Customizations by including the recipe script:
    include_once("$FarmD/cookbook/codemirror.php");
    
  2. If different from defaults, locate the codemirror distribution before the include_once in Local Customizations, e.g. for the 5.25 codemirror distribution located in "pub/codemirror-5.25"):
    $CodeMirrorBaseUrl = "\$FarmPubDirUrl/codemirror-5.25.0";
    include_once("$FarmD/cookbook/codemirror.php");
    
  3. If you only wish to use the code-highlighting component, then place $EnableCodeMirrorPageEditing = 0; before include_once("$FarmD/cookbook/codemirror.php");.
  4. Then, navigate to a wiki page and edit it to see the component in action.

Notes

When enabled, the usual editing graphical buttons are made fully compatible with the new editor. A trailing checkbox is automatically added to the toolbar, allowing to switch back and forth between the codemirror editor and the regular textarea.

$EnableGUIButtons = 1;

Predefined configuration

As provided by the recipe, the CodeMirror component is configured with some active presets:

  • Top and bottom borders (default).
  • Line numbers display, line wrapping (linenumbers, linewrapping).
  • Syntax highlighting (syntax).
  • Text selection compatible with styled background text (selection).
  • Cursor color change according to insertion mode (cursor).
  • Active line background (activeline).
  • Visual tabulation (visualtab).
  • Visual trailing spaces (trailingspace), inactive by default.
  • Regular Tab key focus handling (tabfocus).
  • Folding entitled text sections (fold) according to their hierarchical level.
  • Automatic continuation of (Un)ordered lists (continuelist).
  • Autosize editor area according to content (autoresize) or up to specified height (maxheight). These are inactive by default and shouldn't be used together.
  • Full screen editing (fullscreen), inactive by default. Pressing F11 when cursor is in the editor will toggle full screen editing.
  • Search and replace (search), inactive by default (you may refer to CodeMirror search demo for related keybindings).
  • Highlighting all matching terms with the current one (match-highlighter), inactive by default.
  • Annotate scrollbar with search results/matching terms (annotate-scrollbars), inactive by default.
  • Autocompletion (hint), inactive by default. Pressing Ctrl-Space will simply looks at nearby words in the buffer and completes to those (may interfere with some editing modes).
  • Placeholder text (placeholder) when the editor is empty.
  • Mouse resizing by dragging the enlarged bottom editor border (resizer), inactive by default. Shouldn't be used with other sizing presets.
  • Keep last editing position (posfix) in browser local storage for each page, inactive by default.
  • Emacs/Sublime/Vim-like editing modes (emacs, sublime, vim), inactive by default.
  • Leaving full screen editing with the Esc key (fullscreen-esc), inactive by default (may interfere with some editing modes).

These customizations could be easily managed in the configuration file by setting them before including the recipe main script:

...
$CodeMirrorActivePresets['linenumbers'] = 0; # no line numbers
$CodeMirrorActivePresets['activeline'] = 0; # no highlighting for active line
$CodeMirrorActivePresets['maxheight'] = 1;
$CodeMirrorPresetParams['maxheight'] = '30em';
include_once("$FarmD/cookbook/codemirror.php");
...
Nota
Some presets are based on addons included in the CodeMirror distribution and therefore they shouldn't be forgotten (if needed) when getting the distribution in a minified form.

Configuration variables

The following variables are available to customize the recipe installation and behaviour:

$CodeMirrorBaseUrl, $CodeMirrorDirUrl
Where the CodeMirror distribution and the PmWiki dedicated javascript code could be found.
$CodeMirrorScriptName
Defaults to 'codemirror.js', ie. it provides a way to easily reference a minified version of the CodeMirror script.
As the recipe is dynamically binding CodeMirror's addons and modes sub-scripts according to the context, there's no need to merge other scripts when generating a minified version of the main script.
$CodeMirrorActivePresets, $CodeMirrorPresets, $CodeMirrorPresetParams
Respectively, selector, repository and related parameters of combinated data automatically added to the 3 following variables.
$CodeMirrorAddonsFmt, $CodeMirrorStylesFmt
PlaceHolders in $HTMLHeaderFmt where CodeMirror addon scripts and custom styles could be defined.
$CodeMirrorConfig
Entry point to the CodeMirror configuration object content itself.
$EnableCodeMirrorPageEditing, $EnableCodeMirrorBlockMarkup
Global switches for the 2 recipe main parts.
$EnableCodeMirrorPmWikiMarkup
Global switch for the (:markup:)...(:markupend:) rendering.
$CodeMirrorModeSpecs
Binding between language mode specifications and module definitions in CodeMirror distribution for code highlighting. See below.
$CodeMirrorModes
Binding between language module definitions and javascript implementations for code highlighting. See

below.

Code source highlighting

Initial configuration step

In order to handle all CodeMirror's highlighting languages subscripts and properly handle their inter-dependencies, the recipe need to build and maintain a configuration file describing them. The first time some source code is given to the recipe in a page, a link is provided to generate the required file (cm-modes-dependencies.php located in the cookbook directory). If for various reasons the file couldn't be generated (eg. write permission denied), the feedback message would provide the processed file content, enabling the maintainer to install it by other means.

The next time while the CodeMirror distribution is upgraded, the configuration file can be safely erased, and rebuild using the ?action=cm-dependencies url parameter. If the distribution is extracted in a different directory, a link should be available to regenerate the file.

These data are stored in the $CodeMirrorModeSpecs and $CodeMirrorModes global arrays as overridable defaults. Therefore, extra CodeMirror language modes may be registered without needing to modify files in the script distribution files.

Usage

After the initial configuration step (needed each time the CodeMirror distribution is upgraded), the recipe provides the following markup for your code excerpts:

 (:code <parameters>:)
 ...
 (:codeend:)

or:

 (:code <parameters>:) [@
 ...
 @]

with the following parameters:

  • modelist will list unconditionally all the differents language modes and mime/types offered by the CodeMirror component.
  • <mode / mime> is the CodeMirror mode or mime/type to use for highlighting the code block, e.g., (:code pascal:)...(:codeend:) for highlighing Pascal source code.
  • linenum(=n) would activate the rendering as an ordered list, optionally starting at the specified number.
  • highlight="n1,n2,n3" only meaningful while using linenum, the option would highlight lines with given numbers.

SourceBlock compatibility

The extra cm-modes-compat.php cookbook file has been released for those who wants to keep some compatibilities with the SourceBlock recipe markup. It should be noticed that not all the original languages are handled and only the linenum and highlight options are available.

Once the given file has been added after the main script (see below), the original (:source <parameters>:)...(:sourceend:) and (:source <parameters>:) [@...@] markups are available.

include_once("$FarmD/cookbook/codemirror.php");
include_once("$FarmD/cookbook/cm-modes-compat.php");

Caveats / Known limitations

Before all, despite the CodeMirror component should be able to handle rather old browsers down to IE8, this recipe hasn't been written with them in mind as stated by the CodeMirror's author himself.

As the PmWiki language is a very convenient markup set for the user, writing a syntaxic highlighter for it is rather hard. The one provided here is far from perfect, but should be able to render most of the language features.

Its main limitation is to be only able to handle upper level markups: ie. the markup sequence ''some [[Page]]'' would only be recognized as emphasized text, ignoring the inner link definition.

Another noticeable flaw is the lack of spell checking in the highlighted editor. This intrinsic limitation of CodeMirror and its way of handling text is the main reason to have available the highlight/regular editing checkbox feature in the icons bar.

The syntax colors/styles proposed for the PmWiki markup really need to be improved.

Known bug
In some cases, text/markup combinaisons aren't properly highlighted (any help is graciously appreciated):
(:if false:)(solely the markup rendering is relevant)
* aaa  bbb  [[ccc]] ddd  eee [[fff]] - ok
* aaa  bbb: [[ccc]] ddd  eee [[fff]] - ok
* aaa: bbb  [[ccc]] ddd  eee [[fff]] - ok
* aaa: bbb: [[ccc]] ddd: eee [[fff]] - ok
* aaa: bbb  [[ccc]] ddd: eee [[fff]] - ko!
(:ifend:)

Change log / Release notes

  • 2021-04-08 Fixed erroneous source code highlighting dependencies generation
  • 2021-04-06 Updated recipe for PHP 8.0 compatibility. Synched recipe default to v5.60.0 distribution.
  • 2019-07-24 Enabled SourceBlock partial compatibility markup.
  • 2019-07-23 Synched recipe default to v5.48.0 distribution. Fixed source code highlighting dependencies generation and sanitize markup handling. Added source line highlighting.
  • 2019-04-17 Fixed incomplete handling of non-UTF-8 charsets. Enable use of extra language modes.
  • 2019-04-12 Fixed list and horizontal line handling. Synched recipe default to v5.45.0 distribution.
  • 2018-02-05 Added editors keymap handling. Synched recipe default to 5.34.0 distribution. Fixed syntax highlighting markup for PHP7.2
  • 2017-04-10 Fixed source code highlighting for composite highlighters (php, html,...). The computed configuration file should be regenerated.
  • 2017-03-22 Synched recipe default to v5.25.0 distribution. Added more presets.
  • 2016-05-27 Added more presets. Some fixes in highlighting enabling title variable sizing.
  • 2016-05-26 Added mime/type handling in source code highlighting. Added search preset.
  • 2016-05-24 Synched recipe default to v5.12.2 distribution. Merged Simon's latest highlighting styles and definitions. Fixed (:markup:)...(:markupend:) handling.
  • 2015-04-12 Added more suggested updates to markup handling. Modified presets to simplify configuration.
  • 2015-03-29 Added suggested fixes and updates to markup handling. Extraneous (buggy) development files left in pub/cm/ folder by previous release are unused should be removed (oops).
  • 2015-03-27 Synched recipe default to v5.1 distribution. Remove forgotten debugging code making the recipe crash in some cases.
  • 2015-03-12 Synched recipe default to v4.13 distribution. Enabled source code highligting for intermixed languages.
  • 2015-01-20 Synched recipe default to v4.11 distribution. Fixed missing highlighting, added lists continuation and (:markup:)...(:markupend:) handling
  • 2015-01-07 Altered recipe default to v4.10 distribution and remove some extraneous javascript dependencies
  • 2014-12-26 Added missing MarkupExpr highlighting
  • 2014-12-23 Major rewrite with effective syntax highlighting
  • 2013-03-11 First public release

See also

Cookbook /
EditHelp  Easier editing with automatic detection and insertion of some wiki markups (Experimental)
PmSyntax  Syntax highlighting for the PmWiki documentation and edit form (Experimental)

Contributors

Recipe written by Dfaure and Simon, maintained by Dfaure.

Comments

See discussion at CodeMirror-Talk

User notes +4 -2: If you use, used or reviewed this recipe, you can add your name. These statistics appear in the Cookbook listings and will help newcomers browsing through the wiki.