Images have a syntax that is intended to resemble the syntax for inline and reference links but prepended with an exclamation mark.

![AltText](inline_link) 

![AltText][reference_link]

Alternate text is optional, this writting is also valid:

![](link)

Alternatively, the html <img> tag can also be used.

If the image is not found or cannot be rendered, you can choose to display the alternate text or the unicode "Frame with picture" symbol 🖼 via the images AltTag property. If AltText is empty, the "Frame with picture" symbol is used instead.

Formats

Supported formats are: bmp, jpg, png, tiff, webp, gif or any other file format registered using the WIC API.

SVG is supported but requires a bit more work. See below for more information.

Sources

Images can be:

  • automatically downloaded from the internet.
    Download is asynchronous and the alternate text is displayed while downloading or when the download fails. Downloads are cached for further fast access;
  • local files with absolute or relative path.
    The DesignPath property helps figuring out the final rendering with relative paths at design-time. This entry is ignored at runtime, the root being either the application path or the document path if loaded using LoadFromUri;
  • resources.
    The resource name must be prepended with an hash mark  #, ![AltText](#links). If the resource is located in an external library, insert an at sign @ between the library name and the resource name : ![AltText](#lib.dll@links);
  • embedded into the script in base64 encoding: ![AltText](data:image/svg;base64,...);
  • extracted from an Imagelist or VirtualImagelist.
    The link can be either the image name (Delphi 10.3 Rio or higher) ![AltText](myimage) or the index ![AltText](1). The control searches first in its own image list (`Images` property) or if not found in the linked *TMDStyle* if the `Style` property is set.

ImageList takes precedence over files if their names are identical.

Learn more

High DPI

Without further notice, images other than those from VirtualImageList are rendered in their original size, which is not DPI aware. The Markdown components add the size option to the Markdown specifications. The size is in em (1.0 em = font size) and is appended to the image name, separated by a comma: ![AltText](links,1). The decimal separator, if any, is always a dot. It is then very easy to inline images in text without worrying about the image size.

Notes

  • Images are aligned to the descent of the font, not the baseline.
  • If the URI ends with a comma followed by a valid integer or real number, the comma in the file name must be converted to its hexadecimal representation %2C.

Examples

Input

Output

Size (em)

 myfile,2

myfile

2

myfile,2.1

myfile

2.1

myfile,2.1.0

myfile,2.1.0

Not defined

myfile%2C2

myfile,2

Not defined

myfile,2.png

myfile,2.png

Not defined

myfile,2.png,0.8

myfile,2.png

0.8

SVG

SVG is supported by SKIA since Delphi 12. Markdown components are designed to run on Delphi XE8 (or newer) and therefore do not include SKIA units. However, this format can be supported very easily.

Notes

  • SVG using Skia
    • With Delphi XE8 up to 11 you will need to install the Skia4Delphi package first.
    • You must distribute the sk4d.dll Skia library with your application regardless of the Delphi version.
  • SVG using Image32
    • you will need to download and extract the Image32 package. Then to add the Source and Source\Clipper2 folders to the EDI library path or to your project search path.


Add Vcl.Markdown.Skia to the uses clause and handle the OnUnknownImage event as follow: 

uses Vcl.Graphics, Vcl.Markdown.Skia;

procedure TForm1.MDStyle1UnknownImage(Sender: TObject; const aFileName: string; aSize: TSize; const aImage: TWICImage);
begin
  aImage.LoadFromFile(aControl, aFileName, aSize);
end;

aSize is the size defined in a <img> tag and is used to best fit the image to the desired output. aSize can be null (cx=0, cy=0).

SVG Images can also be encoded in base64 (data:image/svg;base64,...). To load them handle the OnUnknownImage64 event: 

uses Vcl.Graphics, System.UITypes, Vcl.Markdown.Skia;

procedure TForm1.MDStyle1UnknownImage64(Sender: TObject; const aSource: string; aSize: TSize; aColor: TAlphaColor; const aImage: TWICImage);
begin
  aImage.LoadFromBase64(aControl, aSource, aSize, aColor);
end;

Filtering Images

Images can be filtered, for example, to show only in light or dark mode. To do this, append a parameter to the image link. A parameter starts with a question mark ? or a hash sign #.

![img](DarkImage.png?dark)
![img](LightImage.png#light)
<img src="LightImage.png#light" />

If parameters are found, the OnImageValidate event is fired to accept or reject the image (accepted by default).

All images are managed as usual, rejected images are just rendered with a null size.

Example

// The application uses two MDStyle components:
// - MDLightStyle for the light mode and
// - MDDarkStyle for the dark mode

// Here is the validation for MDLightStyle
procedure TForm1.MDLightStyleImageValidate(Sender: TObject; const aName: string; aParams: Array of string; var aAccept: Boolean);
begin
  // Reject what is clearly defined as "dark". Accept all others.
  aAccept := not MatchText('dark', aParams);
end;

Tip

A script from Github can declare #gh-light-mode-only or #gh-dark-mode-only parameters.

See also

Images styling