docsifyjs/docsify

Cannot preview permanent link

Closed this issue · 7 comments

Bug Report

Steps to reproduce

  1. Copy a permanent link and paste to markdown docs.
  2. Commit changes and Deploy to github pages.
  3. Open the docs and see the permanent link.

For example, here's the commit:linrongbin16/commons.nvim@fc78382.

And github can preview the permanent link:

Screenshot_2023-12-16-09-32-49-903_com android chrome-edit

In the mean while, docsify cannot preview:

Screenshot_2023-12-16-09-32-24-260_com android chrome-edit

Current behaviour

See above example.

Expected behaviour

Also preview permanent link.

Other relevant information

  • Docsify version: latest v4.x
  • Bug still occurs when all/other plugins are disabled?

  • Docsify plugins (if the bug happens when plugins enabled, please try to isolate the issue):

Please create a reproducible sandbox

Edit 307qqv236

Mention the docsify version in which this bug was not present (if any)

Hi @linrongbin16 , the permanent link is not standard markdown syntax, github does the trick linking-to-code.

FYI, If you don't wanna implement the permanent link preview hook for now. I suppose Embed a gist could be a workaround

Hi @linrongbin16 , the permanent link is not standard markdown syntax, github does the trick linking-to-code.

FYI, If you don't wanna implement the permanent link preview hook for now. I suppose Embed a gist could be a workaround

thanks for reply, I had searched a while, but didn't found any code snippet do render content from a github permanent link.

would you please educate if there is a way to do it?

Hi @linrongbin16 , If you do want import the github permanent links lines by urself, you may have a try on it. It is a little bit cumbersome tho.

  • Define a placeholder/anchor as your custom github permanent links syntax in your md file.
# MyContent

This is my markdown file.

=permanent-link(https://github.com/linrongbin16/commons.nvim/blob/487e197fe8ce9db28aec656df43df1c712710fac/lua/commons/buffers.lua#L14-L17)

> it should render above;
  • Register a hook to parser the links and fetch the content from github.
          function (hook, vm) {
            hook.beforeEach(html => {
              // Find my own anchor
              var regex = /=permanent-link\((.*)\)/g;
              html = html.replace(regex, function (match, content) {
                // Get the permanent-link
                const api = content;
                // Get which lines you want
                const tokens = content.split('#');
                const lines = tokens[1].replaceAll('L', '').split('-');
                const from_line = lines[0];
                const to_line = lines[1];
                // Fetch the api to get the content and find the lines you want,  replace it now or later.
                fetch(api).then......
                // For more details, you could curl the https://github.com/linrongbin16/commons.nvim/blob/487e197fe8ce9db28aec656df43df1c712710fac/lua/commons/buffers.lua#L14-L17
                // In the $payload.blob.rawLines to get those lines you want and concat them
                return 'return the custom markdown code block with what you want to repalce the =permanent-link(...) stuff';
              });
              return html
            }

Sample payload retrieved from https://github.com/linrongbin16/commons.nvim/blob/487e197fe8ce9db28aec656df43df1c712710fac/lua/commons/buffers.lua#L14-L17.

[
  "local M = {}",
  "",
  "--- @param bufnr integer",
  "--- @param name string",
  "--- @return any",
  "M.get_buf_option = function(bufnr, name)",
  "  if vim.fn.has(\"nvim-0.8\") > 0 then",
  "    return vim.api.nvim_get_option_value(name, { buf = bufnr })",
  "  else",
  "    return vim.api.nvim_buf_get_option(bufnr, name)",
  "  end",
  "end",
  "",
  "--- @param bufnr integer",
  "--- @param name string",
  "--- @param value any",
  "M.set_buf_option = function(bufnr, name, value)",
  "  if vim.fn.has(\"nvim-0.8\") > 0 then",
  "    return vim.api.nvim_set_option_value(name, value, { buf = bufnr })",
  "  else",
  "    return vim.api.nvim_buf_set_option(bufnr, name, value)",
  "  end",
  "end",
  "",
  "return M"
]

@Koooooo-7 really really thanks for your sharing!

hi @Koooooo-7 , I had tried this solution, I have 1 more question. I need to first fetch the github file content, render the part of the source code into the html.

Now in the code snippet:

    plugins: [
        function (hook, vm) {
            hook.beforeEach(function (html) {
              // =permanent-link
              var regex = /=permanent-link\((.*)\)/g;
              html = html.replace(regex, function (match, content) {
                // Get the permanent-link
                const api = content;
                // Get which lines you want
                const tokens = content.split("#");
                const lines = tokens[1].replaceAll("L", "").split("-");
                const from_line = lines[0];
                const to_line = lines[1];

                // https://raw.githubusercontent.com/linrongbin16/commons.nvim/4fb28b74e15792397379ea9469b825d19fa9b946/lua/commons/apis.lua
                const raw = tokens[0].replaceAll(
                  "https://github.com/linrongbin16/commons.nvim/blob",
                  "https://raw.githubusercontent.com/linrongbin16/commons.nvim",
                );
                fetch(raw)
                  .then((response) => {
                    console.log("response:");
                    console.log(response);
                    return response;
                  })
                  .catch((err) => console.log(err));
                // In the $payload.blob.rawLines to get those lines you want and concat them
                return "return the custom markdown code block with what you want to repalce the =permanent-link(...) stuff";
              });
          });
       },
    ]

It seems the fetch operation is async, so in the returned html content, I cannot use the fetched response body?

hi @Koooooo-7 , I had tried this solution, I have 1 more question. I need to first fetch the github file content, render the part of the source code into the html.
It seems the fetch operation is async, so in the returned html content, I cannot use the fetched response body?

Hi @linrongbin16 , yes, the async way needs the hook with next, see beforeach with async task.
So, we could do it like this.

            hook.beforeEach((html, next) => {
              // collect all the match tasks
              const tasks = [];
              var regex = /=permanent-link\((.*)\)/g;
              html.replace(regex, function (match, content) {
                const api = content;
                const tokens = content.split('#');
                const lines = tokens[1].replaceAll('L', '').split('-');
                const from_line = lines[0];
                const to_line = lines[1];
                
                // fetch content
                const task = fetch(api)
                  .then(resp => resp.json())
                  .then(data => {
                    // ... process with data      
                    html = html.replace(match, data);
                  });

                tasks.push(task);
              });
             
             // all tasks done and return  
              Promise.all(tasks).then(finish => {
                next(html);
              });
            });

thank you! @Koooooo-7