An Exploration into Wardley Mapping Language Code

Create your own Wardley Mapping code editor in two easy steps

Mark Craddock
10 min readMay 23, 2023

--

Create your own Wardley Mapping code editor

The Ace Editor is a versatile, high-performance code editor that can be embedded straight into a web page. This feature-rich text editor provides numerous functionalities such as syntax highlighting, code folding, autocompletion, and many more, out of the box.

Ace Editor’s power can be amplified by defining custom language modes, which dictate how the text editor understands and manipulates different programming languages. These modes determine the syntax rules and help the editor offer relevant suggestions and highlight syntax appropriately.

We will explore the intricacies of an Ace Editor mode custom-built for Wardley Mapping language. By shedding light on the usage of regular expressions (regex) in defining syntax rules, we’ll illustrate how they shape our interaction with the language in the Ace Editor environment.

Wardley Mapping Language

Before delving into the code, let’s understand what Wardley Mapping is. Wardley Maps are diagrams that represent the landscape and climate of a business or service, mapping out its value chain and evolution. The language for representing these maps has been custom-developed to provide efficient notation and interpretation of the value chains.

Custom Ace Mode for Wardley Mapping Language

To support the Wardley Mapping language, a custom Ace mode named ‘owm’ is defined. This involves two main steps: defining the mode itself (in ‘ace/mode/owm’) and defining the highlight rules for the mode (in ‘ace/mode/owm_highlight_rules’).

The ‘owm’ mode is derived from the basic text mode, and its key components are the highlight rules, line comments, and block comments.

See the code from onlinewardleymaps.com. This is enough to get you started with creating a custom editor for Wardley Maps.

Highlight Rules and Regex

Highlight rules are pivotal in a language mode as they help differentiate between keywords, operators, comments, etc. These rules are defined using regex, enabling us to match complex patterns in the text. Regex, in essence, is a sequence of characters forming a search pattern used in pattern matching with strings.

In the custom ‘owm’ mode, multiple highlight rules have been defined for various parts of the Wardley Mapping language. For instance, pioneers, settlers, townplanners, etc., followed by four numeric values enclosed in square brackets, are identified as keywords and numeric constants. The numbers represent the location within the Wardley Map.

Keywords

The following section covers the regex definitions of each keyword for Wardley Mapping Code.

Pioneers, Settlers, and Townplanners

'(pioneers|settlers|townplanners)(\\s*\\[)(\\d+(?:\\.\\d{1,})*)(\\,\\s*)(\\d+(?:\\.\\d{1,})*)(\\,\\s*)(\\d+(?:\\.\\d{1,})*)(\\,\\s*)(\\d+(?:\\.\\d{1,}))(\\])'

This regular expression is used for identifying the syntax related to the Wardley Mapping’s ‘pioneers’, ‘settlers’, and ‘townplanners’ components.

The pattern it recognises contains one of these keywords followed by a list of four numbers enclosed in square brackets. The numbers could be integers or floating point.

Let’s break this regular expression down for a better understanding:

(pioneers|settlers|townplanners): This part of the expression uses the '|' operator, which stands for OR in regex. It matches either 'pioneers', 'settlers', or 'townplanners'.

(\\s*\\[): This matches zero or more white space characters followed by an opening square bracket '['.

(\\d+(?:\\.\\d{1,})*): This expression matches a number, which could be an integer or a floating point number.

\\d+ matches one or more digits, representing an integer.

(?:\\.\\d{1,})* is a non-capturing group that matches zero or more instances of a decimal point followed by one or more digits, representing the fractional part of a floating point number.

(\\,\\s*): This matches a comma followed by zero or more white space characters.

The regex then repeats the number and comma+whitespace parts three more times to match a total of four numbers.

(\\]): Finally, this matches a closing square bracket ']'.

So, an example string that this regular expression would match could look like: “pioneers[0.23, 0.56, 0.89, 0.12]” or “settlers[0.23, 0.56, 0.89, 0.12]”.

The array of numbers following the keyword is typically used in Wardley Maps to represent some parameters or properties of the respective component (pioneers, settlers, or townplanners), such as their coordinates or some other quantifiable attributes.

Comments

'(\\/\\/.*$)'

The regular expression '(/\\/\\/.*$)' is intended to match single-line comments in the text. In many programming languages, including JavaScript and C++, two consecutive forward slashes (//) are used to signify that the remainder of that line is a comment, and thus should not be executed as code.

Here’s a breakdown of this regex:

(\\/\\/.*$): This is the entire regular expression.

\\/\\/ matches the character sequence //. The forward slashes are preceded by backslashes, which are escape characters that allow the forward slashes to be treated as literal characters rather than regex metacharacters.

.* matches any character (except for a newline) 0 or more times. The . is a special character in regex that matches any character except for a newline, and * is a quantifier that means "zero or more of the preceding element."

$ is a special character that matches the end of a line.

So, for example, if you have a line of code like this:

component system [0.65, 0.34] // This is a comment.

This regular expression would match // This is a comment. including the two forward slashes at the start and everything else until the end of the line. This allows the syntax highlighter to properly style comments differently from executable code.

Various Keywords

'(y-axis|evolution|note|anchor|annotations|annotation|component|ecosystem|market|submap|title|style|outsource|build|product|buy|pipeline)(\\s*[-+\'";a-zA-Z0-9\\s*]+)'

This regular expression targets several keywords that are used in Wardley Mapping syntax and are followed by one or more of specific characters.

Let’s break down the components of the regex:

(y-axis|evolution|note|anchor|annotations|annotation|component|ecosystem|market|submap|title|style|outsource|build|product|buy|pipeline): This section of the regex matches any of these specific keywords, which are commonly used elements in Wardley Maps. The '|' character is a logical OR, meaning the regex will match any one of the listed words.

(\\s*[-+\'";a-zA-Z0-9\\s*]+): This part of the regex matches zero or more whitespace characters followed by one or more characters from the specific set. The character set includes:

  • ‘-’ and ‘+’ symbols
  • Apostrophe: ‘’’
  • Double quote: ‘“‘
  • Semicolon: ‘;’
  • All uppercase and lowercase letters: ‘a-zA-Z’
  • All numeric digits: ‘0–9’
  • Whitespace: ‘\s*’

These expressions are used in the context of defining various elements or properties of a Wardley Map. For example, ‘component’ may be used to define a new component on the map, ‘title’ to specify the title of the map, and so on. The symbols and alphanumeric characters following these keywords could be additional parameters or values related to the respective element.

Evolve Keyword

'(evolve)(\\s*[a-zA-Z0-9\\s*]+)(\\d+(?:\\.\\d{1,})*)'

This regular expression targets the evolve keyword used in Wardley Mapping syntax, which is typically followed by an alphanumeric string and a numerical value.

Let’s break down the components of the regex:

(evolve): This portion of the regex matches the exact keyword 'evolve'. In the context of Wardley Mapping, 'evolve' might be used to indicate a change or development of a particular component in the map over time.

(\\s*[a-zA-Z0-9\\s*]+): This part matches zero or more whitespace characters followed by one or more alphanumeric characters or whitespace. It's used to match names or labels associated with the 'evolve' keyword. For instance, it could be the name of a component that's evolving.

(\\d+(?:\\.\\d{1,})*): This is a regex for matching a numerical value which can be an integer or a floating-point number. It first matches one or more digit characters. The '(?:\.\d{1,})' part allows for optional decimal places. Here, '\.' is for decimal point, '\d{1,}' matches one or more digits, and the '' means the decimal and the digits after decimal are optional.

So, a string that this regex would match could look like this: ‘evolve ComponentA 0.67’ or ‘evolve ComponentB 0.5’. In a Wardley Map, this could be interpreted as indicating that ‘ComponentA’ or ‘ComponentB’ is expected to evolve to a certain position or state, represented by the numerical value, in the future.

Label Definition

'(label)(\\s*\\[)(-*\\d+)(\\,\\s*)(-*\\d+)(\\])'

This regular expression is designed to match the label keyword in the Wardley Mapping syntax, which is followed by a coordinate pair in square brackets. These coordinates represent the position of the label on the map.

Here is a breakdown of the regex:

(label): This part of the regex matches the keyword 'label'. In the context of Wardley Mapping, 'label' is typically used to specify a name or designation for a particular point or component on the map.

(\\s*\\[): This matches zero or more whitespace characters followed by an opening square bracket '['. The use of double backslashes is a standard convention in regex syntax where special characters like '[' need to be escaped.

(-*\\d+): This matches an optional negative sign followed by one or more digit characters. This allows for the specification of both positive and negative integer coordinates.

(\\,\\s*): This matches a comma followed by zero or more whitespace characters, serving as the separator between the X and Y coordinates.

(-*\\d+): Similar to the previous coordinate regex, this matches an optional negative sign followed by one or more digit characters. This is for the Y-coordinate.

(\\]): Finally, this matches a closing square bracket ']'.

Overall, this regex is used to match a syntax pattern in Wardley Mapping that looks like this: label [-2, 3]. This would place a label at the coordinates (-2, 3) on the Wardley Map.

Inertia

'(inertia)'

This regular expression is quite simple as compared to the others. It is specifically designed to match the keyword ‘inertia’. In the context of Wardley Mapping, ‘inertia’ refers to the resistance of a component, product, or service to change.

Here is a breakdown of the regex:

(inertia): This part of the regex matches the keyword 'inertia'. The parentheses are used to create a capturing group, which can be used to extract the match for further processing if necessary.

This regex doesn’t contain any other special symbols or character classes, making it straightforward to understand. Its purpose is to locate instances of the word ‘inertia’ in the text being processed.

So if in the context of a Wardley map, you have a line such as:

product A [3.5, 3.2] inertia

The regex (inertia) would match the word 'inertia' at the end.

Values Enclosed in Brackets

'(\\[*)(\\[)(\\d+(?:\\.\\d{1,})*)(\\,\\s*)(\\d+(?:\\.\\d{1,}))(\\])(\\]*)'

The regular expression '(\[*)(\[)(\\d+(?:\\.\\d{1,})*)(\\,\\s*)(\\d+(?:\\.\\d{1,}))(\\])(\\]*)' seems to be designed to match a pair of numerical values, possibly representing coordinates or dimensions, enclosed in square brackets [].

Let’s break it down:

(\[*): Matches zero or more opening square brackets [. The asterisk * allows for matching zero or more occurrences of the preceding element.

(\[): Matches a single opening square bracket [. This seems to be the actual start of the coordinates or dimensions.

(\\d+(?:\\.\\d{1,})*): Matches a decimal number, which could be an integer or a float.

\\d+ matches one or more digits.

(?:\\.\\d{1,})* is a non-capturing group that matches a decimal point followed by one or more digits, and this group can appear zero or more times (allowing for numbers like 1.23, 0.5, or just 1).

(\\,\\s*): Matches a comma followed by zero or more whitespace characters. This seems to be the delimiter between the two numbers.

(\\d+(?:\\.\\d{1,})): Matches the second decimal number, using the same pattern as before.

(\\]): Matches a single closing square bracket ]. This seems to be the actual end of the coordinates or dimensions.

(\\]*): Matches zero or more closing square brackets ]. Like the opening square brackets at the start, these don't seem to be part of the actual coordinates or dimensions, but are allowed to be there.

So, in a nutshell, this regex would match patterns like [1, 2], [[1.5, 2.6]] and so on, possibly with multiple wrapping square brackets, and can also handle decimal numbers. The matched numbers could represent a variety of things depending on the specific context, such as coordinates in a two-dimensional space, dimensions of a rectangular area, or any other pair of related numerical values.

Relation Definition

'(\\s*[a-zA-Z0-9\\s*]+)(\\-\\>)(\\s*[a-zA-Z0-9\\s*]+)'

This regular expression is meant to match patterns that look like a directed relation or transition from one term or name to another, using - and > as the arrow. This is commonly seen in diagrams or in programming-related contexts to denote a directional relation.

Let’s break it down:

(\\s*[a-zA-Z0-9\\s*]+): This captures a group of alphanumeric characters (a-z, A-Z, 0-9) and spaces. It allows for any term that consists of one or more alphanumeric characters and spaces, preceded by zero or more spaces.

\\s* matches zero or more whitespace characters (spaces, tabs, line breaks).

[a-zA-Z0-9\\s*]+ matches one or more alphanumeric characters or spaces. The + operator indicates "one or more" of the preceding element.

(\\-\\>): This matches the arrow symbol, which is represented as a hyphen - followed by a greater-than symbol >. This is a typical way of representing a directional arrow in ASCII, especially in contexts where graphical arrows are not available or practical.

(\\s*[a-zA-Z0-9\\s*]+): This matches the same pattern as the first part, for the second term or name in the relation or transition. It allows for the term that follows the arrow to also be composed of one or more alphanumeric characters and spaces, preceded by zero or more spaces.

So, this regular expression would match inputs like term1 -> term2, foo -> bar, and Hello World -> Goodbye, with optional spaces around the terms and the arrow. This pattern could be used to parse transitions or relationships from a text-based input or format, depending on the specific use case.

Here’s how you can create your own editor:

  1. Serve Your Ace Editor Mode File: Your mode files should be served from a server so they can be accessed in the web page. How you do this depends on your specific server setup.
  2. Include Ace Editor Mode file and Your Mode in a Web Page: Now you will create a HTML file and include Ace and your new mode files. This can be done by adding script tags to your HTML file. Here’s a basic example:

<!DOCTYPE html> <html> <head> <title>Ace Editor Test</title> <style type="text/css" media="screen"> #editor { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } </style> </head> <body> <div id="editor">...</div> <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.12/ace.js" charset="utf-8"></script> <script src="path/to/mode-owm.js"></script> <script> var editor = ace.edit("editor"); editor.setTheme("ace/theme/monokai"); editor.session.setMode("ace/mode/owm"); </script> </body> </html>

  1. This HTML file will create a fullscreen Ace editor, set the theme to monokai, and set the mode to your new owm mode. Be sure to replace "path/to/mode-owm.js" with the actual path to your mode-owm.js file.
  2. Test Your Syntax Highlighter
  3. Now you can open this HTML file in a web browser and see your Ace editor. Input some owm code and see if it gets highlighted correctly.

Conclusion

Ace Editor’s adaptability and power make it a favourite among developers. Its ability to define custom language modes paves the way for enhanced code readability and productivity, especially for domain-specific languages like the Wardley Mapping language. Understanding the roles of regex in defining these modes is key to unlocking the full potential of the Ace Editor

--

--

Mark Craddock

Techie. Built VH1, G-Cloud, Unified Patent Court, UN Global Platform. Saved UK Economy £12Bn. Now building AI stuff #datascout #promptengineer #MLOps #DataOps