Skip to content

Commit

Permalink
Merge pull request #156 from TheNorthMemory/setup-github-workflows-ci
Browse files Browse the repository at this point in the history
Wellformed the table's rowspan and/or colspan attributes
  • Loading branch information
arve0 authored Dec 1, 2024
2 parents 80a8e52 + 9ae0c33 commit 1963653
Show file tree
Hide file tree
Showing 9 changed files with 1,354 additions and 304 deletions.
31 changes: 31 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: ci

on: [push, pull_request]

jobs:
test:
name: ${{ matrix.node-version }} on ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
node-version: [16.x, 18.x, 20.x, 22.x]
os: [ubuntu-latest, macOS-latest, windows-latest]
runs-on: ${{ matrix.os }}

steps:
- if: runner.os == 'Windows'
shell: bash
run: |
git config --global core.autocrlf false
git config --global core.symlinks true
- uses: actions/checkout@v4
with:
show-progress: false
- name: v${{ matrix.node-version }} on ${{ matrix.os }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
architecture: 'x64'
cache: 'npm'
- run: npm ci
- run: npm test
5 changes: 5 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,9 @@
/.travis.yml
/.eslintignore
/.eslintrc.js
/.eslintrc.json
/.editorconfig
/.gitignore
/.github
/.devcontainer
/debug.js
42 changes: 41 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# markdown-it-attrs [![Build Status](https://travis-ci.org/arve0/markdown-it-attrs.svg?branch=master)](https://travis-ci.org/arve0/markdown-it-attrs) [![npm version](https://badge.fury.io/js/markdown-it-attrs.svg)](http://badge.fury.io/js/markdown-it-attrs) [![Coverage Status](https://coveralls.io/repos/github/arve0/markdown-it-attrs/badge.svg?branch=master)](https://coveralls.io/github/arve0/markdown-it-attrs?branch=master) <!-- omit in toc -->
# markdown-it-attrs [![GitHub actions](https://github.com/arve0/markdown-it-attrs/workflows/ci/badge.svg)](https://github.com/arve0/markdown-it-attrs/actions) [![npm version](https://badge.fury.io/js/markdown-it-attrs.svg)](http://badge.fury.io/js/markdown-it-attrs) [![Coverage Status](https://coveralls.io/repos/github/arve0/markdown-it-attrs/badge.svg?branch=master)](https://coveralls.io/github/arve0/markdown-it-attrs?branch=master) <!-- omit in toc -->

Add classes, identifiers and attributes to your markdown with `{.class #identifier attr=value attr2="spaced value"}` curly brackets, similar to [pandoc's header attributes](http://pandoc.org/README.html#extension-header_attributes).

Expand Down Expand Up @@ -250,6 +250,46 @@ Output:
</table>
```

Wellformed the table's _rowspan_ and/or _colspan_ attributes, usage sample below:
```md
| A | B | C | D |
| ----------------------- | --- | --- | ---------------- |
| 1 | 11 | 111 | 1111 {rowspan=3} |
| 2 {colspan=2 rowspan=2} | 22 | 222 | 2222 |
| 3 | 33 | 333 | 3333 |

{border=1}
```

Output:
```html
<table border="1">
<thead>
<tr>
<th>A</th>
<th>B</th>
<th>C</th>
<th>D</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>11</td>
<td>111</td>
<td rowspan="3">1111</td>
</tr>
<tr>
<td colspan="2" rowspan="2">2</td>
<td>22</td>
</tr>
<tr>
<td>3</td>
</tr>
</tbody>
</table>
```

If you need finer control, [decorate](https://github.com/rstacruz/markdown-it-decorate) might help you.

## Custom rendering
Expand Down
75 changes: 70 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,75 @@

const patternsConfig = require('./patterns.js');

/**
* @typedef {import('markdown-it')} MarkdownIt
*
* @typedef {import('markdown-it/lib/rules_core/state_core.mjs').default} StateCore
*
* @typedef {import('markdown-it/lib/token.mjs').default} Token
*
* @typedef {import('markdown-it/lib/token.mjs').Nesting} Nesting
*
* @typedef {Object} Options
* @property {!string} leftDelimiter left delimiter, default is `{`(left curly bracket)
* @property {!string} rightDelimiter right delimiter, default is `}`(right curly bracket)
* @property {AllowedAttribute[]} allowedAttributes empty means no limit
*
* @typedef {string|RegExp} AllowedAttribute rule of allowed attribute
*
* @typedef {[string, string]} AttributePair
*
* @typedef {[number, number]} SourceLineInfo
*
* @typedef {Object} CurlyAttrsPattern
* @property {string} name
* @property {DetectingRule[]} tests
* @property {(tokens: Token[], i: number, j?: number) => void} transform
*
* @typedef {Object} MatchedResult
* @property {boolean} match true means matched
* @property {number?} j postion index number of Array<{@link Token}>
*
* @typedef {(str: string) => boolean} DetectingStrRule
*
* @typedef {Object} DetectingRule rule for testing {@link Token}'s properties
* @property {number=} shift offset index number of Array<{@link Token}>
* @property {number=} position fixed index number of Array<{@link Token}>
* @property {(string | DetectingStrRule)=} type
* @property {(string | DetectingStrRule)=} tag
* @property {DetectingRule[]=} children
* @property {(string | DetectingStrRule)=} content
* @property {(string | DetectingStrRule)=} markup
* @property {(string | DetectingStrRule)=} info
* @property {Nesting=} nesting
* @property {number=} level
* @property {boolean=} block
* @property {boolean=} hidden
* @property {AttributePair[]=} attrs
* @property {SourceLineInfo[]=} map
* @property {any=} meta
*/

/** @type {Options} */
const defaultOptions = {
leftDelimiter: '{',
rightDelimiter: '}',
allowedAttributes: []
};

/**
* @param {MarkdownIt} md
* @param {Options=} options_
*/
module.exports = function attributes(md, options_) {
let options = Object.assign({}, defaultOptions);
options = Object.assign(options, options_);

const patterns = patternsConfig(options);

/**
* @param {StateCore} state
*/
function curlyAttrs(state) {
const tokens = state.tokens;

Expand Down Expand Up @@ -43,12 +100,13 @@ module.exports = function attributes(md, options_) {
/**
* Test if t matches token stream.
*
* @param {array} tokens
* @param {Token[]} tokens
* @param {number} i
* @param {object} t Test to match.
* @return {object} { match: true|false, j: null|number }
* @param {DetectingRule} t
* @returns {MatchedResult}
*/
function test(tokens, i, t) {
/** @type {MatchedResult} */
const res = {
match: false,
j: null // position of child
Expand Down Expand Up @@ -78,7 +136,9 @@ function test(tokens, i, t) {
return res;
}
let match;
/** @type {DetectingRule[]} */
const childTests = t.children;
/** @type {Token[]} */
const children = token.children;
if (childTests.every(tt => tt.position !== undefined)) {
// positions instead of shifts, do not loop all children
Expand Down Expand Up @@ -141,14 +201,19 @@ function isArrayOfFunctions(arr) {
/**
* Get n item of array. Supports negative n, where -1 is last
* element in array.
* @param {array} arr
* @param {Token[]} arr
* @param {number} n
* @returns {Token=}
*/
function get(arr, n) {
return n >= 0 ? arr[n] : arr[arr.length + n];
}

// get last element of array, safe - returns {} if not found
/**
* get last element of array, safe - returns {} if not found
* @param {DetectingRule[]} arr
* @returns {DetectingRule}
*/
function last(arr) {
return arr.slice(-1)[0] || {};
}
Loading

0 comments on commit 1963653

Please sign in to comment.