from django.db import models from pygments.lexers import get_all_lexers from pygments.styles import get_all_styles from pygments.lexers import get_lexer_by_name from pygments.formatters.html import HtmlFormatter from pygments import highlight LEXERS = [item for item in get_all_lexers() if item[1]] LANGUAGE_CHOICES = sorted([(item[1][0], item[0]) for item in LEXERS]) STYLE_CHOICES = sorted([(item, item) for item in get_all_styles()]) ACCESS_TYPES = (("public", "Public"), ("private", "Private"), ("owner-only", "Owner only")) class Snippet(models.Model): created = models.DateTimeField(auto_now_add=True) title = models.CharField(max_length=100, blank=True, default='') content = models.TextField() linenos = models.BooleanField(default=False) language = models.CharField(choices=LANGUAGE_CHOICES, default='python', max_length=100) style = models.CharField(choices=STYLE_CHOICES, default='friendly', max_length=100) highlighted = models.TextField() owner = models.ForeignKey( verbose_name="Snippet owner", to="auth.User", on_delete=models.CASCADE ) access = models.CharField( verbose_name="Access type", choices=ACCESS_TYPES, default="private", max_length=20 ) def save(self, *args, **kwargs): """ Use the `pygments` library to create a highlighted HTML representation of the code snippet. """ lexer = get_lexer_by_name(self.language) linenos = 'table' if self.linenos else False options = {'title': self.title} if self.title else {} formatter = HtmlFormatter( style=self.style, linenos=linenos, full=True, **options ) self.highlighted = highlight(self.content, lexer, formatter) super().save(*args, **kwargs) class Meta: ordering = ['created'] class SnippetParticipant(models.Model): id = models.IntegerField( verbose_name="ID", primary_key=True ) user = models.ForeignKey( verbose_name="Associated User", to="auth.User", on_delete=models.CASCADE ) snippet = models.ForeignKey( verbose_name="Associated Snippet", to=Snippet, on_delete=models.CASCADE )