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

Ability to Remove Clipboard for Code Snippets #2418

Closed
4 tasks done
BrandonE opened this issue Mar 8, 2021 · 31 comments
Closed
4 tasks done

Ability to Remove Clipboard for Code Snippets #2418

BrandonE opened this issue Mar 8, 2021 · 31 comments
Labels
change request Issue requests a new feature or improvement resolved Issue is resolved, yet unreleased if open

Comments

@BrandonE
Copy link

BrandonE commented Mar 8, 2021

  • I've read the [contribution guidelines][1] and agree with them

I want to suggest an idea and checked that ...

  • ... to my best knowledge, my idea wouldn't break something for other users
  • ... the documentation does not mention anything about my idea
  • ... there are no open or closed issues that are related to my idea

Description

I would like the ability to remove the "copy to clipboard" functionality for specific code snippets on a case-by-base basis.

Use Cases

I like to show a command that the viewer should run followed by the expected output. I use code snippets for both of these purposes. However, an inattentive viewer might confuse the command for the expected output and try to copy and paste the output. I would like to prevent this by hiding the clipboard icon for expected output.

Screenshots / Mockups

The syntax can look something like this:

```<Optional language> no-copy
Error: ...
```
@squidfunk squidfunk added the change request Issue requests a new feature or improvement label Mar 8, 2021
@polarathene
Copy link
Contributor

Use attr_list extension to add a no-copy class and CSS to set display: none; on the target child element to hide.

```{: .optional-language-as-class .no-copy}
Error: ...
```

Add docs/assets/css/custom.css file:

.highlight.no-copy .md-clipboard { display: none; }

In mkdocs.yml add:

markdown_extensions:
  - attr_list

extra_css:
  - assets/css/custom.css

@squidfunk
Copy link
Owner

Thanks, @polarathene – definitely the way to go!

@BrandonE
Copy link
Author

@polarathene Is there a particular version in which this is supported? I'm using 4.6.3 and am struggling to upgrade. When following your steps, I get the following results:

image

@facelessuser
Copy link
Contributor

  1. Are you using SuperFences?
  2. I want to say you can use : at the start of the fenced code block, I think you use {.lang .no-copy}.

With that said, now I need to check if Python Markdown's built-in fenced-code supports : at the start of fenced code this way...I know it does for normal attr_list...

@polarathene
Copy link
Contributor

@BrandonE Are you using it exactly as that? .optional-language-as-class should be the language name eg .yaml or .css, like you'd normally use. Make sure you are using the extensions and custom CSS as I also provided in snippets above.

@facelessuser I tested with SuperFences enabled iirc.

@facelessuser
Copy link
Contributor

@polarathene, You used :? I'm pretty sure the code won't parse the language right that way. The regex will absorb the : into the language name I think...

@facelessuser
Copy link
Contributor

Yeah, I just tested. Lose the : as it won't work properly.

@polarathene
Copy link
Contributor

polarathene commented Mar 11, 2021

@facelessuser yes I used it exactly as shown above and I'm pretty certain it worked fine, so long as I provided the language class as mentioned (using pygments, haven't tested with highlight.js).

@facelessuser
Copy link
Contributor

@polarathene I don't know what you are doing, but that doesn't work.

```{.py3 .no-copy}
test = "A tale of two code blocks"
```

```{:.py3 .no-copy}
test = "It was the best of times and the worst of times"
```

Screen Shot 2021-03-10 at 8 34 33 PM

Screen Shot 2021-03-10 at 8 34 45 PM

@facelessuser
Copy link
Contributor

Maybe you are not using SuperFences? 🤷

@polarathene
Copy link
Contributor

polarathene commented Mar 11, 2021

Maybe you are not using SuperFences? shrug

I am. I have reproduced the solution again to verify. You accidentally missed having a space between the : and .py3:

Screenshot_20210311_164525

Screenshot_20210311_164315

Screenshot_20210311_164358

@facelessuser
Copy link
Contributor

I am, just reproduced for you. Your mistake was not having a space between the : and .py3.

It's not a mistake, it is an exploit. I'm the author of the plugin, and I do not support :, even it seems to work when you do things just so.

I say all of this as the author of SuperFences. The space is not needed when using attr_list on inline blocks. I'm not entirely sure what is going on, but we pass the contents to attr_list's get_attr function, but we do not exclude :. I would not rely on that behavior even if it works right now.

@facelessuser
Copy link
Contributor

This also works, but it is not intentional:

```{::::: .py3 .no-copy}
test = "It was the best of times and the worst of times"
```

It's just that we aren't strict about what is found between {} and we expected attr_list to not allow insanity. We were wrong 🙃.

@polarathene
Copy link
Contributor

polarathene commented Mar 11, 2021

It's not a mistake, it is an exploit. I'm the author of the plugin, and I do not support :, even it seems to work when you do things just so.

I was just referencing the attr_list docs which seemed to use the syntax {: <your-stuff-here> }. If that behaviour differs specifically for SuperFences to expect that there is no :, that's fine, I didn't consider to look at your docs for any differences/conflicts.

Regardless, solution works as shown and @BrandonE should be able to get it working with the info above (with or without the :).

@BrandonE
Copy link
Author

  1. Are you using SuperFences?
  2. I want to say you can use : at the start of the fenced code block, I think you use {.lang .no-copy}.

With that said, now I need to check if Python Markdown's built-in fenced-code supports : at the start of fenced code this way...I know it does for normal attr_list...

  1. Yes.
  2. I understand now that the above snippet was a sample. I changed it accordingly just for a proof-of-concept:

image

It no longer shows this syntax in the result, but the clipboard is still visible:

image

@squidfunk
Copy link
Owner

squidfunk commented Mar 11, 2021

Using the text lexer should work:

``` { .text .no-copy }
...
```

@facelessuser
Copy link
Contributor

Yup, the first class is assumed to be the language, so you need to specify a language if you specify additional classes.

@BrandonE
Copy link
Author

No luck @squidfunk @facelessuser:

image

image

Unsure if this is helpful at all, but here are the HTML elements that are generated using the code that I previously posted. It looks like my version uses codehilite instead of highlight, so the CSS originally posted wouldn't work, but I also don't see the no-user class on any of these elements:

image

@facelessuser
Copy link
Contributor

Please post your config. I'm having a hard time understanding what you have enabled for plugins. I at least can tell you are using CodeHilite, probably?

@BrandonE
Copy link
Author

Please post your config. I'm having a hard time understanding what you have enabled for plugins. I at least can tell you are using CodeHilite, probably?

mkdocs.yml:

site_name: "Workbook"
site_description: "Workbook"
site_author: "..."
nav:
  - Introduction:
    - 'Home': 'index.md'
    - 'System Requirements': 'labs/system_requirements/index.md'
    - 'Errata Patches': 'errata/index.md'
  - Exercises:
    - "Lab 0": "labs/setup/index.md"
  - Resources:
    - "Troubleshooting": "troubleshooting/index.md"
    - "References": "references/index.md"

extra_css:
  - css/jquery.fancybox.min.css
  - css/custom.css
  - css/pdf.css

extra_javascript:
  - js/jquery-3.4.1.min.js
  - js/jquery.fancybox.min.js
  - js/custom.js

theme:
  name: 'material'
  palette:
    primary: 'Orange'
    accent: 'Blue'
  feature:
    tabs: true
  font: false
  logo:
    icon: 'home'
    favicon: 'media/favicon.png'

markdown_extensions:
  - admonition
  - attr_list
  - codehilite:
      guess_lang: false
  - toc:
      permalink: false
      toc_depth : "1-3"
  - pymdownx.arithmatex
  - pymdownx.betterem:
      smart_enable: all
  - pymdownx.caret
  - pymdownx.critic
  - pymdownx.details
  - pymdownx.inlinehilite
  - pymdownx.magiclink
  - pymdownx.mark
  - pymdownx.smartsymbols
  - pymdownx.superfences
  - pymdownx.tasklist:
      custom_checkbox: true
  - pymdownx.tilde

plugins:
    - search
    - exclude:
        glob:
            - "*.pdf"
    - pdf-export:
        verbose: false
        combined: true
        combined_output_path: pdf/Workbook.pdf
        media_type: print
        enabled_if_env: ENABLE_PDF_EXPORT

requirements.txt:

cairocffi==0.9.0
pymdown-extensions==6.3
mkdocs==1.0.4
mkdocs-material==4.6.3
mkdocs-minify-plugin==0.2.1
mkdocs-exclude==1.0.2
mkdocs-pdf-export-plugin==0.5.5
git+git://github.com/aleray/mdx_del_ins.git

@facelessuser
Copy link
Contributor

Try updating pymdown-extensions to the latest. Maybe markdown too, I don't see its version. attr_list support for code blocks was added I think in a later pymdown-extensions. Latest in 8.1.X, I think.

Also, if you are using the latest pydmown-extensions, you don't need to specify codehilite anymore. Technically, you don't need to specify it in 6.3 (I think).

@BrandonE
Copy link
Author

@facelessuser Upgrading pymdown-extensions requires me to upgrade mkdocs-material, which requires me to upgrade mkdocs, which causes an error until I upgrade mkdocs-pdf-export-plugin.

Afterwards, I get this error, which I understand means that I need to update my theme.logo.icon syntax to theme.icon. I copy the example in the migration docs verbatim, and mkdocs serve crashes like so:

INFO    -  Building documentation... 
PDF export is disabled (set environment variable ENABLE_PDF_EXPORT to 1 to enable)
INFO    -  Cleaning site directory 

.icons/.svg

I get the same problem if I remove the theme.logo block altogether. I'm happy to upgrade any and all of these packages if I can figure out the process.

@facelessuser
Copy link
Contributor

Yeah, you were on an older version. I'd check out the migration guide: https://squidfunk.github.io/mkdocs-material/upgrading/. I can't answer questions about the PDF plugin as I don't use it.

@facelessuser
Copy link
Contributor

If things are unclear, you can always reference other mkdocs.yml files that are using the most recent config format. Obviously, you can look at this projects yml, but you can also look at mine as well: https://github.com/facelessuser/pymdown-extensions/blob/main/mkdocs.yml.

@BrandonE
Copy link
Author

@facelessuser I was referring to the 4.x to 5.x migration process. I changed theme.logo.icon to theme.icon according to the documentation. I tried removing it well. mkdocs serve crashes and just prints out .icons/.svg. This happens even if my theme just specifies that the name of the theme is material.

I removed the entire theme section, which resulted in mkdocs serve running. After restoring the config, it hot reloaded with a more detailed error message:

ERROR   -  Exception in callback <bound method LiveReloadHandler.poll_tasks of <class 'livereload.handlers.LiveReloadHandler'>>
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/tornado/ioloop.py", line 905, in _run
    return self.callback()
  File "/usr/local/lib/python3.9/site-packages/livereload/handlers.py", line 69, in poll_tasks
    filepath, delay = cls.watcher.examine()
  File "/usr/local/lib/python3.9/site-packages/livereload/watcher.py", line 119, in examine
    func()
  File "/usr/local/lib/python3.9/site-packages/mkdocs/commands/serve.py", line 136, in builder
    build(config, live_server=live_server, dirty=dirty)
  File "/usr/local/lib/python3.9/site-packages/mkdocs/commands/build.py", line 288, in build
    _build_theme_template(template, env, files, config, nav)
  File "/usr/local/lib/python3.9/site-packages/mkdocs/commands/build.py", line 114, in _build_theme_template
    output = _build_template(template_name, template, files, config, nav)
  File "/usr/local/lib/python3.9/site-packages/mkdocs/commands/build.py", line 93, in _build_template
    output = template.render(context)
  File "/usr/local/lib/python3.9/site-packages/jinja2/environment.py", line 1090, in render
    self.environment.handle_exception()
  File "/usr/local/lib/python3.9/site-packages/jinja2/environment.py", line 832, in handle_exception
    reraise(*rewrite_traceback_stack(source=source))
  File "/usr/local/lib/python3.9/site-packages/jinja2/_compat.py", line 28, in reraise
    raise value.with_traceback(tb)
  File "/usr/local/lib/python3.9/site-packages/material/404.html", line 4, in top-level template code
    {% extends "base.html" %}
  File "/usr/local/lib/python3.9/site-packages/material/base.html", line 176, in top-level template code
    {% block footer %}
  File "/usr/local/lib/python3.9/site-packages/material/base.html", line 177, in block "footer"
    {% include "partials/footer.html" %}
  File "/usr/local/lib/python3.9/site-packages/material/partials/footer.html", line 55, in top-level template code
    {% include "partials/social.html" %}
  File "/usr/local/lib/python3.9/site-packages/material/partials/social.html", line 10, in top-level template code
    {% include ".icons/" ~ social.icon ~ ".svg" %}
  File "/usr/local/lib/python3.9/site-packages/jinja2/loaders.py", line 197, in get_source
    raise TemplateNotFound(template)
jinja2.exceptions.TemplateNotFound: .icons/.svg

@BrandonE
Copy link
Author

BrandonE commented Mar 13, 2021

I can now see that this particular error is the same as this one: #1600 - I can now get mkdocs to serve again. Sorry for not properly following the migration documents; it can get confusing which part of the file I neglected to update when the error messages are hard to make sense of.

Edit: The advice provided earlier for hiding the clipboard now works! Thanks!

@facelessuser
Copy link
Contributor

Sorry for not properly following the migration documents; it can get confusing which part of the file I neglected to update when the error messages are hard to make sense of.

Yeah, this can be a little annoying that you can't always get sane errors when a configuration issue arises. I know when I migrated I ran into that same issue.

@squidfunk
Copy link
Owner

@facelessuser from the comments, I read that { ... } is generally favored over {: ... }? Thus, it's safer to switch to the former? If so, we should definitely do this for the whole project.

@facelessuser
Copy link
Contributor

Let me be clear, attr_list supports the legacy behavior of using :. I'm not sure where this legacy behavior comes from.

fenced_code never supported :. Probably because : is a legacy behavior. SuperFences, which is modeled after fenced_code, also does not support it.

It happens to work if you use a space just because how attr_list handles the content, but that is not intentional behavior.

Is this a little confusing? Yup.

In general, it is probably less confusing to just never use : with attr_list, even if it is supported formally in some cases.

@squidfunk
Copy link
Owner

Thanks for the explanation! Fixed all occurrences in e9c5b53.

@squidfunk
Copy link
Owner

Fixed in 128e267. As of Material for MkDocs 9, the copy-to-clipboard button will be opt-in. It can be enabled globally via a new feature flag called content.code.copy, or per-block by setting the .copy class on the block. When enabled globally, the clipboard button can be removed selectively for a specific code block with .no-copy.

@squidfunk squidfunk added the resolved Issue is resolved, yet unreleased if open label Nov 12, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
change request Issue requests a new feature or improvement resolved Issue is resolved, yet unreleased if open
Projects
None yet
Development

No branches or pull requests

4 participants