Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 61 additions & 13 deletions docs/syntax/applies.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@
When you write or edit documentation, only specify the keys that apply to that content.
Each key accepts values with the following syntax:

```
```yaml
<key>: <lifecycle> [version]
```

Where:

- The [lifecycle](#lifecycle) is mandatory
- The [version](#version) is optional
- You can specify multiple states by separating them with a comma. For example: `stack: preview 9.1, ga 9.4`
* The [lifecycle](#lifecycle) is mandatory
* The [version](#version) is optional
* You can specify multiple states by separating them with a comma. For example: `stack: preview 9.1, ga 9.4`

:::{note}
**Automatic Version Sorting**: When you specify multiple versions for the same product, the build system automatically sorts them in descending order (highest version first) regardless of the order you write them in the source file. For example, `stack: ga 8.18.6, ga 9.1.2, ga 8.19.2, ga 9.0.6` will be displayed as `stack: ga 9.1.2, ga 9.0.6, ga 8.19.2, ga 8.18.6`. Items without versions (like `ga` without a version or `all`) are sorted last.
Expand All @@ -41,7 +41,7 @@

Versioned products require a `version` tag to be used with the `lifecycle` tag. See [Syntax](#syntax):

```
```yaml
applies_to:
stack: preview 9.1, ga 9.4
deployment:
Expand All @@ -50,7 +50,7 @@

Unversioned products use `lifecycle` tags without a version:

```
```yaml
applies_to:
serverless:
elasticsearch: beta
Expand All @@ -72,7 +72,6 @@
:::{include} /_snippets/applies_to-version.md
:::


## Examples

### Lifecycle examples
Expand Down Expand Up @@ -173,6 +172,56 @@
: definition body
```

## Directive property

### Tab-item directive

::::{tab-set}
:::{tab-item}

Check failure on line 180 in docs/syntax/applies.md

View workflow job for this annotation

GitHub Actions / build

{tab-item} requires an argument to name the tab.
:applies_to: stack: beta 9.0
This is where the content for tab #1 goes.
:::
:::{tab-item}

Check failure on line 184 in docs/syntax/applies.md

View workflow job for this annotation

GitHub Actions / build

{tab-item} requires an argument to name the tab.
:applies_to: stack: ga 9.1
This is where the content for tab #2 goes.
:::
:::{tab-item}

Check failure on line 188 in docs/syntax/applies.md

View workflow job for this annotation

GitHub Actions / build

{tab-item} requires an argument to name the tab.
:applies_to: serverless: ga
This is where the content for tab #3 goes.
:::
:::{tab-item} Titled Tab
This is where the content for tab #4 goes.
:::
::::

### Admonition directive

:::{tip}
:applies_to: eck: all
This is a tip.
:::

:::{admonition} This is my callout
:applies_to: eck: all
It can *span* multiple lines and supports inline formatting.
:::

:::{admonition}
:applies_to: stack: ga 9.0
In {{stack}} 9.0, dense vector fields are always indexed as `int8_hnsw`.
:::

### Dropdown directive

:::{dropdown} Rules are failing due to number of alerts
:applies_to: stack: all
Dropdown content
:::
:::{dropdown} Rules are failing due to number of alerts
:applies_to: stack: ga 9.0
Dropdown content
:::

## Structured model

![Applies To Model](images/applies.png)
Expand Down Expand Up @@ -215,7 +264,6 @@
---
```


## Look and feel

### Block
Expand All @@ -242,15 +290,15 @@
sit amet auctor odio. Donec ac placerat nunc. {applies_to}`stack: preview` Aenean scelerisque viverra lectus
nec dignissim. Vestibulum ut felis nec massa auctor placerat. Maecenas vel dictum.

- {applies_to}`elasticsearch: preview` Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas ut libero diam. Mauris sed eleifend erat, sit amet auctor odio. Donec ac placerat nunc.
- {applies_to}`observability: preview` Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas ut libero diam.
- {applies_to}`security: preview` Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas ut libero diam. Mauris sed eleifend erat, sit amet auctor odio. Donec ac placerat nunc. Aenean scelerisque viverra lectus nec dignissim.
* {applies_to}`elasticsearch: preview` Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas ut libero diam. Mauris sed eleifend erat, sit amet auctor odio. Donec ac placerat nunc.
* {applies_to}`observability: preview` Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas ut libero diam.
* {applies_to}`security: preview` Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas ut libero diam. Mauris sed eleifend erat, sit amet auctor odio. Donec ac placerat nunc. Aenean scelerisque viverra lectus nec dignissim.

#### Stack

| `applies_to` | result |
|--------------------------------------------|--------------------------------------|
| `` {applies_to}`stack: ` `` | {applies_to}`stack: ` |
| `` {applies_to}`stack: ` `` | {applies_to}`stack:` |
| `` {applies_to}`stack: preview` `` | {applies_to}`stack: preview` |
| `` {applies_to}`stack: preview 8.18` `` | {applies_to}`stack: preview 8.18` |
| `` {applies_to}`stack: preview 9.0` `` | {applies_to}`stack: preview 9.0` |
Expand Down Expand Up @@ -281,7 +329,7 @@

| `applies_to` | result |
|-------------------------------------------------|-------------------------------------------|
| `` {applies_to}`serverless: ` `` | {applies_to}`serverless: ` |
| `` {applies_to}`serverless: ` `` | {applies_to}`serverless:` |
| `` {applies_to}`serverless: preview` `` | {applies_to}`serverless: preview` |
| `` {applies_to}`serverless: ga` `` | {applies_to}`serverless: ga` |
| `` {applies_to}`serverless: beta` `` | {applies_to}`serverless: beta` |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ public AdmonitionBlock(DirectiveBlockParser parser, string admonition, ParserCon

public override void FinalizeAndValidate(ParserContext context)
{
// Call the DirectiveBlock's FinalizeAndValidate
// for setup common to all the directive blocks
base.FinalizeAndValidate(context);

CrossReferenceName = Prop("name");
DropdownOpen = TryPropBool("open");
if (DropdownOpen.HasValue)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
@using Elastic.Markdown.Myst.Components

@inherits RazorSlice<Elastic.Markdown.Myst.Directives.Admonition.AdmonitionViewModel>
<div class="admonition @Model.Directive @Model.Classes" id="@Model.CrossReferenceName" open="@Model.Open">
<div class="admonition-title">

@{
@{
switch (Model.Directive)
{
case "tip":
Expand Down Expand Up @@ -33,6 +34,12 @@
}
}
<span>@Model.Title</span>
@if (Model.ApplicableToViewModel != null)
{
<span class="blah applies applies-inline" style="margin-left: auto;">
@RenderPartialAsync(ApplicableToComponent.Create(Model.ApplicableToViewModel))
</span>
}
</div>
<div class="admonition-content">@Model.RenderBlock()</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information

using Elastic.Markdown.Myst.Components;

namespace Elastic.Markdown.Myst.Directives.Admonition;

public class AdmonitionViewModel : DirectiveViewModel
Expand All @@ -11,4 +13,5 @@ public class AdmonitionViewModel : DirectiveViewModel
public required string? CrossReferenceName { get; init; }
public required string? Classes { get; init; }
public required string? Open { get; init; }
public required ApplicableToViewModel? ApplicableToViewModel { get; init; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ public class DiagramBlock(DirectiveBlockParser parser, ParserContext context) :

public override void FinalizeAndValidate(ParserContext context)
{
// Call the DirectiveBlock's FinalizeAndValidate
// for setup common to all the directive blocks
base.FinalizeAndValidate(context);

// Extract diagram type from arguments or default to "mermaid"
DiagramType = !string.IsNullOrWhiteSpace(Arguments) ? Arguments.ToLowerInvariant() : "mermaid";

Expand Down
49 changes: 48 additions & 1 deletion src/Elastic.Markdown/Myst/Directives/DirectiveBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
// See the license.txt file in the project root for more information.

using System.IO.Abstractions;
using Elastic.Documentation.AppliesTo;
using Elastic.Documentation.Configuration;
using Elastic.Markdown.Diagnostics;
using Elastic.Markdown.Myst.Components;
using Markdig.Helpers;
using Markdig.Syntax;

Expand Down Expand Up @@ -95,11 +98,55 @@ public abstract class DirectiveBlock(
/// <inheritdoc />
public int ClosingFencedCharCount { get; set; }

/// <summary>
/// Applicability of this directive, in terms of product and version.
/// </summary>
public ApplicableToViewModel? ApplicableToViewModel { get; set; }

/// <summary>
/// Allows blocks to finalize setting properties once fully parsed
/// </summary>
/// <param name="context"></param>
public abstract void FinalizeAndValidate(ParserContext context);
public virtual void FinalizeAndValidate(ParserContext context)
{
//context.Build.VersionsConfiguration;
var applicableTo = ParseApplicableTo(context);
if (applicableTo != null)
{
ApplicableToViewModel = new ApplicableToViewModel
{
Inline = true,
AppliesTo = applicableTo,
VersionsConfig = context.Build.VersionsConfiguration
};
}
}

private ApplicableTo? ParseApplicableTo(ParserContext processor)
{
if (Properties is null)
return null;
var appliesTo = Prop("applies_to");
if (string.IsNullOrWhiteSpace(appliesTo))
return null;

try
{
var applicableTo = YamlSerialization.Deserialize<ApplicableTo>(appliesTo);
if (applicableTo.Diagnostics is null)
return applicableTo;
foreach (var (severity, message) in applicableTo.Diagnostics)
processor.EmitError(message);
applicableTo.Diagnostics = null;
return applicableTo;
}
catch (Exception e)
{
processor.EmitError($"Unable to parse applies_to role: {{{Directive}}}{appliesTo}", e);
}

return null;
}

internal void AddProperty(string key, string value)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,12 +201,12 @@ public override BlockState TryContinue(BlockProcessor processor, Block block)
if (block is not DirectiveBlock directiveBlock)
return base.TryContinue(processor, block);

var tokens = line.ToString().Split(':', 3, RemoveEmptyEntries | TrimEntries);
var tokens = line.ToString().Split(':', 2, RemoveEmptyEntries | TrimEntries);
if (tokens.Length < 1)
return base.TryContinue(processor, block);

var name = tokens[0];
var data = tokens.Length > 1 ? string.Join(":", tokens[1..]) : string.Empty;
var data = tokens.Length > 1 ? tokens[1] : string.Empty;
directiveBlock.AddProperty(name, data);

return BlockState.Continue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,8 @@ private static void WriteAdmonition(HtmlRenderer renderer, AdmonitionBlock block
CrossReferenceName = block.CrossReferenceName,
Classes = block.Classes,
Title = block.Title,
Open = block.DropdownOpen.GetValueOrDefault() ? "open" : null
Open = block.DropdownOpen.GetValueOrDefault() ? "open" : null,
ApplicableToViewModel = block.ApplicableToViewModel,
});
RenderRazorSlice(slice, renderer);
}
Expand All @@ -226,7 +227,8 @@ private static void WriteDropdown(HtmlRenderer renderer, DropdownBlock block)
CrossReferenceName = block.CrossReferenceName,
Classes = block.Classes,
Title = block.Title,
Open = block.DropdownOpen.GetValueOrDefault() ? "open" : null
Open = block.DropdownOpen.GetValueOrDefault() ? "open" : null,
ApplicableToViewModel = block.ApplicableToViewModel,
});
RenderRazorSlice(slice, renderer);
}
Expand All @@ -246,7 +248,8 @@ private static void WriteTabItem(HtmlRenderer renderer, TabItemBlock block)
Title = block.Title,
TabSetIndex = block.TabSetIndex,
SyncKey = block.SyncKey,
TabSetGroupKey = block.TabSetGroupKey
TabSetGroupKey = block.TabSetGroupKey,
ApplicableToViewModel = block.ApplicableToViewModel,
});
RenderRazorSlice(slice, renderer);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
@using Elastic.Markdown.Myst.Components

@inherits RazorSlice<Elastic.Markdown.Myst.Directives.Admonition.AdmonitionViewModel>

<details class="dropdown @Model.Classes" id="@Model.CrossReferenceName" open="@Model.Open">
<summary class="dropdown-title">
<span class="sd-summary-text">@Model.Title</span>
<span>
@if (Model.ApplicableToViewModel != null)
{
<span class="applies applies-inline">
@RenderPartialAsync(ApplicableToComponent.Create(Model.ApplicableToViewModel))
&nbsp
</span>
}
<span class="sd-summary-text">@Model.Title</span>
</span>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
Expand Down
4 changes: 4 additions & 0 deletions src/Elastic.Markdown/Myst/Directives/Image/ImageBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ public class ImageBlock(DirectiveBlockParser parser, ParserContext context)

public override void FinalizeAndValidate(ParserContext context)
{
// Call the DirectiveBlock's FinalizeAndValidate
// for setup common to all the directive blocks
base.FinalizeAndValidate(context);

Label = Prop("label", "name");
Alt = Prop("alt")?.ReplaceSubstitutions(context) ?? string.Empty;
// Use Alt as Title if no explicit Title is provided
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ public class ImageCarouselBlock(DirectiveBlockParser parser, ParserContext conte

public override void FinalizeAndValidate(ParserContext context)
{
// Call the DirectiveBlock's FinalizeAndValidate
// for setup common to all the directive blocks
base.FinalizeAndValidate(context);

// Parse options
Id = Prop("id");
MaxHeight = Prop("max-height");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ public class IncludeBlock(DirectiveBlockParser parser, ParserContext context) :
//https://mystmd.org/guide/directives#directive-include
public override void FinalizeAndValidate(ParserContext context)
{
// Call the DirectiveBlock's FinalizeAndValidate
// for setup common to all the directive blocks
base.FinalizeAndValidate(context);

Literal |= PropBool("literal");
Language = Prop("lang", "language", "code");
Caption = Prop("caption");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ public class MermaidBlock(DirectiveBlockParser parser, ParserContext context) :
{
public override string Directive => "mermaid";

public override void FinalizeAndValidate(ParserContext context)
{
}
public override void FinalizeAndValidate(ParserContext context) =>
// Call the DirectiveBlock's FinalizeAndValidate
// for setup common to all the directive blocks
base.FinalizeAndValidate(context);
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,14 @@ public class SettingsBlock(DirectiveBlockParser parser, ParserContext context) :

//TODO add all options from
//https://mystmd.org/guide/directives#directive-include
public override void FinalizeAndValidate(ParserContext context) => ExtractInclusionPath(context);
public override void FinalizeAndValidate(ParserContext context)
{
// Call the DirectiveBlock's FinalizeAndValidate
// for setup common to all the directive blocks
base.FinalizeAndValidate(context);

ExtractInclusionPath(context);
}

private void ExtractInclusionPath(ParserContext context)
{
Expand Down
Loading
Loading