Skip to content

Commit 333d0c5

Browse files
Mpdreamzreakaleek
andauthored
Add support for version context variables (#1560)
* Add support for version context variables * Apply suggestion from @reakaleek Co-authored-by: Jan Calanog <[email protected]> * Apply suggestion from @reakaleek Co-authored-by: Jan Calanog <[email protected]> * Add support for variable operator syntax (#1563) * Add support for variable operator syntax * do not report version variables as unused * Allow a space after {{ * carry trimming over to split * Temporarily make variables with spaces that are not found hints, we used to not do anything here * flip ternary --------- Co-authored-by: Jan Calanog <[email protected]>
1 parent 34e2e16 commit 333d0c5

File tree

14 files changed

+393
-63
lines changed

14 files changed

+393
-63
lines changed

docs/_docset.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ toc:
100100
- file: sidebars.md
101101
- file: stepper.md
102102
- file: substitutions.md
103+
- file: version-variables.md
103104
- file: sundries.md
104105
- file: tables.md
105106
- file: tabs.md

docs/syntax/substitutions.md

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ sub:
33
frontmatter_key: "Front Matter Value"
44
a-key-with-dashes: "A key with dashes"
55
version: 7.17.0
6+
hello-world: "Hello world!"
67
---
78

89
# Substitutions
@@ -26,7 +27,7 @@ Doing so will result in a build error.
2627

2728
To use the variables in your files, surround them in curly brackets (`{{variable}}`).
2829

29-
## Example
30+
### Example
3031

3132
Here are some variable substitutions:
3233

@@ -36,6 +37,97 @@ Here are some variable substitutions:
3637
| {{a-key-with-dashes}} | Front Matter |
3738
| {{a-global-variable}} | `docset.yml` |
3839

40+
## Mutations
41+
42+
Substitutions can be mutated using a chain of operators seperated by a pipe (`|`).
43+
44+
````markdown
45+
`{{hello-world | trim | lc | tc}}`
46+
````
47+
48+
Will trim, lowercase and finally titlecase the contents of the 'hello-world' variable.
49+
50+
### Operators
51+
52+
53+
| Operator | Purpose |
54+
|----------|----------------------------------------------------|
55+
| `lc` | LowerCase, |
56+
| `uc` | UpperCase, |
57+
| `tc` | TitleCase, capitalizes all words, |
58+
| `c` | Capitalize the first letter, |
59+
| `kc` | Convert to KebabCase, |
60+
| `sc` | Convert to SnakeCase, |
61+
| `cc` | Convert to CamelCase, |
62+
| `pc` | Convert to PascalCase, |
63+
| `trim` | Trim common non word characters from start and end |
64+
65+
For variables declaring a semantic version or `Major.Minor` the following operations are also exposed
66+
67+
| Operator | Purpose |
68+
|----------|------------------------------------------|
69+
| `M` | Display only the major component |
70+
| `M.x` | Display major component followed by '.x' |
71+
| `M.M` | Display only the major and the minor |
72+
| `M+1` | The next major version |
73+
| `M.M+1` | The next minor version |
74+
75+
### Example
76+
77+
Given the following frontmatter:
78+
79+
```yaml
80+
---
81+
sub:
82+
hello-world: "Hello world!"
83+
---
84+
```
85+
86+
::::{tab-set}
87+
88+
:::{tab-item} Output
89+
90+
* Lowercase: {{hello-world | lc}}
91+
* Uppercase: {{hello-world | uc}}
92+
* TitleCase: {{hello-world | tc}}
93+
* kebab-case: {{hello-world | kc}}
94+
* camelCase: {{hello-world | tc | cc}}
95+
* PascalCase: {{hello-world | pc}}
96+
* SnakeCase: {{hello-world | sc}}
97+
* CapitalCase (chained): {{hello-world | lc | c}}
98+
* Trim: {{hello-world | trim}}
99+
* M.x: {{version.stack | M.x }}
100+
* M.M: {{version.stack | M.M }}
101+
* M: {{version.stack | M }}
102+
* M+1: {{version.stack | M+1 }}
103+
* M+1 | M.M: {{version.stack | M+1 | M.M }}
104+
* M.M+1: {{version.stack | M.M+1 }}
105+
106+
:::
107+
108+
:::{tab-item} Markdown
109+
110+
````markdown
111+
* Lowercase: {{hello-world | lc}}
112+
* Uppercase: {{hello-world | uc}}
113+
* TitleCase: {{hello-world | tc}}
114+
* kebab-case: {{hello-world | kc}}
115+
* camelCase: {{hello-world | tc | cc}}
116+
* PascalCase: {{hello-world | pc}}
117+
* SnakeCase: {{hello-world | sc}}
118+
* CapitalCase (chained): {{hello-world | lc | c}}
119+
* Trim: {{hello-world | trim}}
120+
* M.x: {{version.stack | M.x }}
121+
* M.M: {{version.stack | M.M }}
122+
* M: {{version.stack | M }}
123+
* M+1: {{version.stack | M+1 }}
124+
* M+1 | M.M: {{version.stack | M+1 | M.M }}
125+
* M.M+1: {{version.stack | M.M+1 }}
126+
````
127+
:::
128+
129+
::::
130+
39131
## Code blocks
40132

41133
Substitutions are supported in code blocks but are disabled by default. Enable substitutions by adding `subs=true` to the code block.

docs/syntax/version-variables.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Version Variables
2+
3+
Version are exposed during build using the `{{versions.VERSIONING_SCHEME}}` variable.
4+
5+
For example `stack` versioning variables are exposed as `{{versions.stack}}`.
6+
7+
## Specialized Suffixes.
8+
9+
Besides the current version, the following suffixes are available:
10+
11+
| Version substitution | result | purpose |
12+
|--------------------------------------|-----------------------------------|-----------------------------------------|
13+
| `{{version.stack}}` | {{version.stack}} | Current version |
14+
| `{{version.stack.base}}` | {{version.stack.base}} | The first version on the new doc system |
15+
16+
## Formatting
17+
18+
Using specialized [mutation operators](substitutions.md#mutations) versions
19+
can be printed in any kind of ways.
20+
21+
22+
| Version substitution | result |
23+
|------------------------|-----------|
24+
| `{{version.stack| M.M}}` | {{version.stack|M.M}} |
25+
| `{{version.stack.base | M }}` | {{version.stack.base | M }} |
26+
| `{{version.stack | M+1 | M }}` | {{version.stack | M+1 | M }} |
27+
| `{{version.stack.base | M.M+1 }}` | {{version.stack.base | M.M+1 }} |
28+
29+
## Available versioning schemes.
30+
31+
This is dictated by the [versions.yml](https://github.com/elastic/docs-builder/blob/main/src/Elastic.Documentation.Configuration/versions.yml) configuration file
32+
33+
* `stack`
34+
* `ece`
35+
* `ech`
36+
* `eck`
37+
* `ess`
38+
* `self`
39+
* `ecctl`
40+
* `curator`
41+
* `security`
42+
* `apm_agent_android`
43+
* `apm_agent_ios`
44+
* `apm_agent_dotnet`
45+
* `apm_agent_go`
46+
* `apm_agent_java`
47+
* `apm_agent_node`
48+
* `apm_agent_php`
49+
* `apm_agent_python`
50+
* `apm_agent_ruby`
51+
* `apm_agent_rum`
52+
* `edot_ios`
53+
* `edot_android`
54+
* `edot_dotnet`
55+
* `edot_java`
56+
* `edot_node`
57+
* `edot_php`
58+
* `edot_python`
59+
* `edot_cf_aws`
60+
* `edot_collector`
61+
62+
The following are available but should not be used. These map to serverless projects and have a fixed high version number.
63+
64+
* `all`
65+
* `ech`
66+
* `ess` (This is deprectated but was added for backwards-compatibility.)
67+
68+
* `serverless`
69+
* `elasticsearch`
70+
* `observability`

src/Elastic.Documentation.Configuration/BuildContext.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ public BuildContext(
100100
DocumentationSourceDirectory = ConfigurationPath.Directory!;
101101

102102
Git = gitCheckoutInformation ?? GitCheckoutInformation.Create(DocumentationCheckoutDirectory, ReadFileSystem);
103-
Configuration = new ConfigurationFile(this);
103+
Configuration = new ConfigurationFile(this, VersionsConfig);
104104
GoogleTagManager = new GoogleTagManagerConfiguration
105105
{
106106
Enabled = false

src/Elastic.Documentation.Configuration/Builder/ConfigurationFile.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using DotNet.Globbing;
77
using Elastic.Documentation.Configuration.Suggestions;
88
using Elastic.Documentation.Configuration.TableOfContents;
9+
using Elastic.Documentation.Configuration.Versions;
910
using Elastic.Documentation.Links;
1011
using Elastic.Documentation.Navigation;
1112
using YamlDotNet.RepresentationModel;
@@ -61,7 +62,7 @@ public record ConfigurationFile : ITableOfContentsScope
6162
Project is not null
6263
&& Project.Equals("Elastic documentation", StringComparison.OrdinalIgnoreCase);
6364

64-
public ConfigurationFile(IDocumentationContext context)
65+
public ConfigurationFile(IDocumentationContext context, VersionsConfiguration versionsConfig)
6566
{
6667
_context = context;
6768
ScopeDirectory = context.ConfigurationPath.Directory!;
@@ -159,6 +160,16 @@ public ConfigurationFile(IDocumentationContext context)
159160
}
160161
}
161162

163+
foreach (var (id, system) in versionsConfig.VersioningSystems)
164+
{
165+
var name = id.ToStringFast(true);
166+
var key = $"version.{name}";
167+
_substitutions[key] = system.Current;
168+
169+
key = $"version.{name}.base";
170+
_substitutions[key] = system.Base;
171+
}
172+
162173
var toc = new TableOfContentsConfiguration(this, sourceFile, ScopeDirectory, _context, 0, "");
163174
TableOfContents = toc.TableOfContents;
164175
Files = toc.Files;

src/Elastic.Documentation.Configuration/Versions/Version.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,11 @@ public enum VersioningSystemId
4444
[Display(Name = "serverless")]
4545
Serverless,
4646
[Display(Name = "elasticsearch")]
47-
Elasticsearch,
47+
ElasticsearchProject,
4848
[Display(Name = "observability")]
49-
Observability,
49+
ObservabilityProject,
5050
[Display(Name = "security")]
51-
Security,
51+
SecurityProject,
5252
[Display(Name = "apm_agent_android")]
5353
ApmAgentAndroid,
5454
[Display(Name = "apm_agent_ios")]

src/Elastic.Markdown/Diagnostics/ProcessorDiagnosticExtensions.cs

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,32 +14,24 @@ public static class ProcessorDiagnosticExtensions
1414
{
1515
private static string CreateExceptionMessage(string message, Exception? e) => message + (e != null ? Environment.NewLine + e : string.Empty);
1616

17-
public static void EmitError(this InlineProcessor processor, int line, int column, int length, string message)
18-
{
19-
var context = processor.GetContext();
20-
if (context.SkipValidation)
21-
return;
22-
var d = new Diagnostic
23-
{
24-
Severity = Severity.Error,
25-
File = processor.GetContext().MarkdownSourcePath.FullName,
26-
Column = column,
27-
Line = line,
28-
Message = message,
29-
Length = length
30-
};
31-
context.Build.Collector.Write(d);
32-
}
17+
public static void EmitError(this InlineProcessor processor, int line, int column, int length, string message) =>
18+
processor.Emit(Severity.Error, line, column, length, message);
3319

3420

35-
public static void EmitWarning(this InlineProcessor processor, int line, int column, int length, string message)
21+
public static void EmitWarning(this InlineProcessor processor, int line, int column, int length, string message) =>
22+
processor.Emit(Severity.Warning, line, column, length, message);
23+
24+
public static void EmitHint(this InlineProcessor processor, int line, int column, int length, string message) =>
25+
processor.Emit(Severity.Hint, line, column, length, message);
26+
27+
public static void Emit(this InlineProcessor processor, Severity severity, int line, int column, int length, string message)
3628
{
3729
var context = processor.GetContext();
3830
if (context.SkipValidation)
3931
return;
4032
var d = new Diagnostic
4133
{
42-
Severity = Severity.Warning,
34+
Severity = severity,
4335
File = processor.GetContext().MarkdownSourcePath.FullName,
4436
Column = column,
4537
Line = line,

src/Elastic.Markdown/DocumentationGenerator.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,13 @@ private void HintUnusedSubstitutionKeys()
180180
{
181181
var definedKeys = new HashSet<string>(Context.Configuration.Substitutions.Keys.ToArray());
182182
var inUse = new HashSet<string>(Context.Collector.InUseSubstitutionKeys.Keys);
183-
var keysNotInUse = definedKeys.Except(inUse).ToArray();
183+
var keysNotInUse = definedKeys.Except(inUse)
184+
// versions keys are injected
185+
.Where(key => !key.StartsWith("version."))
186+
// reserving context namespace
187+
.Where(key => !key.StartsWith("context."))
188+
.ToArray();
189+
184190
// If we have less than 20 unused keys, emit them separately,
185191
// Otherwise emit one hint with all of them for brevity
186192
if (keysNotInUse.Length >= 20)

0 commit comments

Comments
 (0)