diff --git a/context/documentation-guidelines.md b/context/documentation-guidelines.md
index 71b93c5..1e6dd33 100644
--- a/context/documentation-guidelines.md
+++ b/context/documentation-guidelines.md
@@ -16,7 +16,7 @@ Source code documentation is included adjacent to the code it describes, using s
However, in short:
- Documentation is expected to be in markdown format.
-- You may embed links to definitions using `{MyClass}` or `{my_method}`.
+- You may embed links to definitions using ruby:`MyClass` or ruby:`my_method`.
- You can use tags:
- `@parameters name [Type] Description.`
- `@yields {|argument| ...} If a block is given.`
@@ -173,7 +173,7 @@ $ bundle add $project
`$project` has several core concepts:
-- A {ruby MyProject::MyClass} which represents the main entry point for using the project.
+- A ruby:`MyProject::MyClass` which represents the main entry point for using the project.
## Usage
@@ -284,7 +284,7 @@ Following `utopia-project` guidelines, each guide should:
2. **Provide user context**: Explain why users would need this feature
3. **Include practical examples**: Working code samples that demonstrate real scenarios
4. **Follow consistent structure**: Problem → Use Cases → Implementation → Best Practices
-5. **Cross-reference appropriately**: Use `{ruby ClassName}` for internal references
+5. **Cross-reference appropriately**: Use ruby:`ClassName` for internal references
6. **Include error handling**: Show how to handle common failure scenarios
7. **Provide troubleshooting**: Common issues and solutions
8. **Maintain currency**: Keep examples updated with latest best practices
diff --git a/guides/documentation-guidelines/readme.md b/guides/documentation-guidelines/readme.md
index 71b93c5..1e6dd33 100644
--- a/guides/documentation-guidelines/readme.md
+++ b/guides/documentation-guidelines/readme.md
@@ -16,7 +16,7 @@ Source code documentation is included adjacent to the code it describes, using s
However, in short:
- Documentation is expected to be in markdown format.
-- You may embed links to definitions using `{MyClass}` or `{my_method}`.
+- You may embed links to definitions using ruby:`MyClass` or ruby:`my_method`.
- You can use tags:
- `@parameters name [Type] Description.`
- `@yields {|argument| ...} If a block is given.`
@@ -173,7 +173,7 @@ $ bundle add $project
`$project` has several core concepts:
-- A {ruby MyProject::MyClass} which represents the main entry point for using the project.
+- A ruby:`MyProject::MyClass` which represents the main entry point for using the project.
## Usage
@@ -284,7 +284,7 @@ Following `utopia-project` guidelines, each guide should:
2. **Provide user context**: Explain why users would need this feature
3. **Include practical examples**: Working code samples that demonstrate real scenarios
4. **Follow consistent structure**: Problem → Use Cases → Implementation → Best Practices
-5. **Cross-reference appropriately**: Use `{ruby ClassName}` for internal references
+5. **Cross-reference appropriately**: Use ruby:`ClassName` for internal references
6. **Include error handling**: Show how to handle common failure scenarios
7. **Provide troubleshooting**: Common issues and solutions
8. **Maintain currency**: Keep examples updated with latest best practices
diff --git a/lib/utopia/project/base.md b/lib/utopia/project/base.md
index 297e8d9..36d1769 100644
--- a/lib/utopia/project/base.md
+++ b/lib/utopia/project/base.md
@@ -4,4 +4,4 @@ Provides structured access to a project directory which contains source code and
## Usage
-To get an instance for the current project, use {Base#instance}.
+To get an instance for the current project, use ruby:`Base#instance`.
diff --git a/lib/utopia/project/base.rb b/lib/utopia/project/base.rb
index e1e3a16..d7a9885 100644
--- a/lib/utopia/project/base.rb
+++ b/lib/utopia/project/base.rb
@@ -136,12 +136,12 @@ def linkify(text, definition, language: definition&.language)
end
# Format the given text in the context of the given definition and language.
- # See {document} for details.
+ # See ruby:`document` for details.
# @returns [XRB::MarkupString]
#
# @example Format text with code links
# base = Utopia::Project::Base.new
- # base.format("See {Utopia::Project::Base#guides}.") # => XRB::MarkupString
+ # base.format("See ruby:`Utopia::Project::Base#guides`.") # => XRB::MarkupString
def format(text, definition = nil, language: definition&.language, **options)
if document = self.document(text, definition, language: language)
return XRB::Markup.raw(
@@ -152,7 +152,7 @@ def format(text, definition = nil, language: definition&.language, **options)
# Convert the given markdown text into HTML.
#
- # Updates source code references (`{language identifier}`) into links.
+ # Updates language-prefixed inline code (e.g. `ruby:` followed by inline code) into links.
#
# @returns [Document]
#
diff --git a/lib/utopia/project/document.rb b/lib/utopia/project/document.rb
index d70c3e8..3283cda 100644
--- a/lib/utopia/project/document.rb
+++ b/lib/utopia/project/document.rb
@@ -29,7 +29,7 @@ def initialize(text, base = nil, definition: nil, default_language: nil)
# Parse and resolve the document root.
# @returns [Markly::Node] The root document node.
def root
- @root ||= resolve(Markly.parse(@text, extensions: [:table]))
+ @root ||= resolve(Markly.parse(@text, flags: Markly::INLINE_CODE_INFO, extensions: [:table]))
end
# Extract the leading heading as the document title.
@@ -99,7 +99,12 @@ def to_markdown(**options)
# @parameter node [Markly::Node] The node to render.
# @returns [XRB::MarkupString] The rendered HTML markup.
def to_html(node = self.root, **options)
- renderer = Renderer.new(ids: true, flags: Markly::UNSAFE, **options)
+ renderer = Renderer.new(
+ inline_code_resolver: (@index ? method(:reference_node) : nil),
+ ids: true,
+ flags: Markly::UNSAFE,
+ **options
+ )
XRB::Markup.raw(renderer.render(node))
end
@@ -160,15 +165,9 @@ def link_node(title, url, child)
# @parameter language [String | Nil] The source language name.
# @returns [Markly::Node] The code node.
def code_node(content, language = nil)
- if language
- node = inline_html_node(
- "#{XRB::Strings.to_html(content)}"
- )
- else
- node = Markly::Node.new(:code)
- node.string_content = content
- return node
- end
+ node = Markly::Node.new(:code)
+ node.string_content = content
+ node.code_info = language if language
return node
end
@@ -176,9 +175,17 @@ def code_node(content, language = nil)
private
# Replace source code references in the given text with HTML anchors.
- #
- def reference_node(content)
- if reference = @index.languages.parse_reference(content, default_language: @default_language)
+ # @parameter content [String] The source code reference.
+ # @parameter language [String | Nil] The explicit source language.
+ # @returns [Markly::Node] The resolved link or code node.
+ def reference_node(content, language: nil)
+ reference = if language
+ @index.languages.reference_for(language, content)
+ else
+ @index.languages.parse_reference(content, default_language: @default_language)
+ end
+
+ if reference
definition = @index.lookup(reference, relative_to: @definition)
end
@@ -189,7 +196,7 @@ def reference_node(content)
elsif reference
code_node(reference.identifier, reference.language.name)
else
- code_node(content)
+ code_node(content, language)
end
end
diff --git a/lib/utopia/project/renderer.rb b/lib/utopia/project/renderer.rb
index 089640e..b82fc9c 100644
--- a/lib/utopia/project/renderer.rb
+++ b/lib/utopia/project/renderer.rb
@@ -10,6 +10,15 @@ module Utopia
module Project
# Renders project Markdown with support for Mermaid code blocks.
class Renderer < Markly::Renderer::HTML
+ # Initialize the project renderer.
+ # @parameter inline_code_resolver [Proc | Nil] Resolves language-prefixed inline code into a replacement node.
+ def initialize(inline_code_resolver: nil, **options)
+ @inline_code_resolver = inline_code_resolver
+ @resolving_inline_code = false
+
+ super(**options)
+ end
+
# Render a heading and expose its title to Pagefind for sub-results.
# @parameter node [Markly::Node] The heading node.
def header(node)
@@ -45,6 +54,21 @@ def code_block(node)
super
end
end
+
+ # Render inline code, resolving language-prefixed references when possible.
+ # @parameter node [Markly::Node] The inline code node.
+ def code(node)
+ if @inline_code_resolver && !@resolving_inline_code && (language = node.code_language)
+ begin
+ @resolving_inline_code = true
+ out(@inline_code_resolver.call(node.string_content, language: language))
+ ensure
+ @resolving_inline_code = false
+ end
+ else
+ super
+ end
+ end
end
end
end
diff --git a/releases.md b/releases.md
index aa1cc29..600968b 100644
--- a/releases.md
+++ b/releases.md
@@ -1,5 +1,9 @@
# Changes
+## Unreleased
+
+ - Add support for language-prefixed inline code references such as ruby:`Object.new`.
+
## v0.41.0
- Don't render empty signature block when there are only examples.
diff --git a/test/utopia/project/document.rb b/test/utopia/project/document.rb
index 73ae45a..b527bf9 100644
--- a/test/utopia/project/document.rb
+++ b/test/utopia/project/document.rb
@@ -22,6 +22,40 @@
expect(html).to be(:include?, '')
end
+ it "renders language-prefixed inline code" do
+ root = File.expand_path("../../..", __dir__)
+ base = Utopia::Project::Base.new(root)
+ document = subject.new("Use ruby:`Object.new` to create an object.", base)
+ html = document.to_html.to_s
+
+ expect(html).to be(:include?, 'Object.new')
+ expect(html).not.to be(:include?, "Utopia::Project::Document#root')
+ end
+
+ it "continues to resolve legacy brace references" do
+ root = File.expand_path("../../..", __dir__)
+ base = Utopia::Project::Base.new(root)
+ base.update([File.join(root, "lib/utopia/project/document.rb")])
+
+ document = subject.new("See {ruby Utopia::Project::Document#root}.", base)
+ html = document.to_html.to_s
+
+ expect(html).to be(:include?, '"))
diff --git a/utopia-project.gemspec b/utopia-project.gemspec
index dc96086..76846c0 100644
--- a/utopia-project.gemspec
+++ b/utopia-project.gemspec
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
spec.add_dependency "decode", "~> 0.30"
spec.add_dependency "falcon"
- spec.add_dependency "markly", "~> 0.15"
+ spec.add_dependency "markly", "~> 0.17"
spec.add_dependency "thread-local"
spec.add_dependency "utopia", "~> 3.0.4"
end