Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Partially Copying Code Blocks #3436

Open
4 tasks done
soerenmartius opened this issue Jan 10, 2024 · 5 comments
Open
4 tasks done

Partially Copying Code Blocks #3436

soerenmartius opened this issue Jan 10, 2024 · 5 comments

Comments

@soerenmartius
Copy link

soerenmartius commented Jan 10, 2024

Is your feature request related to a problem? Please describe.

Currently, whenever copying from a code block, all code exposed in that box will be copied. In an ideal world, within the same code block I am able to show a command as well as the resulting output of a command. However, as a user, when copying the code I only want the actual command without the outputs to be copied.

E.g.

```sh
ls # command

file file file file #output

Describe the solution you'd like

Being able to define a line or range of lines of code to be copied from a code block.

```sh{cp1}
ls # command

file file file file #output

Describe alternatives you've considered

No response

Additional context

No response

Validations

@ms264556
Copy link

ms264556 commented Feb 2, 2024

I would love this sort of functionality.

When showing the necessary console commands to achieve something, it is helpful to show not just the output but also the prompt since the prompt shows useful information.

e.g. I would like to show the entire code block below, but the only information I want to be copied is enable\n and debug\n:-

ruckus> enable 
ruckus# debug 
You have all rights in this mode.
ruckus(debug)#

@github-actions github-actions bot added the stale label Mar 7, 2024
@BenoitDesrosiers
Copy link

it would also be useful when putting code in a context. For example, if you want to show that a line has to be inserted between 2 lines, you want to show these 2 lines, but you don't want them to be copied

@github-actions github-actions bot removed the stale label Jun 23, 2024
@github-actions github-actions bot added the stale label Sep 1, 2024
@ms264556
Copy link

ms264556 commented Jan 12, 2025

For excluding entire lines, it turns out pretty easy to create a code comment which you can use like this:

```console
$ ls -la
output output output # [!code copy-ignore]
```

I added shiki transformers to my devDependencies: pnpm install -D @shikijs/transformers

Then I added this to my .vitepress config.ts:

import { transformerNotationMap } from '@shikijs/transformers'

...

export default defineConfig({
  ...
  markdown: {
    ...
    codeTransformers: [
      transformerNotationMap({ classMap: { 'copy-ignore': 'vp-copy-ignore', } })
    ],
    ...
  }
  ...
}

@ms264556
Copy link

Unfortunately you still get the line-breaks for the missing lines.

This can be fixed by wrapping vp-copy-ignore lines with the preceding line-break in an extra vp-copy-ignore span.

I wrote a shell ShikiTransformer today which does this (+ handles prompt formatting properly). I'll clean it up and post it on github this weekend.

You can try an example here.

@github-actions github-actions bot removed the stale label Jan 20, 2025
@ms264556
Copy link

ms264556 commented Jan 30, 2025

I have a fix in shiki 2.2.0 so this transformer can play nice with the word highlighting transformer. Once that's in vitepress then I'll fix the code and put it somewhere.

In the meantime, I chucked my proof-of-concept transformer here.

The line-breaks removal is in the pre() function, which hopefully runs after other stuff has finished modifying elements.

The preprocess() function has

  1. code to remove prompts and output before the grammar runs, then reinstate it afterwards, since the prompts currently break highlighting. And

  2. code to wrap prompts and output with classes for vp-copy-none + styling, with the option to also whack styles on the elements if you don't want to bother with css.

The default pattern is pretty boring: $ and > start code lines; anything without a prompt is considered output.
But you can add your own prompt regexp for other targets. Any capture groups in your regex are assumed to be prompt text, which can be style differently from the prompt symbol.

So e.g.

export default defineConfig({
  markdown: {
    codeTransformers: [
      transformerShellPrompt({
        languages: [
          ['ruckus-cli', /^(\w+)(?:\(([-\w]+)\))?(?:\:|>|#|%|\$) ?/d],
          'terminal'
        ],
        applyStyles: true
      })
    ],
    languageAlias: { 'ruckus-cli': 'shell', 'terminal': 'shell' },
})

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

No branches or pull requests

4 participants