imdone-core 1.53.14 → 1.53.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -4
- package/lib/adapters/parsers/content-transformer.js +80 -14
- package/lib/adapters/parsers/task/CheckStyleTaskParser.js +1 -1
- package/lib/adapters/parsers/task/TaskParser.js +5 -0
- package/lib/card.js +1 -0
- package/lib/file.js +11 -0
- package/lib/plugins/default-board-properties-plugin.js +24 -1
- package/lib/project.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -197,11 +197,9 @@ License
|
|
|
197
197
|
[travis-image]: https://img.shields.io/travis/imdone/imdone-core/master.svg?label=linux
|
|
198
198
|
[travis-url]: https://travis-ci.org/imdone/imdone-core
|
|
199
199
|
|
|
200
|
-
<!--
|
|
201
|
-
- #BACKLOG:-550 As a vscode user I would like to see the imdone board in vscode so I can get shit done! ic:gh gh:132 id:30 +enhancement
|
|
200
|
+
<!-- # #NOTE Notes
|
|
202
201
|
|
|
203
|
-
|
|
204
|
-
# #NOTE Notes
|
|
202
|
+
**Package Version {{version}}**
|
|
205
203
|
|
|
206
204
|
[Focus]({{getFilterURL('list = DOING or tags = focus')}})
|
|
207
205
|
[Plan]({{getFilterURL(' ')}})
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const template = require('lodash.template')
|
|
2
|
+
const uuid = require('uuid'); // Ensure you have uuid installed: npm install uuid
|
|
2
3
|
|
|
3
4
|
module.exports = {
|
|
4
5
|
format,
|
|
@@ -8,27 +9,92 @@ function removeDisplayComments(description) {
|
|
|
8
9
|
return description.replace(/<!--\s*\[([\s\S]*?)\]\s*-->/g, '$1')
|
|
9
10
|
}
|
|
10
11
|
|
|
12
|
+
function escapeCodeBlocks(content) {
|
|
13
|
+
const codeBlockRegex = /(```[\s\S]*?```|`[^`]*`)/g
|
|
14
|
+
let codeBlocks = []
|
|
15
|
+
|
|
16
|
+
// Replace code blocks with unique keys
|
|
17
|
+
content = content.replace(codeBlockRegex, (match) => {
|
|
18
|
+
const key = `__CODE_BLOCK_${codeBlocks.length}__`
|
|
19
|
+
codeBlocks.push(match) // Maintain order
|
|
20
|
+
return key
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
return { content, codeBlocks }
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function restoreCodeBlocks(content, codeBlocks) {
|
|
27
|
+
// Restore code blocks in order using stored array
|
|
28
|
+
codeBlocks.forEach((code, index) => {
|
|
29
|
+
content = content.replace(`__CODE_BLOCK_${index}__`, code)
|
|
30
|
+
})
|
|
31
|
+
return content
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Interpolates the content with the provided data.
|
|
36
|
+
* @param {string} content - The content to interpolate.
|
|
37
|
+
* @param {object} data - The data to use for interpolation.
|
|
38
|
+
* @param {object} opts - The options for interpolation.
|
|
39
|
+
* @returns {object} - The interpolated content, whether there was interpolation, and error tokens.
|
|
40
|
+
*/
|
|
41
|
+
function interpolate(content, data, opts) {
|
|
42
|
+
const errorTokens = {};
|
|
43
|
+
let hasInterpolation = false;
|
|
44
|
+
|
|
45
|
+
content = content.replace(opts.interpolate, (match, p1) => {
|
|
46
|
+
try {
|
|
47
|
+
const result = template(match, opts)(data);
|
|
48
|
+
if (result !== match) {
|
|
49
|
+
hasInterpolation = true;
|
|
50
|
+
}
|
|
51
|
+
return result;
|
|
52
|
+
} catch (e) {
|
|
53
|
+
const token = `__ERROR_TOKEN_${uuid.v4()}__`;
|
|
54
|
+
errorTokens[token] = match;
|
|
55
|
+
return token;
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
return { content, hasInterpolation, errorTokens };
|
|
60
|
+
}
|
|
61
|
+
|
|
11
62
|
function format(content, data, mustache) {
|
|
12
|
-
const opts = { interpolate: /(?<![`\\])\${([\s\S]+?)}/g }
|
|
63
|
+
const opts = { interpolate: /(?<![`\\])\${([\s\S]+?)}/g };
|
|
64
|
+
const errorTokens = {};
|
|
65
|
+
|
|
66
|
+
if (mustache) content = removeDisplayComments(content);
|
|
67
|
+
|
|
68
|
+
// Escape code blocks before processing interpolation
|
|
69
|
+
const { content: escapedContent, codeBlocks } = escapeCodeBlocks(content);
|
|
13
70
|
|
|
14
|
-
|
|
71
|
+
let result = escapedContent;
|
|
72
|
+
let hasInterpolation = true;
|
|
15
73
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
74
|
+
while (hasInterpolation) {
|
|
75
|
+
const interpolationResult = interpolate(result, data, opts);
|
|
76
|
+
result = interpolationResult.content;
|
|
77
|
+
hasInterpolation = interpolationResult.hasInterpolation;
|
|
78
|
+
Object.assign(errorTokens, interpolationResult.errorTokens);
|
|
21
79
|
}
|
|
22
80
|
|
|
23
81
|
if (mustache) {
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
82
|
+
const mustacheOpts = { interpolate: /(?<!`){{([\s\S]+?)}}/g };
|
|
83
|
+
hasInterpolation = true;
|
|
84
|
+
while (hasInterpolation) {
|
|
85
|
+
const interpolationResult = interpolate(result, data, mustacheOpts);
|
|
86
|
+
result = interpolationResult.content;
|
|
87
|
+
hasInterpolation = interpolationResult.hasInterpolation;
|
|
88
|
+
Object.assign(errorTokens, interpolationResult.errorTokens);
|
|
30
89
|
}
|
|
31
90
|
}
|
|
32
91
|
|
|
33
|
-
|
|
92
|
+
result = restoreCodeBlocks(result, codeBlocks);
|
|
93
|
+
|
|
94
|
+
// Restore error tokens
|
|
95
|
+
Object.keys(errorTokens).forEach(token => {
|
|
96
|
+
result = result.replace(new RegExp(token, 'g'), errorTokens[token]);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
return result;
|
|
34
100
|
}
|
|
@@ -28,6 +28,11 @@ module.exports = class TaskParser {
|
|
|
28
28
|
const re = new RegExp(this.pattern)
|
|
29
29
|
const result = re.exec(lineContent)
|
|
30
30
|
const parseResult = result && this.parse(lineContent, line, result, task)
|
|
31
|
+
|
|
32
|
+
if (parseResult && this.config.lists && !this.config.listExists(parseResult.list)) {
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
|
|
31
36
|
return parseResult && new Task(parseResult)
|
|
32
37
|
}
|
|
33
38
|
}
|
package/lib/card.js
CHANGED
package/lib/file.js
CHANGED
|
@@ -206,6 +206,11 @@ File.parseDeferDate = function (config, text) {
|
|
|
206
206
|
}
|
|
207
207
|
|
|
208
208
|
File.parseDate = function (config, text, dateType) {
|
|
209
|
+
// TODO Add the ability to set multiple reminders
|
|
210
|
+
// #imdone-1.54.0
|
|
211
|
+
// <!--
|
|
212
|
+
// order:-150
|
|
213
|
+
// -->
|
|
209
214
|
if (text.includes(`${dateType}${config.getMetaSep()}`)) return text
|
|
210
215
|
let dateString
|
|
211
216
|
return text.replace(new RegExp(`(\\s${dateType})\\s.*?\\.`,'gi'), (match, p1) => {
|
|
@@ -597,6 +602,12 @@ File.prototype.deleteDescription = function (task, config) {
|
|
|
597
602
|
this.modifyDescription(task, config)
|
|
598
603
|
}
|
|
599
604
|
|
|
605
|
+
// TODO This isn't deleting all the newlines at the end of each line in code files
|
|
606
|
+
// <!--
|
|
607
|
+
// #bug
|
|
608
|
+
// #imdone-1.54.0
|
|
609
|
+
// order:-165
|
|
610
|
+
// -->
|
|
600
611
|
File.prototype.deleteCodeOrHashTask = function (re, task, config) {
|
|
601
612
|
var log = require('debug')('delete-task:deleteCodeOrHashTask')
|
|
602
613
|
var self = this
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
const Plugin = require('imdone-api')
|
|
2
2
|
const {getIsoDateWithOffset} = require('../adapters/date-time')
|
|
3
3
|
const path = require('path')
|
|
4
|
+
|
|
4
5
|
const simpleTemplate = '\n<!--\ncreated:${timestamp}\n-->\n'
|
|
5
6
|
|
|
7
|
+
const codeSpan = (value) => '`' + value + '`';
|
|
8
|
+
const codeBlock = (value, language = '') => '```' + language + '\n' + value + '\n```';
|
|
9
|
+
|
|
6
10
|
function flattenObject(object) {
|
|
7
11
|
return Object.keys(object).reduce((acc, key) => {
|
|
8
12
|
return { ...acc, [`template_${key}`]: object[key] };
|
|
@@ -24,10 +28,29 @@ module.exports = class DefaultBoardPropertiesPlugin extends Plugin {
|
|
|
24
28
|
const clearFilterURL = this.getFilterURL('');
|
|
25
29
|
const getFilterURL = (filter) => this.getFilterURL(filter);
|
|
26
30
|
const getFilterLink = (filter) => `[Filter By: ${filter}](${this.getFilterURL(filter)})`;
|
|
27
|
-
|
|
31
|
+
// DOING Make board properties self documenting
|
|
32
|
+
// <!--
|
|
33
|
+
// #imdone-1.53.16
|
|
34
|
+
// #feature
|
|
35
|
+
// created:2025-02-14T16:54:22-05:00
|
|
36
|
+
// -->
|
|
37
|
+
// [Feature Description]
|
|
38
|
+
// ## :ballot_box_with_check: Tasks
|
|
39
|
+
// - [ ] Add tasks here
|
|
40
|
+
// ## :white_check_mark: DoD
|
|
41
|
+
// - [ ] Code complete (No Tech Debt)
|
|
42
|
+
// - [ ] Update tests
|
|
43
|
+
// - [ ] Automate what's working
|
|
44
|
+
// - [ ] Update tutorial project
|
|
45
|
+
// - [ ] Update documentation
|
|
46
|
+
// - [ ] Run like a new user and make the experience better
|
|
47
|
+
// - [ ] Make sure the first card is expanded by default or in view mode
|
|
48
|
+
// - [ ] Make sure global and default settings isn't modified when opened for the first time
|
|
28
49
|
return {
|
|
29
50
|
date: `${getIsoDateWithOffset(new Date()).substring(0, 10)}`,
|
|
30
51
|
timestamp: getIsoDateWithOffset(new Date()),
|
|
52
|
+
codeSpan,
|
|
53
|
+
codeBlock,
|
|
31
54
|
clearFilterURL,
|
|
32
55
|
getFilterURL,
|
|
33
56
|
getFilterLink,
|
package/lib/project.js
CHANGED