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
84 changes: 84 additions & 0 deletions .markdownlint-cli2.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// https://github.com/DavidAnson/markdownlint

{
"config": {
"default": true,
// heading-style
// Enforces ATX style headings, e.g. ### A level 3 heading
"MD003": {
"style": "atx"
},
// ul-style
// Enforces dash syntax for unordered lists
"MD004": {
"style": "dash"
},
// line-length
// Avoids errors related to line lengths in the MD files
"MD013": {
"code_blocks": false,
"headings": false,
"tables": false,
// Arbitrary length - Revisit to possibly set a standard
"line_length": 9999
},
// no-trailing-punctuation
// Prevents most punctuation in headings, except for exclamation and question marks
"MD026": {
"punctuation": ".:,;"
},
// ol-prefix
// Enforces lazy numbering for ordered lists
"MD029": {
"style": "one"
},
// no-inline-html
// Only allows specified HTML to be inline
"MD033": {
"allowed_elements": [
"p",
"a",
"div",
"span",
"kbd",
"script",
"iframe",
"details",
"summary",
"pre"
]
},
// first-line-heading/first-line-h1
// Enforces the first heading on a lesson page to be an H3, since the page template renders an H1 and H2 automatically
"MD041": {
"level": 3
},
// proper-names
// Enforces proper spelling of the names array, except for code blocks and HTML elements
"MD044": {
"code_blocks": false,
"html_elements": false,
"names": ["CSS", "HTML", "JavaScript"]
},
// code-block-style
// Prevents indented code blocks from being used
"MD046": {
"style": "fenced"
},
// code-fence-style
// Enforces backticks for codeblocks
"MD048": {
"style": "backtick"
},
// emphasis-style
// Enforces asterisk syntax instead of underscore syntax
"MD049": {
"style": "asterisk"
},
// strong-style
// Enforces asterisk syntax instead of underscore syntax
"MD050": {
"style": "asterisk"
}
}
}
13 changes: 13 additions & 0 deletions app/components/markdown/preview_component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,19 @@
<%= render ContentContainerComponent.new(classes: 'pt-6') do %>
<% if markdown.present? %>
<%= sanitize MarkdownConverter.new(markdown).as_html, tags: allowed_tags, attributes: allowed_attributes %>

<% if lint.any? %>
<div class="lesson-note lesson-note--critical" markdown="1">
<h4>The linter has detected issues with this preview</h4>
<p>Below are a list of potential issues with your preview. If you intend to create a pull request with this markdown, these warnings may appear later on in the pull request!</p>
</div>

<ul class="list-none">
<% for err in @lint_errors %>
<li class="m-0"><%= inline_svg_tag 'icons/flag.svg', class: '-ml-0.5 mr-2 h-4 w-4 text-orange-500 dark:text-orange-400 inline', aria: true, title: 'Warning' %><%= err %></li>
<% end %>
</ul>
<% end %>
<% else %>
<p>Nothing to preview yet!</p>
<% end %>
Expand Down
14 changes: 14 additions & 0 deletions app/components/markdown/preview_component.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
class Markdown::PreviewComponent < ApplicationComponent
def initialize(markdown: '')
@markdown = markdown
@lint_errors = []
end

def lint
File.write('markdown_to_lint.md', @markdown)
results = `markdownlint-cli2 markdown_to_lint.md 2>&1`
File.delete('markdown_to_lint.md')

@lint_errors = results.split("\n").drop(4)
@lint_errors.each_with_index do |err, i|
@lint_errors[i] = err.split.drop(2).join(' ')
end

@lint_errors
end

def allowed_tags
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"eslint": "eslint --max-warnings 0 './app/javascript/**/*.js'",
"build:css": "npm-run-all --parallel \"build:css:* {@}\" --",
"build:css:application": "postcss ./app/assets/stylesheets/application.postcss.css -o ./app/assets/builds/application.css",
"build:css:active_admin": "sass ./app/assets/stylesheets/active_admin.scss ./app/assets/builds/active_admin.css --no-source-map --load-path=node_modules --style=compressed"
"build:css:active_admin": "sass ./app/assets/stylesheets/active_admin.scss ./app/assets/builds/active_admin.css --no-source-map --load-path=node_modules --style=compressed",
"postinstall": "npm install -g markdownlint-cli2"
},
"dependencies": {
"@activeadmin/activeadmin": "^3.2.0",
Expand Down Expand Up @@ -40,6 +41,7 @@
"hint.css": "^3.0.0",
"js-base64": "^3.7.5",
"lodash": "^4.17.21",
"markdownlint-cli2": "^0.13.0",
"mermaid": "^9.4.3",
"mini-css-extract-plugin": "^2.8.1",
"npm-run-all": "^4.1.5",
Expand Down
44 changes: 44 additions & 0 deletions spec/services/markdown/preview_component_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
require 'rails_helper'
require './lib/kramdown/document_sections'

RSpec.describe Markdown::PreviewComponent do
describe '#lint' do
it 'lints the markdown' do
sample_markdown = <<~MARKDOWN
### First section header
some content

### Second section header
some content

### Third section header
some content
MARKDOWN

expect(described_class.new(markdown: sample_markdown).lint.any?).to be true
end

context 'when no issues present' do
it 'lints the markdown and returns an empty array' do
sample_markdown = <<~MARKDOWN
### First section header

some content
MARKDOWN

expect(described_class.new(markdown: sample_markdown).lint.any?).to be false
end
end

context 'when no empty line is present under the header' do
it 'detects it in the linter' do
sample_markdown = <<~MARKDOWN
### First section header
some content
MARKDOWN

expect(described_class.new(markdown: sample_markdown).lint.first).to include 'surrounded by blank lines'
end
end
end
end
77 changes: 73 additions & 4 deletions yarn.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.