@opendocs/sfdocs-liquid-lint-capture
v0.0.1-alpha
Published
Validates '{% capture tag_name %} "..." {% endcapture %}' Liquid capture under shared/partials markdown files
Readme
liquid-lint-capture
This Markdown plugin validates the correct usage of Liquid capture blocks based on file location.
What it checks
For files in shared/partials/:
- Content must be in capture blocks: All markdown content (except comments) must be inside
{% capture %}blocks - No duplicate capture names: Each capture variable name must be unique within the file
- Allowed content outside capture blocks:
- HTML comments:
<!-- comment --> - Liquid comments:
{% comment %}...{% endcomment %} - Whitespace
- HTML comments:
For files outside shared/partials/:
- Capture blocks are not allowed: Files outside the partials folder must not contain
{% capture %}blocks
Why
Partial files in shared/partials/ are reusable snippets that define Liquid variables via capture blocks. These variables are then consumed by other markdown files through includes. Enforcing this structure ensures:
- Predictable variable definitions
- No unintended content rendering
- Prevent variable name collisions
- Clear separation between partials and regular content
Regular content files outside shared/partials/ should not use capture blocks, as they are meant to render content directly, not define reusable variables. This validation prevents:
- Misplaced variable definitions in content files
- Confusion about file purpose and behavior
- Accidental capture block usage outside the partials system
Examples
✅ Valid
Single capture block:
{% capture my_variable %}
# Heading
Content goes here.
{% endcapture %}Multiple captures with comments:
<!-- This file defines common callouts -->
{% comment %}Success message{% endcomment %}
{% capture success_msg %}
:::tip
Operation completed successfully!
:::
{% endcapture %}
{% capture error_msg %}
:::warning
An error occurred.
:::
{% endcapture %}Capture with whitespace control:
{%- capture trimmed_content -%}
No extra whitespace before/after
{%- endcapture -%}❌ Invalid
Content outside capture block:
# This heading is not captured
{% capture my_var %}
Captured content
{% endcapture %}Error: Content in shared/partials files must be inside capture blocks.
Duplicate capture names:
{% capture my_variable %}
First definition
{% endcapture %}
{% capture my_variable %}
Duplicate definition
{% endcapture %}Error: Duplicate capture block name "my_variable". This variable already exists in file.
Mixed issues:
Regular paragraph outside capture.
{% capture my_var %}First{% endcapture %}
{% capture my_var %}Duplicate{% endcapture %}Errors:
Content in shared/partials files must be inside capture blocks.Duplicate capture block name "my_var"
❌ Invalid (Files outside shared/partials)
Capture block in regular content file:
# Guide Title
{% capture my_variable %}
Some content
{% endcapture %}
Regular content here.Error: Capture blocks are not allowed in files outside shared/partials folder.
File Scope
This rule applies to all markdown files with different validation rules based on location:
Files in shared/partials/:
- Must use capture blocks for all content
- Must have unique capture block names
/content/shared/partials/common.md✅/docs/shared/partials/alerts.md✅shared/partials/buttons.md✅
Files outside shared/partials/:
- Must not contain capture blocks
/content/guides/example.md✅/shared/snippets/code.md✅docs/tutorials/intro.md✅
Install & build
yarn install && yarn buildTesting
yarn testUsage
In your unified pipeline:
import unified from 'unified';
import parse from 'remark-parse';
import liquidLintPartialsCapture from '@salesforcedevs/sfdocs-liquid-lint-capture';
const processor = unified()
.use(parse)
.use(liquidLintPartialsCapture);
const file = await processor.process(markdownContent);
if (file.messages.length > 0) {
file.messages.forEach(msg => {
console.log(`${msg.line}:${msg.column}: ${msg.message}`);
});
}