obsidian-parser 0.5.2 → 0.5.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4b8337e7963b9236dcf2e06bcdbe81c44002546ca23b5c30451c3b9b218c7da4
4
- data.tar.gz: a69df6022fe82cfd016c56a1445c1b5fb23acca02ecd0521c6b455df58df3679
3
+ metadata.gz: 37cfdc15ab5d67c4ac5972db19df269b71a20c516bc43bc9014daccdf42879eb
4
+ data.tar.gz: ed67a9489d6e3ed05df0b72d14773b5674945ae993b51386e76634023629de74
5
5
  SHA512:
6
- metadata.gz: 2b898a0bfabe2aea32d357452b513078bb768be34f5607f07d1c4cbe05d5f9513b8a7c0cdc978995706621964cea01adbe88faf3213c4ff53bb2512b9f42927c
7
- data.tar.gz: 63697c74da15ee1b4c5897706fdaf6e0ed4b87cea7dfcf1ecc97d2e9c0317d06ed8f6ed821debf6ea23a5f2ca33ccbee3e02271f2328f67c68f121cc86d9292a
6
+ metadata.gz: 1b39d82790d769bda1434db80434715715c9be20b9fae0fd9f9c51147354e9f8adb46062b3500ff07d1084d3435ab764fc7f27a22481dfc48447ef0524802cec
7
+ data.tar.gz: acd7d36cac25c162da92a939e132033afd2b4585af490c188505295b9d51134a3073b47fc8e457777a984facec6884230c6b5e2188554be1a56a0a26f8ceec8e
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.5.4] - 2023-08-02
4
+ - Fix page getting clobbered when wikilinks point to non-existent pages.
5
+ - Expand `[[foo/index]]` wiklinks to `[foo](foo)`.
6
+
7
+ ## [0.5.3] - 2023-08-01
8
+ - Support non-fully qualified titles when parsing wikilink syntax.
9
+ - Autolink raw URLs.
10
+
3
11
  ## [0.5.2] - 2023-07-30
4
12
  - Fix handling of `index.md` at the root level.
5
13
 
data/Gemfile CHANGED
@@ -10,3 +10,5 @@ gem "rake", "~> 13.0"
10
10
  gem "rspec", "~> 3.0"
11
11
 
12
12
  gem "standard", "~> 1.3"
13
+
14
+ gem "pry"
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- obsidian-parser (0.5.2)
4
+ obsidian-parser (0.5.4)
5
5
  kramdown (~> 2.4)
6
6
  kramdown-parser-gfm (~> 1.1)
7
7
 
@@ -9,6 +9,7 @@ GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
11
  ast (2.4.2)
12
+ coderay (1.1.3)
12
13
  diff-lcs (1.5.0)
13
14
  json (2.6.3)
14
15
  kramdown (2.4.0)
@@ -17,10 +18,14 @@ GEM
17
18
  kramdown (~> 2.0)
18
19
  language_server-protocol (3.17.0.3)
19
20
  lint_roller (1.1.0)
21
+ method_source (1.0.0)
20
22
  parallel (1.23.0)
21
23
  parser (3.2.2.3)
22
24
  ast (~> 2.4.1)
23
25
  racc
26
+ pry (0.14.2)
27
+ coderay (~> 1.1)
28
+ method_source (~> 1.0)
24
29
  racc (1.7.1)
25
30
  rainbow (3.1.1)
26
31
  rake (13.0.6)
@@ -74,6 +79,7 @@ PLATFORMS
74
79
 
75
80
  DEPENDENCIES
76
81
  obsidian-parser!
82
+ pry
77
83
  rake (~> 13.0)
78
84
  rspec (~> 3.0)
79
85
  standard (~> 1.3)
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Obsidian
4
+ class MarkdownContent
5
+ def initialize(path, root)
6
+ @path = path
7
+ @root = root
8
+ end
9
+
10
+ def generate_html
11
+ markdown = @path.read
12
+ Obsidian::ObsidianFlavoredMarkdown.parse(markdown, root: @root).to_html
13
+ end
14
+ end
15
+ end
@@ -17,23 +17,57 @@ module Obsidian
17
17
  \]\]
18
18
  }x
19
19
 
20
+ # Match URLs
21
+ # Pattern based on https://gist.github.com/dperini/729294
22
+ LONE_URL = %r{
23
+ (?<!\S) # not preceeded by a non-whitespace character
24
+ https?:// # Protocol
25
+ (?:\S+(?::\S*)?@)? # basic auth
26
+ (?![-_]) # Not followed by a dash or underscore
27
+ (?:[-\w\u00a1-\uffff]{0,63}[^-_]\.)+ # host and domain names
28
+ (?:[a-z\u00a1-\uffff]{2,}\.?) # top level domain
29
+ (?::\\d{2,5})? # Port number
30
+ (?:[/?#]\\S*)? # Resource path
31
+ (?!\S) # not followed by a non-whitespace character
32
+ }x
33
+
34
+ # Workaround for lack of auto-linking in Kramdown.
35
+ # Note: this breaks for URLs included in code blocks.
36
+ def self.auto_link(markdown_text)
37
+ markdown_text.gsub(LONE_URL) do |s|
38
+ "<#{s}>" # Kramdown-specific markup
39
+ end
40
+ end
41
+
20
42
  # Convert Obsidian-flavored-markdown syntax to something parseable
21
43
  # (i.e. with Github-flavored-markdown syntax)
22
- def self.normalize(markdown_text)
44
+ def self.expand_wikilinks(markdown_text, root:)
23
45
  markdown_text.gsub(WIKILINK_SYNTAX) do |s|
24
46
  text = $~[:text]
25
47
  target = $~[:target]
26
48
  fragment = $~[:fragment]
27
- display_text = text.nil? ? target.split("/").last : text
28
- href = fragment.nil? ? target : "#{target}##{fragment}"
49
+ page = root.find_in_tree(target)
29
50
 
30
- "[#{display_text}](#{href})"
51
+ if page.nil?
52
+ text.nil? ? target.split("/").last : text
53
+ else
54
+ display_text = text.nil? ? page.slug.split("/").last : text
55
+ href = fragment.nil? ? page.slug : "#{page.slug}##{fragment}"
56
+
57
+ "[#{display_text}](#{href})"
58
+ end
31
59
  end
32
60
  end
33
61
 
34
- # Parse links from obsidian-flavored-markdown text
35
- def self.parse(markdown_text)
36
- document = Kramdown::Document.new(normalize(markdown_text), input: "GFM")
62
+ def self.normalize(markdown_text, root: nil)
63
+ auto_linked = auto_link(markdown_text)
64
+ return auto_linked if root.nil?
65
+
66
+ expand_wikilinks(auto_link(markdown_text), root: root)
67
+ end
68
+
69
+ def self.parse(markdown_text, root: nil)
70
+ document = Kramdown::Document.new(normalize(markdown_text, root: root), input: "GFM")
37
71
  Obsidian::ParsedMarkdownDocument.new(document)
38
72
  end
39
73
  end
@@ -103,16 +103,18 @@ module Obsidian
103
103
  # If there is an exact match, we should always return that
104
104
  # Otherwise, if we can skip over some anscestors and get a
105
105
  # match, then return the first, shortest match.
106
+ # If a query slug contains `/index` we ignore it and treat it
107
+ # the same as `/`
106
108
  def find_in_tree(query_slug)
107
109
  # Exact match
108
110
  return self if slug == query_slug
109
111
 
110
112
  # Partial match
111
- query_parts = query_slug.split("/")
113
+ query_parts = query_slug.split("/").reject { |part| part == "index" }
112
114
  length = query_parts.size
113
115
  slug_parts = slug.split("/")
114
116
 
115
- if slug_parts.length > length
117
+ if slug_parts.length >= length
116
118
  if slug_parts.slice(-length, length) == query_parts
117
119
  return self
118
120
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Obsidian
4
4
  class Parser
5
- VERSION = "0.5.2"
5
+ VERSION = "0.5.4"
6
6
  end
7
7
  end
@@ -4,6 +4,7 @@ require_relative "parser/version"
4
4
  require_relative "parser/parsed_markdown_document"
5
5
  require_relative "parser/obsidian_flavored_markdown"
6
6
  require_relative "parser/page"
7
+ require_relative "parser/markdown_content"
7
8
 
8
9
  require "forwardable"
9
10
 
@@ -14,17 +15,6 @@ module Obsidian
14
15
  (parent_slug == "") ? title : "#{parent_slug}/#{title}"
15
16
  end
16
17
 
17
- class MarkdownContent
18
- def initialize(path)
19
- @path = path
20
- end
21
-
22
- def generate_html
23
- markdown = @path.read
24
- Obsidian::ObsidianFlavoredMarkdown.parse(markdown).to_html
25
- end
26
- end
27
-
28
18
  class Parser
29
19
  attr_reader :index
30
20
 
@@ -49,7 +39,7 @@ module Obsidian
49
39
  @index.add_page(
50
40
  slug,
51
41
  last_modified: path.mtime,
52
- content: MarkdownContent.new(path)
42
+ content: MarkdownContent.new(path, @index)
53
43
  )
54
44
  end
55
45
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: obsidian-parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.5.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mat Moore
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-07-30 00:00:00.000000000 Z
11
+ date: 2023-08-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: kramdown
@@ -56,6 +56,7 @@ files:
56
56
  - README.md
57
57
  - Rakefile
58
58
  - lib/obsidian/parser.rb
59
+ - lib/obsidian/parser/markdown_content.rb
59
60
  - lib/obsidian/parser/obsidian_flavored_markdown.rb
60
61
  - lib/obsidian/parser/page.rb
61
62
  - lib/obsidian/parser/parsed_markdown_document.rb