Skip to content

Conversation

yordis
Copy link
Contributor

@yordis yordis commented Oct 2, 2025

Signed-off-by: Yordis Prieto [email protected]

Signed-off-by: Yordis Prieto <[email protected]>
@@ -0,0 +1,133 @@
defmodule ExDoc.Formatter.MARKDOWNTest do
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
defmodule ExDoc.Formatter.MARKDOWNTest do
defmodule ExDoc.Formatter.MarkdownTest do

I feel markdown should be Markdown thou, no?

Copy link

github-actions bot commented Oct 2, 2025

@yordis
Copy link
Contributor Author

yordis commented Oct 6, 2025

@josevalim any thoughts here thus far?

@josevalim
Copy link
Member

Sorry, a bit busy with Elixir v1.19-rc and today I was out of focus. It is in my inbox and I will review it as soon as I can.

Copy link
Contributor

@leandrocp leandrocp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @yordis that's amazing! Let me share some ideas that could be useful.

I was inspecting the generated Markdown files and thinking if we could apply some changes. See the differences here https://gist.github.com/leandrocp/ee4f0ba8325b410b8650ccd26b9b2351 (CompiledWithDocs.md vs CompiledWithDocs_PROPOSAL.md)

  • Use frontmatter block to describe global values/notes
  • Use the format "Summary / Functions" similar to HTML pages (so Functions become a level 2 heading)
  • Include source links
  • Reorganize metadata, for eg: add (deprecated) and doc in summary
  • Remove links to hexdocs.pm because 1) it breaks the content and I guess that would make it harder for LLMs to parse; 2) I'm not sure it should link to html pages

You can see some examples on https://shopify.dev/docs/api/liquid/basics.md and https://vercel.com/docs/rest-api/reference/sdk.md

Comment on lines +89 to +94
def to_markdown_string({:code, _attrs, inner, _meta} = ast, fun) do
result = """
```
#{inner}
```
"""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should add the lang here:

Suggested change
def to_markdown_string({:code, _attrs, inner, _meta} = ast, fun) do
result = """
```
#{inner}
```
"""
def to_markdown_string({:code, attrs, inner, _meta} = ast, fun) do
class = attrs[:class] || ""
result = """
```#{class}
#{inner}
```
"""

Comment on lines +125 to +147
EEx.function_from_file(
:def,
:nav_template,
Path.expand("templates/nav_template.eex", __DIR__),
[:config, :nodes],
trim: true
)

EEx.function_from_file(
:defp,
:nav_item_template,
Path.expand("templates/nav_item_template.eex", __DIR__),
[:name, :nodes],
trim: true
)

EEx.function_from_file(
:defp,
:nav_grouped_item_template,
Path.expand("templates/nav_grouped_item_template.eex", __DIR__),
[:nodes],
trim: true
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me suggest using using ~MD as an alternative :)

Since ~MD does compile EEx strings, you could replace all template files and these functions with just:

  import MDEx.Sigil
  import ExDoc.Utils, only: [before_closing_body_tag: 2, h: 1, text_to_id: 1]

  defp nav_template(assigns) do
    ~MD"""
    # <%= @config.project %> v<%= @config.version %> - Documentation - Table of contents

    <%= nav_grouped_item_template %{nodes: @config.extras} %>
    <%= unless Enum.empty?(@nodes.modules) do %>
    ## Modules
    <%= nav_grouped_item_template %{nodes: @nodes.modules}  %>
    <% end %>
    <%= nav_item_template %{name: "Mix Tasks", nodes: @nodes.tasks} %>
    <%= before_closing_body_tag(@config, :markdown) %>
    """MD
  end

  defp nav_grouped_item_template(assigns) do
    ~MD"""
    <%= for {title, nodes} <- @nodes do %>
    <%= if title do %>
    - <%=h to_string(title) %>
    <% end %>
    <%= for node <- nodes do %>
      - [<%=h node.title %>](<%= URI.encode node.id %>.md)
    <% end %>
    <% end %>
    """MD
  end

  defp nav_item_template(assigns) do
    ~MD"""
    <%= unless Enum.empty?(@nodes) do %>
    - <%= @name %>
    <%= for node <- @nodes do %>
      - [<%=h node.title %>](<%= URI.encode node.id %>.md)
    <% end %>
    <% end %>
    """MD
  end

  # ... rest

Note that MDEx can do more than just templating so it could be useful for manipulating documents too as for eg https://github.com/elixir-lang/ex_doc/pull/1992/files#diff-ca88e8bb57ba3af8237d2b7edb130ca72744fe6e0772bcd73a28690e958e6cc5R148-R169

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We try our best to avoid adding dependencies to ExDoc because they may impose further constraints on users of ExDoc, given ExDoc is used by almost every library. Furthermore, if we use MDEx as a dependency, then you need to write some doc publishing helpers in MDEx, cause you will no longer be able to depend on ExDoc. :D So it is best to postpone this as much as possible.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We try our best to avoid adding dependencies to ExDoc because they may impose further constraints on users of ExDoc, given ExDoc is used by almost every library. Furthermore, if we use MDEx as a dependency, then you need to write some doc publishing helpers in MDEx, cause you will no longer be able to depend on ExDoc. :D So it is best to postpone this as much as possible.

Makes sense :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants