A structured markdown syntax for iterating on documents with Claude AI
Custom lint rules that flag iteration markers. Integrates with existing linting workflows.
Create .markdownlint/iteration-markers.js:
module.exports = {
names: ["iteration-markers"],
description: "No iteration markers in final documents",
tags: ["iteration"],
function: function rule(params, onError) {
const patterns = [
/%%[^%]*%%/g, // Comments: %% comment %%
/•%%>[^<]*<%%•/g, // Responses: •%%>response <%%•
/==[^=]*\([^)]+\)==/g // Highlights: ==text(TOKEN)==
];
params.lines.forEach((line, index) => {
patterns.forEach(pattern => {
const matches = line.match(pattern);
if (matches) {
matches.forEach(match => {
onError({
lineNumber: index + 1,
detail: `Found iteration marker: ${match}`,
context: line.trim()
});
});
}
});
});
}
};
Configure in .markdownlint.json:
{
"customRules": ["./.markdownlint/iteration-markers.js"]
}
Alternatively, use the built-in regex check:
{
"search-replace": {
"rules": [
{
"name": "no-iteration-comments",
"message": "Remove iteration comment before committing",
"searchPattern": "/%%[^%]*%%/",
"searchScope": "text"
}
]
}
}
Create .eslintrc.js rule:
module.exports = {
rules: {
"no-restricted-syntax": [
"error",
{
selector: "Literal[value=/%%.*%%/]",
message: "Iteration markers should be removed"
}
]
}
};
Create remark-no-iteration-markers.js:
import { lintRule } from 'unified-lint-rule';
import { visit } from 'unist-util-visit';
const rule = lintRule(
'remark-lint:no-iteration-markers',
(tree, file) => {
visit(tree, 'text', (node) => {
if (/%%[^%]*%%/.test(node.value)) {
file.message('Iteration marker found', node);
}
});
}
);
export default rule;
Combine with pre-commit hooks:
# .pre-commit-config.yaml
repos:
- repo: https://github.com/igorshubovych/markdownlint-cli
rev: v0.37.0
hooks:
- id: markdownlint
args: ["--config", ".markdownlint.json"]
{
"scripts": {
"lint:markers": "grep -r -l '%%' --include='*.md' docs/ && exit 1 || exit 0",
"lint": "npm run lint:markers && markdownlint docs/"
}
}