![Deno 2.2 Improves Dependency Management and Expands Node.js Compatibility](https://cdn.sanity.io/images/cgdhsj6q/production/97774ea8c88cc8f4bed2766c31994ebc38116948-1664x1366.png?w=400&fit=max&auto=format)
Security News
Deno 2.2 Improves Dependency Management and Expands Node.js Compatibility
Deno 2.2 enhances Node.js compatibility, improves dependency management, adds OpenTelemetry support, and expands linting and task automation for developers.
markdown-proofing
Advanced tools
A markdown proofing platform for individuals, teams, and organizations.
A markdown proofing platform for individuals, teams, and organizations.
Install into your project:
> npm install markdown-proofing
Now, create a .markdown-proofing
JSON file in the root of your project. Here's a simple one using a preset to get started:
{
"presets": ["technical-blog"]
}
Now, run it (may require global npm installation to run directly at command line):
> markdown-proofing ./file1.md
Next, you could wire it up in your package.json
as part of your build (or, perhaps as a lint step, you decide!).
This section is centered around Jekyll, but may work with other static site generators, too!
Jekyll itself doesn't use npm. But, markdown-proofing can still be used!
First, check if a package.json
file exists in the repository root. If one does, great! If not, no problem -- simply create one using npm init
.
After package.json
exists, run npm install markdown-proofing --save-dev
. This assumes you won't need this package available in your production environment.
Then, add or modify the package.json
test
script:
"scripts": {
"test": "markdown-proofing _posts/*.md"
},
Adjust the above as necessary if the posts live in a different place, or if you use a different file extension.
Now, use npm test
to run markdown-proofing on the posts!
Configuration is specified in JSON.
By default .markdown-proofing
located in the root of the project is used. You can optionally specify a different file using the -c
/ --configuration
flags, if you'd like.
The configuration can be as simple as:
{
"presets": ["technical-blog"]
}
Or, a bit more complex:
{
"presets": [],
"analyzers": [
"require-oxford-commas",
"sensitivity",
"sentiment",
"spelling",
"statistics",
"write-good"
],
"rules": {
"missing-oxford-commas": "error",
"sensitivity": "warning",
"sentiment-score": "info",
"sentiment-comparative-score": "info",
"spelling-error": "error",
"statistics-flesch-kincaid-grade-level": "info, warning > 12",
"statistics-flesch-kincaid-reading-ease": "warning <= 40",
"write-good": "info"
}
}
The SpellingAnalyzer
implements markdown-spellcheck. This package uses a .spelling
file for permitting unrecognized text. Only global words are currently supported, though (no file specific words).
markdown-spellcheck also includes an interactive CLI, which you can use to interactively fix spelling and update the .spelling
file as necessary. You may find this useful.
There are two core concepts: Analyzers and Rules.
AnalyzerResult
, which includes a collection of AnalyzerMessage
objects.
AnalyzerMessage
's are { type: String, text: String, line: Number, column: Number }
.'{{message-type}}': '{{condition}}'
.
'statistics-word-count': 'info'
'statistics-flesch-kincaid-reading-ease': 'warning < 40'
info
, warning
, error
, and none
.
info
signals to add this to any output. It should show up in build results and any place where messages should be visible.warning
is a standard warning, it shouldn't fail a build.error
violations should result in a build failure.none
is used to override a preset.warning < 40
-- it's a warning
only when the value is less than 40
.
You can use the following to integrate with Jekyll:
package.json
"scripts": {
"test": "markdown-proofing _posts/*.md",
"proof": "markdown-proofing --color --no-throw --",
"proof:all": "npm run test -- --no-throw",
"proof:latest": "node proofScripts.js latest _posts/*.md",
"proof:changed": "node proofScripts.js git-index-and-uncommitted _posts/*.md",
"proof:index": "node proofScripts.js git-index _posts/*.md",
"proof:uncommitted": "node proofScripts.js git-uncommitted _posts/*.md"
},
"devDependencies": {
"shelljs": "^0.7.0"
}
proofScripts.js
require('shelljs/global');
const arg = process.argv[2];
if (!arg) {
echo('Please specify a proofing instruction argument.');
exit(1);
}
const filePattern = process.argv[3];
if (!filePattern) {
echo('Please specify the file pattern as the last argument.');
exit(1);
}
if (arg === 'latest') {
const orderedPosts = ls('-l', filePattern)
.filter(x => x.name)
.map(x => x.name)
.sort((a, b) => b.localeCompare(a));
if (orderedPosts.length > 0) {
const latestPost = orderedPosts[0];
proof(latestPost);
}
}
else if (arg === 'git-index') {
gitProof(`git diff --name-only --cached ${filePattern}`);
}
else if (arg === 'git-uncommitted') {
gitProof(`git diff --name-only --diff-filter=ACMRT ${filePattern}`);
}
else if (arg === 'git-index-and-uncommitted') {
gitProof([
`git diff --name-only --diff-filter=ACMRT ${filePattern}`,
`git diff --name-only --cached' ${filePattern}`
]);
}
function gitProof(gitDiffPatterns) {
if (!which('git')) {
echo('This script requires git.');
exit(1);
}
if (!Array.isArray(gitDiffPatterns)) {
gitDiffPatterns = [ gitDiffPatterns ];
}
const files = [];
gitDiffPatterns.forEach(x => {
const gitDiffOutput = exec(x, { silent: true });
if (gitDiffOutput.stderr) {
throw new Error(gitDiffOutput.stderr);
}
if (gitDiffOutput.stdout) {
files.push(gitDiffOutput.stdout);
}
});
if (files.length === 0) {
echo('No files to proof.');
exit(0);
}
proof(files);
}
function proof(files) {
if (!Array.isArray(files)) {
files = [ files ];
}
const cmd = `npm run proof ${files.join(' ')}`;
if (exec(cmd).code !== 0) {
echo(`Error while running: ${cmd}`);
exit(1);
}
}
import AnalyzerResult from 'markdown-proofing/analyzer-result'; // TODO: Change this import if this is not correct
export default class MyCustomAnalyzerAnalyzer {
analyze(str) {
const result = new AnalyzerResult();
// As part of the logic, optionally add one or more messages:
result.addMessage('my-custom-analyzer-message-type', 'some-value');
// The return value can be an `AnalyzerResult`
// or a promise to return an `AnalyzerResult`.
return result;
}
}
Then, simply wire it up in configuration as an analyzers
array item:
{
"presets": [
],
"analyzers": [
"path/to/custom-analyzer"
],
"rules": {
"custom-analyzer-message": "info"
}
}
Ritter Insurance Marketing
MIT
Contributions are highly welcome! However, before making large changes that may be outside the scope of this project, we may want to discuss it in an issue prior to opening a pull request.
If you construct an analyzer useful to you and/or your team/company and it could be useful for others, we'd appreciate a pull request to incorporate it into the project!
FAQs
A markdown proofing platform for individuals, teams, and organizations.
We found that markdown-proofing demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Deno 2.2 enhances Node.js compatibility, improves dependency management, adds OpenTelemetry support, and expands linting and task automation for developers.
Security News
React's CRA deprecation announcement sparked community criticism over framework recommendations, leading to quick updates acknowledging build tools like Vite as valid alternatives.
Security News
Ransomware payment rates hit an all-time low in 2024 as law enforcement crackdowns, stronger defenses, and shifting policies make attacks riskier and less profitable.