imdone-core 1.50.2 → 1.50.4

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.
@@ -1,32 +1,80 @@
1
1
  const checkbox = require('markdown-it-checkbox')
2
2
  const imageSize = require('markdown-it-imsize')
3
- const emoji = require('markdown-it-emoji') // used in taskEditor
3
+ const emoji = require('markdown-it-emoji')
4
4
  const mark = require('markdown-it-mark')
5
- const removeMD = require('remove-markdown') // used in epic-plugins
5
+ const removeMD = require('remove-markdown')
6
6
  const wikilinks = require('@kwvanderlinde/markdown-it-wikilinks')
7
+ const path = require('path');
7
8
 
8
9
  const MarkdownIt = require('markdown-it')
9
- const md = new MarkdownIt({html: true, breaks: true})
10
-
11
- md.use(checkbox)
12
- .use(mark)
13
- .use(emoji)
14
- .use(imageSize)
15
- .use(wikilinks(
16
- {
17
- linkPattern: /\[\[([\w\u00C0-\u017F\s\d-/]+)(\|([\w\u00C0-\u017F\s\d-/]+))?\]\]/,
18
- uriSuffix: '.md',
19
- postProcessPageName (pagename) {
20
- return pagename.trim()
10
+ let _platform = process.platform
11
+
12
+ function getRenderer(projectPath) {
13
+ const md = new MarkdownIt({html: true, breaks: true})
14
+
15
+ md.use(checkbox)
16
+ .use(mark)
17
+ .use(emoji)
18
+ .use(imageSize)
19
+ .use(wikilinks(
20
+ {
21
+ linkPattern: /\[\[([\w\u00C0-\u017F\s\d-/]+)(\|([\w\u00C0-\u017F\s\d-/]+))?\]\]/,
22
+ uriSuffix: '.md',
23
+ postProcessPageName (pagename) {
24
+ return pagename.trim()
25
+ }
21
26
  }
27
+ ))
28
+ .use(replaceImagePaths(projectPath))
29
+ .validateLink = () => true
30
+
31
+ return md
32
+ }
33
+
34
+ function replaceImagePaths(projectPath) {
35
+
36
+ return function(md) {
37
+ const defaultRender = md.renderer.rules.image || function(tokens, idx, options, env, self) {
38
+ return self.renderToken(tokens, idx, options);
39
+ };
40
+
41
+ md.renderer.rules.image = function(tokens, idx, options, env, self) {
42
+ const token = tokens[idx];
43
+ const srcIndex = token.attrIndex('src');
44
+
45
+ if (srcIndex >= 0) {
46
+ const src = token.attrs[srcIndex][1];
47
+ if (!src.startsWith('http')) {
48
+ const filePath = projectPath ? path.join(projectPath, src) : path.resolve(src);
49
+ const fileUrl = pathToFileURL(filePath);
50
+ token.attrs[srcIndex][1] = fileUrl;
51
+ }
52
+ }
53
+
54
+ return defaultRender(tokens, idx, options, env, self);
55
+ };
56
+ }
57
+ }
58
+
59
+ function pathToFileURL(absolutePath) {
60
+ if (_platform === 'win32') {
61
+ absolutePath = '/' + absolutePath.replace(/\\/g, '/');
22
62
  }
23
- ))
24
- .validateLink = () => true
63
+ return `file://${absolutePath}`;
64
+ }
65
+
66
+ function renderCancelledTasks(markdown) {
67
+ return markdown.replace(/- \[-\] (.+)/gm, '- :no_entry_sign: ~~$1~~');
68
+ }
25
69
 
26
70
  module.exports = {
27
- renderMarkdown (markdown) {
28
- markdown = markdown.replace(/- \[-\] (.+)/gm, '- :no_entry_sign: ~~$1~~');
29
- return md.render(markdown)
71
+ _setPlatform(platform) {
72
+ _platform = platform
73
+ },
74
+ renderMarkdown (markdown, projectPath) {
75
+ const md = getRenderer()
76
+ markdown = renderCancelledTasks(markdown)
77
+ return getRenderer(projectPath).render(markdown)
30
78
  },
31
79
  removeMD
32
- }
80
+ }
@@ -5,7 +5,8 @@ const languages = require('../../../languages')
5
5
  const ReadStreamCodeParser = require('./ReadStreamCodeParser')
6
6
 
7
7
 
8
- function getLang(languages, filePath) {
8
+ function getLang(config, filePath) {
9
+ const languages = getLanguages(config)
9
10
  var lang = languages[path.extname(filePath)]
10
11
  return lang || { name: 'text', symbol: '' }
11
12
  }
@@ -15,13 +16,12 @@ function getLanguages(config) {
15
16
  return { ...languages, ...configLanguages }
16
17
  }
17
18
 
18
-
19
+ module.exports.getLang = getLang
19
20
  module.exports.getFileParser = async function getFileParser (filePath, config, readStream) {
20
21
  if (!readStream) {
21
22
  readStream = createReadStream(filePath)
22
23
  }
23
- const languages = getLanguages(config)
24
- const lang = getLang(languages, filePath)
24
+ const lang = getLang(config, filePath)
25
25
  if (lang.name === 'text') {
26
26
  return new ReadStreamMarkdownParser(readStream, config)
27
27
  } else {
@@ -33,7 +33,7 @@ module.exports = class ReadStreamCodeParser extends ReadStreamTaskParser {
33
33
  Object.keys(comments).forEach((comment) => {
34
34
  const { begin, end, content } = comments[comment];
35
35
  const line = begin;
36
- const lastLine = end - 1;
36
+ const lastLine = end; // DOING: lastLine should not be - 1
37
37
  const lines = content.split('\n');
38
38
 
39
39
  // Check if the comment contains "TODO"
@@ -89,17 +89,12 @@ module.exports = class ReadStreamTaskParser {
89
89
 
90
90
  trimLinesToEndTask() {
91
91
  if (!this.task) return
92
- if (
93
- this.blankLines == blankLinesToEndTask
94
- ) {
95
- this.task.description.length = this.task.description.length - (this.blankLines - 1)
96
- } else if (this.nextTask){
97
- this.task.description.length = this.task.description.length - (this.blankLines + 1)
98
- } else {
99
- this.task.description.length = this.task.description.length - this.blankLines
100
- }
101
92
 
102
- this.task.lastLine = this.task.line + this.task.description.length - 1
93
+ // Remove the empty strings from the end of the task description
94
+ while (this.task.description[this.task.description.length - 1] === '') {
95
+ this.task.description.pop()
96
+ }
97
+ this.task.lastLine = this.task.line + this.task.description.length
103
98
  }
104
99
 
105
100
  close() {
@@ -38,7 +38,7 @@ async function getYamlConfig(filePath) {
38
38
  if (configLike.watcher) delete configLike.watcher
39
39
 
40
40
  } catch (e) {
41
- /* noop */
41
+ console.error(`Error parsing config file: ${filePath}`)
42
42
  }
43
43
  return configLike
44
44
  }
package/lib/card.js CHANGED
@@ -10,7 +10,7 @@ const eol = require('eol')
10
10
  const allEmoji = require('markdown-it-emoji/lib/data/full.json')
11
11
  const { getIsoDateWithOffset } = require('./adapters/date-time')
12
12
 
13
- const { removeMD, renderMarkdown } = require('./adapters/markdown')
13
+ const { removeMD } = require('./adapters/markdown')
14
14
 
15
15
  const CONTENT_TOKEN = '__CONTENT__'
16
16
  const lf = String(eol.lf)
@@ -250,7 +250,7 @@ module.exports = function newCard(task, _project, dontParse) {
250
250
  .replace(/%%[\s\S]*?%%/g, '')
251
251
  .replace(/<\!--\s*?-->/gs, '')
252
252
  .trim()
253
- taskMD = this.replaceImagePaths(taskMD)
253
+ // taskMD = this.replaceImagePaths(taskMD)
254
254
  // - Split on eol and append lines until visible line count equals lines
255
255
  const displayContent = []
256
256
  const rawContent = []
@@ -271,28 +271,28 @@ module.exports = function newCard(task, _project, dontParse) {
271
271
  return { totalLines, markdown, rawMarkdown }
272
272
  }
273
273
 
274
- replaceImagePaths(content) {
275
- return content.replace(
276
- /(!\[.*?\]\()(.*?)(\))/g,
277
- (match, p1, imagePath, p3) => {
278
- if (/^http/.test(imagePath)) return match
279
- imagePath = _path.join(
280
- _path.dirname(this.fullPath),
281
- imagePath
282
- ).replace(/ /g, '%20')
283
- const imageURL = `file://${imagePath}`
284
- return p1 + imageURL + p3
285
- }
286
- )
287
- }
274
+ // replaceImagePaths(content) {
275
+ // return content.replace(
276
+ // /(!\[.*?\]\()(.*?)(\))/g,
277
+ // (match, p1, imagePath, p3) => {
278
+ // if (/^http/.test(imagePath)) return match
279
+ // imagePath = _path.join(
280
+ // _path.dirname(this.fullPath),
281
+ // imagePath
282
+ // ).replace(/ /g, '%20')
283
+ // const imageURL = `file://${imagePath}`
284
+ // return p1 + imageURL + p3
285
+ // }
286
+ // )
287
+ // }
288
288
 
289
289
  getHtml(content) {
290
- const html = renderMarkdown(content)
290
+ const html = project.renderMarkdown(content)
291
291
  const mdArray = eol.split(content)
292
292
  let truncHtml = null
293
293
  if (mdArray.length > this.truncLines) {
294
294
  mdArray.length = this.truncLines
295
- truncHtml = renderMarkdown(mdArray.join(eol.lf))
295
+ truncHtml = project.renderMarkdown(mdArray.join(eol.lf))
296
296
  }
297
297
  return { html, truncHtml }
298
298
  }
package/lib/config.js CHANGED
@@ -6,16 +6,7 @@ const _get = require('lodash.get')
6
6
  const {
7
7
  JOURNAL_TYPE,
8
8
  DEFAULT_CONFIG,
9
- CONFIG_FILE_YML,
10
- CONFIG_DIR
11
9
  } = require('./constants')
12
- const _path = require('path')
13
- const findUp = require('find-up')
14
- const { loadYAML } = require('./adapters/yaml')
15
- const {
16
- exists,
17
- readFile,
18
- } = require('./adapters/file-gateway')
19
10
 
20
11
  /**
21
12
  * Description
@@ -1,6 +1,7 @@
1
1
  const { loadYAML } = require('./adapters/yaml')
2
2
 
3
3
  const defaultSettingsString = `openIn: default #override
4
+ openCodeIn: default #override
4
5
  journalType: New File
5
6
  journalPath: imdone-tasks #override
6
7
  appendNewCardsTo: imdone-tasks.md
@@ -1,5 +1,3 @@
1
- // const removeMD = require('remove-markdown')
2
- const { renderMarkdown } = require('../adapters/markdown')
3
1
  const Plugin = require('imdone-api')
4
2
 
5
3
  function getIsEpicMeta(task) {
@@ -161,7 +159,7 @@ module.exports = class EpicPlugin extends Plugin {
161
159
  content += '<ul style="list-style: none;">'
162
160
  content += tasks
163
161
  .map((task) => {
164
- const taskText = renderMarkdown(task.text).replaceAll(/<p>|<\/p>/ig, '') // removeMD(task.text)
162
+ const taskText = this.project.renderMarkdown(task.text).replaceAll(/<p>|<\/p>/ig, '') // removeMD(task.text)
165
163
  const checked =
166
164
  task.list === this.project.doneList ? ' checked="true"' : ''
167
165
  const taskFilePath = encodeURI(
package/lib/project.js CHANGED
@@ -787,6 +787,6 @@ module.exports = class WorkerProject extends Project {
787
787
  }
788
788
 
789
789
  renderMarkdown(content) {
790
- return renderMarkdown(content)
790
+ return renderMarkdown(content, this.path)
791
791
  }
792
792
  }
package/lib/repository.js CHANGED
@@ -1573,16 +1573,46 @@ Repository.deserialize = function (repo, cb) {
1573
1573
  }
1574
1574
 
1575
1575
  Repository.regexQuery = function (tasks, queryString) {
1576
- return tasks.map((task) => {
1577
- const match = task.content.match(new RegExp(tools.escapeRegExp(queryString), 'i'))
1578
- task.match = match
1579
- if (match && queryString.trim() && task.interpretedContent) {
1580
- task.interpretedContent = task.interpretedContent.replace(new RegExp(`(${tools.escapeRegExp(queryString.trim())})`, 'gi'), '==$1==' )
1581
- task.updateDescriptionData()
1582
- }
1583
- return task
1584
- }).filter(({match}) => match)
1585
- }
1576
+ return tasks
1577
+ .map((task) => {
1578
+ const escapedQueryString = tools.escapeRegExp(queryString.trim());
1579
+
1580
+ // Regex to match occurrences not part of a URL and not already surrounded by `==`
1581
+ const regex = new RegExp(
1582
+ `(?<!https?:\\/\\/[^\\s]*?)\\b${escapedQueryString}\\b(?![^\\s]*\\/)(?<!==)(?!==)`,
1583
+ 'gi'
1584
+ );
1585
+
1586
+ // Regex to detect Markdown links `[title](url)` where `queryString` is in title or URL
1587
+ const markdownLinkRegex = new RegExp(
1588
+ `\\[([^\\]]*${escapedQueryString}[^\\]]*)\\]\\(([^)]+${escapedQueryString}[^)]*)\\)`,
1589
+ 'gi'
1590
+ );
1591
+
1592
+ let match = task.content.match(regex) || task.content.match(markdownLinkRegex);
1593
+ task.match = match;
1594
+
1595
+ if (match && queryString.trim() && task.interpretedContent) {
1596
+ // Replace standalone occurrences
1597
+ task.interpretedContent = task.interpretedContent.replace(
1598
+ regex,
1599
+ '==$&=='
1600
+ );
1601
+
1602
+ // Replace Markdown links where queryString is in title or URL
1603
+ task.interpretedContent = task.interpretedContent.replace(
1604
+ markdownLinkRegex,
1605
+ (match) => `==${match}==`
1606
+ );
1607
+
1608
+ task.updateDescriptionData();
1609
+ }
1610
+
1611
+ return task;
1612
+ })
1613
+ .filter(({ match }) => match);
1614
+ };
1615
+
1586
1616
 
1587
1617
  Repository.parseSortFromQueryString = function (queryString) {
1588
1618
  const sort = []
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "imdone-core",
3
- "version": "1.50.2",
3
+ "version": "1.50.4",
4
4
  "description": "imdone-core",
5
5
  "main": "index.js",
6
6
  "scripts": {