google / mesop

Rapidly build AI apps in Python
https://google.github.io/mesop/
Apache License 2.0
5.63k stars 269 forks source link

Provide syntax highlighting in markdown code blocks #96

Closed wwwillchen closed 6 months ago

wwwillchen commented 7 months ago

Potential API:

me.code(language="python")

Prior Art:

richard-to commented 7 months ago

Related (or maybe also related to the Markdown style issue), is that we should also add horizontal scroll for the code blocks. Right now they just overflow outside the layout.

wwwillchen commented 6 months ago

See #203

Potential way of supporting copy to clipboard using Python-markdown:


To add a "Copy to Clipboard" button using Python-markdown, you can create a custom extension that renders the button and associates it with the code block. Here's an example of how you can achieve this:

  1. Create a custom Markdown extension:
    
    from markdown.extensions import Extension
    from markdown.preprocessors import Preprocessor

class CopyButtonExtension(Extension): def extendMarkdown(self, md): md.preprocessors.register(CopyButtonPreprocessor(md), 'copy_button', 25)

class CopyButtonPreprocessor(Preprocessor): def run(self, lines): new_lines = [] for line in lines: if line.startswith(''): new_lines.append(line) if not line.endswith(''): new_lines.append('') else: new_lines.append(line) return new_lines


2. Update the `markdown_to_html` function to include the custom extension:
```python
def markdown_to_html(md_text):
    md = markdown.Markdown(extensions=['codehilite', 'fenced_code', 'tables', CopyButtonExtension()])
    md.preprocessors['code_highlight'] = code_highlight
    html = md.convert(md_text)
    return html
  1. Add the necessary JavaScript function to handle the copy functionality:

    <script>
    function copyCode(button) {
    var codeBlock = button.previousElementSibling;
    var code = codeBlock.innerText;
    
    var tempTextarea = document.createElement('textarea');
    tempTextarea.value = code;
    document.body.appendChild(tempTextarea);
    tempTextarea.select();
    document.execCommand('copy');
    document.body.removeChild(tempTextarea);
    
    button.innerText = 'Copied!';
    setTimeout(function() {
        button.innerText = 'Copy';
    }, 2000);
    }
    </script>
  2. Add some CSS styles for the copy button:

    <style>
    .copy-button {
    position: relative;
    float: right;
    margin-top: -30px;
    margin-right: 10px;
    padding: 5px 10px;
    background-color: #f0f0f0;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    }
    </style>
  3. Update the Markdown text to include code blocks:

    
    md_text = '''
    # Example Markdown

This is an example of using Pygments and Python-markdown together.

def hello_world():
    print("Hello, World!")
Column 1 Column 2
Row 1 Value 1
Row 2 Value 2

'''


6. Generate the HTML output:
```python
html_output = markdown_to_html(md_text)
print(html_output)

Now, when you run the script, it will generate HTML output with a "Copy to Clipboard" button next to each code block. Clicking the button will copy the code to the clipboard and display a "Copied!" message for a short duration.

Note: Make sure to include the necessary JavaScript function and CSS styles in your HTML template or file to ensure the copy functionality and button styling work as expected.