# HG changeset patch # User dellsystem # Date 1346396002 14400 # Node ID f872c643b056be7885ae30bf545e3165feb15514 # Parent a8da60d611f717f2ff99bd155e8d2de1d6fe5bc9 Updates to snippet functionality (see details) Sorry about the large commit, but it was difficult to break it up as a lot of new functionality was introduced. Most of it is specific to the snippet feature but there are some other changes as well. Commit highlights: * Added the ability to switch the syntax highlighting colour scheme when viewing a snippet. This is currently done on a per-snippet basis only, but eventually it will be possible to set a default in your profile to have all the snippets you view use that colour scheme. There are currently 8 different colour schemes, all of which were taken from the default pygments stylesheets (some were modified). * Added a "num_views" field to the Snippet model, with the field being incremented any time the snippet view is called (raw or regular view). * Created a simple "explore" view that lists the recently-posted snippets. Will implement pagination and sorting by other attributes ("popularity", for example, based on number of views) as well. * Added a post-save hook to the User model to ensure that a Profile is created for every user as soon as the User itself is created. This alleviates the need for a get_profile method that checks if the user has a profile or not and creates one if necessary. (The code is currently still there, will be cleaned up soon). * Added back the wordwrap toggling feature. Currently, if you want to enable word-wrapping, the line numbers have to be hidden in order to ensure that the lines and their numbers don't go out of sync. This will be fixed soon. * History/diff view is back * And some other minor cosmetic changes. Note: since some existing models have been changed, you'll likely need to delete the existing sqlite database before running syncdb. The alternative is to determine the necessary column changes/additions and run the SQL query yourself. diff --git a/apps/profile/models.py b/apps/profile/models.py --- a/apps/profile/models.py +++ b/apps/profile/models.py @@ -2,13 +2,24 @@ from django.contrib.auth.models import User from agora.apps.free_license.models import FreeLicense +from agora.apps.pygments_style.models import PygmentsStyle class Profile(models.Model): user = models.OneToOneField(User) - preferred_license = models.ForeignKey(FreeLicense) - interests = models.CharField(max_length=512) - blurb = models.TextField(max_length=16384) + preferred_license = models.ForeignKey(FreeLicense, default=1) + interests = models.CharField(max_length=512, null=True, blank=True) + blurb = models.TextField(max_length=16384, null=True, blank=True) + pygments_style = models.ForeignKey(PygmentsStyle, default=1) def __unicode__(self): return self.user.username + + +# Defines a post_save hook to ensure that a profile is created for each user +# This also ensures that the admin user (created when running syncdb) has one +def create_user_profile(sender, instance, created, **kwards): + if created: + Profile.objects.create(user=instance) + +models.signals.post_save.connect(create_user_profile, sender=User) diff --git a/apps/pygments_style/__init__.py b/apps/pygments_style/__init__.py new file mode 100644 diff --git a/apps/pygments_style/fixtures/initial_data.json b/apps/pygments_style/fixtures/initial_data.json new file mode 100644 --- /dev/null +++ b/apps/pygments_style/fixtures/initial_data.json @@ -0,0 +1,66 @@ +[ + { + "pk": 1, + "model": "pygments_style.pygmentsstyle", + "fields": { + "class_name": "tango", + "description": null + } + }, + { + "pk": 2, + "model": "pygments_style.pygmentsstyle", + "fields": { + "class_name": "autumn", + "description": null + } + }, + { + "pk": 3, + "model": "pygments_style.pygmentsstyle", + "fields": { + "class_name": "borland", + "description": null + } + }, + { + "pk": 4, + "model": "pygments_style.pygmentsstyle", + "fields": { + "class_name": "fruity", + "description": null + } + }, + { + "pk": 5, + "model": "pygments_style.pygmentsstyle", + "fields": { + "class_name": "monokai", + "description": null + } + }, + { + "pk": 6, + "model": "pygments_style.pygmentsstyle", + "fields": { + "class_name": "native", + "description": null + } + }, + { + "pk": 7, + "model": "pygments_style.pygmentsstyle", + "fields": { + "class_name": "vs", + "description": null + } + }, + { + "pk": 8, + "model": "pygments_style.pygmentsstyle", + "fields": { + "class_name": "vibrant", + "description": null + } + } +] \ No newline at end of file diff --git a/apps/pygments_style/models.py b/apps/pygments_style/models.py new file mode 100644 --- /dev/null +++ b/apps/pygments_style/models.py @@ -0,0 +1,16 @@ +from django.db import models + + +class PygmentsStyle(models.Model): + """ + For allowing users to choose between syntax highlighting styles. + + Affects viewing snippets but not creating them. Users can set a + default and can change the style when viewing specific snippets or + files if necessary. + """ + class_name = models.CharField(max_length=20) + description = models.TextField(null=True, blank=True) + + def __unicode__(self): + return self.class_name diff --git a/apps/snippet/models.py b/apps/snippet/models.py --- a/apps/snippet/models.py +++ b/apps/snippet/models.py @@ -30,6 +30,7 @@ expires = models.DateTimeField(_(u'Expires'), blank=True, help_text='asdf') parent = models.ForeignKey('self', null=True, blank=True, related_name='children') + num_views = models.IntegerField(default=0) class Meta: ordering = ('-published',) diff --git a/apps/snippet/views.py b/apps/snippet/views.py --- a/apps/snippet/views.py +++ b/apps/snippet/views.py @@ -1,7 +1,7 @@ import difflib from django.shortcuts import render_to_response, \ - get_object_or_404, get_list_or_404 + get_object_or_404, get_list_or_404, render from django.template.context \ import RequestContext from django.http \ @@ -21,7 +21,11 @@ def snippet_explore(request): - pass + context = { + 'recent_snippets': Snippet.objects.all()[:20] + } + + return render(request, 'snippet/explore.html', context) def snippet_new(request, template_name='snippet/snippet_new.djhtml'): @@ -59,12 +63,15 @@ is_raw=False): snippet = get_object_or_404(Snippet, secret_id=snippet_id) + snippet.num_views += 1 + snippet.save() tree = snippet.get_root() tree = tree.get_descendants(include_self=True) new_snippet_initial = { 'content': snippet.content, + 'lexer': snippet.lexer, } if request.method == "POST": @@ -75,7 +82,13 @@ request, new_snippet = snippet_form.save(parent=snippet) return HttpResponseRedirect(new_snippet.get_absolute_url()) else: - snippet_form = SnippetForm(initial=new_snippet_initial, request=request) + snippet_form = SnippetForm(initial=new_snippet_initial, + request=request) + + if request.user.is_authenticated(): + default_pygments_style = request.user.get_profile().pygments_style + else: + default_pygments_style = PygmentsStyle.objects.get(pk=1) template_context = { 'snippet_form': snippet_form, @@ -83,6 +96,9 @@ 'lines': range(snippet.get_linecount()), 'tree': tree, 'language': dict(LEXER_LIST)[snippet.lexer], + 'pygments_styles': PygmentsStyle.objects.all(), + 'default_style': default_pygments_style, + 'no_descendants': len(tree) == 1, } response = render_to_response( diff --git a/settings.py b/settings.py --- a/settings.py +++ b/settings.py @@ -144,6 +144,7 @@ 'agora.apps.snippet', 'agora.apps.bundle', 'agora.apps.free_license', + 'agora.apps.pygments_style', 'agora.apps.mptt', ) diff --git a/static/css/agora.less b/static/css/agora.less --- a/static/css/agora.less +++ b/static/css/agora.less @@ -146,6 +146,7 @@ #breadcrumbs { border-bottom: 1px solid @lightGrey; margin-bottom: 10px; + padding-bottom: 5px; } #info-box { @@ -202,10 +203,11 @@ } #sidebar { - width: @sidebarWidth - @sidebarPadding * 2; + margin-top: 10px; + width: @sidebarWidth - @sidebarPadding * 2 - 2; + border: 1px solid @lightGrey; padding: @sidebarPadding; - min-height: 300px; - background: @lighterGrey; + background: @offWhite; .inline-block; } @@ -219,15 +221,47 @@ .hint { border: 1px solid @lightBlue; background: lighten(@mediumBlue, 40%); - padding-left: 10px; + padding: 10px; margin-bottom: 10px; - padding-top: 10px; } hr { border: 0; border-top: 1px solid @mediumGrey; - & + p { - margin-top: 10px; + margin: 5px 0; +} + +.tree { + ul { + list-style-type: none; } } + +#diff { + .hidden; + border: 1px solid @lightGrey; + padding: 10px; + background: @offWhite; + + .gi { + background: #DFD; + } + + .gu { + color: @mediumGrey; + } + + .gd { + background: #FDD; + } +} + +table &.default { + width: 100%; + border: 1px solid @lightGrey; + + thead th { + padding: 5px 0; + border-bottom: 1px solid @lightGrey; + } +} diff --git a/static/css/code.less b/static/css/code.less --- a/static/css/code.less +++ b/static/css/code.less @@ -1,1 +1,27 @@ -// Nothing yet +// For all syntax-highlighted code +.highlight { + width: 650px; + padding: 10px; + .border-radius(7px); + overflow-x: auto; + border: 1px solid @lightGrey; + + &.wrap { + white-space: pre-wrap; + width: 688px; + } +} + +.numbers, .highlight { + line-height: 18px; +} + +#line-numbers { + vertical-align: top; + padding-top: 11px; + width: 40px; +} + +.snippet table { + border-spacing: 0; +} diff --git a/static/css/code/autumn.less b/static/css/code/autumn.less new file mode 100644 --- /dev/null +++ b/static/css/code/autumn.less @@ -0,0 +1,60 @@ +.highlight &.autumn { + .hll { background-color: #ffffcc } + .c { color: #aaaaaa; font-style: italic } /* Comment */ + .err { color: #F00000; background-color: #F0A0A0 } /* Error */ + .k { color: #0000aa } /* Keyword */ + .cm { color: #aaaaaa; font-style: italic } /* Comment.Multiline */ + .cp { color: #4c8317 } /* Comment.Preproc */ + .c1 { color: #aaaaaa; font-style: italic } /* Comment.Single */ + .cs { color: #0000aa; font-style: italic } /* Comment.Special */ + .gd { color: #aa0000 } /* Generic.Deleted */ + .ge { font-style: italic } /* Generic.Emph */ + .gr { color: #aa0000 } /* Generic.Error */ + .gh { color: #000080; font-weight: bold } /* Generic.Heading */ + .gi { color: #00aa00 } /* Generic.Inserted */ + .go { color: #888888 } /* Generic.Output */ + .gp { color: #555555 } /* Generic.Prompt */ + .gs { font-weight: bold } /* Generic.Strong */ + .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ + .gt { color: #aa0000 } /* Generic.Traceback */ + .kc { color: #0000aa } /* Keyword.Constant */ + .kd { color: #0000aa } /* Keyword.Declaration */ + .kn { color: #0000aa } /* Keyword.Namespace */ + .kp { color: #0000aa } /* Keyword.Pseudo */ + .kr { color: #0000aa } /* Keyword.Reserved */ + .kt { color: #00aaaa } /* Keyword.Type */ + .m { color: #009999 } /* Literal.Number */ + .s { color: #aa5500 } /* Literal.String */ + .na { color: #1e90ff } /* Name.Attribute */ + .nb { color: #00aaaa } /* Name.Builtin */ + .nc { color: #00aa00; text-decoration: underline } /* Name.Class */ + .no { color: #aa0000 } /* Name.Constant */ + .nd { color: #888888 } /* Name.Decorator */ + .ni { color: #800000; font-weight: bold } /* Name.Entity */ + .nf { color: #00aa00 } /* Name.Function */ + .nn { color: #00aaaa; text-decoration: underline } /* Name.Namespace */ + .nt { color: #1e90ff; font-weight: bold } /* Name.Tag */ + .nv { color: #aa0000 } /* Name.Variable */ + .ow { color: #0000aa } /* Operator.Word */ + .w { color: #bbbbbb } /* Text.Whitespace */ + .mf { color: #009999 } /* Literal.Number.Float */ + .mh { color: #009999 } /* Literal.Number.Hex */ + .mi { color: #009999 } /* Literal.Number.Integer */ + .mo { color: #009999 } /* Literal.Number.Oct */ + .sb { color: #aa5500 } /* Literal.String.Backtick */ + .sc { color: #aa5500 } /* Literal.String.Char */ + .sd { color: #aa5500 } /* Literal.String.Doc */ + .s2 { color: #aa5500 } /* Literal.String.Double */ + .se { color: #aa5500 } /* Literal.String.Escape */ + .sh { color: #aa5500 } /* Literal.String.Heredoc */ + .si { color: #aa5500 } /* Literal.String.Interpol */ + .sx { color: #aa5500 } /* Literal.String.Other */ + .sr { color: #009999 } /* Literal.String.Regex */ + .s1 { color: #aa5500 } /* Literal.String.Single */ + .ss { color: #0000aa } /* Literal.String.Symbol */ + .bp { color: #00aaaa } /* Name.Builtin.Pseudo */ + .vc { color: #aa0000 } /* Name.Variable.Class */ + .vg { color: #aa0000 } /* Name.Variable.Global */ + .vi { color: #aa0000 } /* Name.Variable.Instance */ + .il { color: #009999 } /* Literal.Number.Integer.Long */ +} diff --git a/static/css/code/borland.less b/static/css/code/borland.less new file mode 100644 --- /dev/null +++ b/static/css/code/borland.less @@ -0,0 +1,48 @@ +.highlight &.borland { + .hll { background-color: #ffffcc } + .c { color: #008800; font-style: italic } /* Comment */ + .err { color: #a61717; background-color: #e3d2d2 } /* Error */ + .k { color: #000080; font-weight: bold } /* Keyword */ + .cm { color: #008800; font-style: italic } /* Comment.Multiline */ + .cp { color: #008080 } /* Comment.Preproc */ + .c1 { color: #008800; font-style: italic } /* Comment.Single */ + .cs { color: #008800; font-weight: bold } /* Comment.Special */ + .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ + .ge { font-style: italic } /* Generic.Emph */ + .gr { color: #aa0000 } /* Generic.Error */ + .gh { color: #999999 } /* Generic.Heading */ + .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ + .go { color: #888888 } /* Generic.Output */ + .gp { color: #555555 } /* Generic.Prompt */ + .gs { font-weight: bold } /* Generic.Strong */ + .gu { color: #aaaaaa } /* Generic.Subheading */ + .gt { color: #aa0000 } /* Generic.Traceback */ + .kc { color: #000080; font-weight: bold } /* Keyword.Constant */ + .kd { color: #000080; font-weight: bold } /* Keyword.Declaration */ + .kn { color: #000080; font-weight: bold } /* Keyword.Namespace */ + .kp { color: #000080; font-weight: bold } /* Keyword.Pseudo */ + .kr { color: #000080; font-weight: bold } /* Keyword.Reserved */ + .kt { color: #000080; font-weight: bold } /* Keyword.Type */ + .m { color: #0000FF } /* Literal.Number */ + .s { color: #0000FF } /* Literal.String */ + .na { color: #FF0000 } /* Name.Attribute */ + .nt { color: #000080; font-weight: bold } /* Name.Tag */ + .ow { font-weight: bold } /* Operator.Word */ + .w { color: #bbbbbb } /* Text.Whitespace */ + .mf { color: #0000FF } /* Literal.Number.Float */ + .mh { color: #0000FF } /* Literal.Number.Hex */ + .mi { color: #0000FF } /* Literal.Number.Integer */ + .mo { color: #0000FF } /* Literal.Number.Oct */ + .sb { color: #0000FF } /* Literal.String.Backtick */ + .sc { color: #800080 } /* Literal.String.Char */ + .sd { color: #0000FF } /* Literal.String.Doc */ + .s2 { color: #0000FF } /* Literal.String.Double */ + .se { color: #0000FF } /* Literal.String.Escape */ + .sh { color: #0000FF } /* Literal.String.Heredoc */ + .si { color: #0000FF } /* Literal.String.Interpol */ + .sx { color: #0000FF } /* Literal.String.Other */ + .sr { color: #0000FF } /* Literal.String.Regex */ + .s1 { color: #0000FF } /* Literal.String.Single */ + .ss { color: #0000FF } /* Literal.String.Symbol */ + .il { color: #0000FF } /* Literal.Number.Integer.Long */ +} diff --git a/static/css/code/fruity.less b/static/css/code/fruity.less new file mode 100644 --- /dev/null +++ b/static/css/code/fruity.less @@ -0,0 +1,73 @@ +.highlight &.fruity { + background: @almostBlack; + + .hll { background-color: #333333 } + .c { color: #008800; font-style: italic; } /* Comment */ + .err { color: #ffffff } /* Error */ + .g { color: #ffffff } /* Generic */ + .k { color: #fb660a; font-weight: bold } /* Keyword */ + .l { color: #ffffff } /* Literal */ + .n { color: #ffffff } /* Name */ + .o { color: #ffffff } /* Operator */ + .x { color: #ffffff } /* Other */ + .p { color: #ffffff } /* Punctuation */ + .cm { color: #008800; font-style: italic; } /* Comment.Multiline */ + .cp { color: #ff0007; font-weight: bold; font-style: italic; } /* Comment.Preproc */ + .c1 { color: #008800; font-style: italic; } /* Comment.Single */ + .cs { color: #008800; font-style: italic; } /* Comment.Special */ + .gd { color: #ffffff } /* Generic.Deleted */ + .ge { color: #ffffff } /* Generic.Emph */ + .gr { color: #ffffff } /* Generic.Error */ + .gh { color: #ffffff; font-weight: bold } /* Generic.Heading */ + .gi { color: #ffffff } /* Generic.Inserted */ + .go { color: #444444; background-color: #222222 } /* Generic.Output */ + .gp { color: #ffffff } /* Generic.Prompt */ + .gs { color: #ffffff } /* Generic.Strong */ + .gu { color: #ffffff; font-weight: bold } /* Generic.Subheading */ + .gt { color: #ffffff } /* Generic.Traceback */ + .kc { color: #fb660a; font-weight: bold } /* Keyword.Constant */ + .kd { color: #fb660a; font-weight: bold } /* Keyword.Declaration */ + .kn { color: #fb660a; font-weight: bold } /* Keyword.Namespace */ + .kp { color: #fb660a } /* Keyword.Pseudo */ + .kr { color: #fb660a; font-weight: bold } /* Keyword.Reserved */ + .kt { color: #cdcaa9; font-weight: bold } /* Keyword.Type */ + .ld { color: #ffffff } /* Literal.Date */ + .m { color: #0086f7; font-weight: bold } /* Literal.Number */ + .s { color: #0086d2 } /* Literal.String */ + .na { color: #ff0086; font-weight: bold } /* Name.Attribute */ + .nb { color: #ffffff } /* Name.Builtin */ + .nc { color: #ffffff } /* Name.Class */ + .no { color: #0086d2 } /* Name.Constant */ + .nd { color: #ffffff } /* Name.Decorator */ + .ni { color: #ffffff } /* Name.Entity */ + .ne { color: #ffffff } /* Name.Exception */ + .nf { color: #ff0086; font-weight: bold } /* Name.Function */ + .nl { color: #ffffff } /* Name.Label */ + .nn { color: #ffffff } /* Name.Namespace */ + .nx { color: #ffffff } /* Name.Other */ + .py { color: #ffffff } /* Name.Property */ + .nt { color: #fb660a; font-weight: bold } /* Name.Tag */ + .nv { color: #fb660a } /* Name.Variable */ + .ow { color: #ffffff } /* Operator.Word */ + .w { color: #888888 } /* Text.Whitespace */ + .mf { color: #0086f7; font-weight: bold } /* Literal.Number.Float */ + .mh { color: #0086f7; font-weight: bold } /* Literal.Number.Hex */ + .mi { color: #0086f7; font-weight: bold } /* Literal.Number.Integer */ + .mo { color: #0086f7; font-weight: bold } /* Literal.Number.Oct */ + .sb { color: #0086d2 } /* Literal.String.Backtick */ + .sc { color: #0086d2 } /* Literal.String.Char */ + .sd { color: #0086d2 } /* Literal.String.Doc */ + .s2 { color: #0086d2 } /* Literal.String.Double */ + .se { color: #0086d2 } /* Literal.String.Escape */ + .sh { color: #0086d2 } /* Literal.String.Heredoc */ + .si { color: #0086d2 } /* Literal.String.Interpol */ + .sx { color: #0086d2 } /* Literal.String.Other */ + .sr { color: #0086d2 } /* Literal.String.Regex */ + .s1 { color: #0086d2 } /* Literal.String.Single */ + .ss { color: #0086d2 } /* Literal.String.Symbol */ + .bp { color: #ffffff } /* Name.Builtin.Pseudo */ + .vc { color: #fb660a } /* Name.Variable.Class */ + .vg { color: #fb660a } /* Name.Variable.Global */ + .vi { color: #fb660a } /* Name.Variable.Instance */ + .il { color: #0086f7; font-weight: bold } /* Literal.Number.Integer.Long */ +} diff --git a/static/css/code/monokai.less b/static/css/code/monokai.less new file mode 100644 --- /dev/null +++ b/static/css/code/monokai.less @@ -0,0 +1,64 @@ +.highlight &.monokai { + background: #272822; + color: #F8F8F2; + + .hll { background-color: #49483e } + .c { color: #75715e } /* Comment */ + .err { color: #960050; background-color: #1e0010 } /* Error */ + .k { color: #66d9ef } /* Keyword */ + .l { color: #ae81ff } /* Literal */ + .n { color: #f8f8f2 } /* Name */ + .o { color: #f92672 } /* Operator */ + .p { color: #f8f8f2 } /* Punctuation */ + .cm { color: #75715e } /* Comment.Multiline */ + .cp { color: #75715e } /* Comment.Preproc */ + .c1 { color: #75715e } /* Comment.Single */ + .cs { color: #75715e } /* Comment.Special */ + .ge { font-style: italic } /* Generic.Emph */ + .gs { font-weight: bold } /* Generic.Strong */ + .kc { color: #66d9ef } /* Keyword.Constant */ + .kd { color: #66d9ef } /* Keyword.Declaration */ + .kn { color: #f92672 } /* Keyword.Namespace */ + .kp { color: #66d9ef } /* Keyword.Pseudo */ + .kr { color: #66d9ef } /* Keyword.Reserved */ + .kt { color: #66d9ef } /* Keyword.Type */ + .ld { color: #e6db74 } /* Literal.Date */ + .m { color: #ae81ff } /* Literal.Number */ + .s { color: #e6db74 } /* Literal.String */ + .na { color: #a6e22e } /* Name.Attribute */ + .nb { color: #f8f8f2 } /* Name.Builtin */ + .nc { color: #a6e22e } /* Name.Class */ + .no { color: #66d9ef } /* Name.Constant */ + .nd { color: #a6e22e } /* Name.Decorator */ + .ni { color: #f8f8f2 } /* Name.Entity */ + .ne { color: #a6e22e } /* Name.Exception */ + .nf { color: #a6e22e } /* Name.Function */ + .nl { color: #f8f8f2 } /* Name.Label */ + .nn { color: #f8f8f2 } /* Name.Namespace */ + .nx { color: #a6e22e } /* Name.Other */ + .py { color: #f8f8f2 } /* Name.Property */ + .nt { color: #f92672 } /* Name.Tag */ + .nv { color: #f8f8f2 } /* Name.Variable */ + .ow { color: #f92672 } /* Operator.Word */ + .w { color: #f8f8f2 } /* Text.Whitespace */ + .mf { color: #ae81ff } /* Literal.Number.Float */ + .mh { color: #ae81ff } /* Literal.Number.Hex */ + .mi { color: #ae81ff } /* Literal.Number.Integer */ + .mo { color: #ae81ff } /* Literal.Number.Oct */ + .sb { color: #e6db74 } /* Literal.String.Backtick */ + .sc { color: #e6db74 } /* Literal.String.Char */ + .sd { color: #e6db74 } /* Literal.String.Doc */ + .s2 { color: #e6db74 } /* Literal.String.Double */ + .se { color: #ae81ff } /* Literal.String.Escape */ + .sh { color: #e6db74 } /* Literal.String.Heredoc */ + .si { color: #e6db74 } /* Literal.String.Interpol */ + .sx { color: #e6db74 } /* Literal.String.Other */ + .sr { color: #e6db74 } /* Literal.String.Regex */ + .s1 { color: #e6db74 } /* Literal.String.Single */ + .ss { color: #e6db74 } /* Literal.String.Symbol */ + .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */ + .vc { color: #f8f8f2 } /* Name.Variable.Class */ + .vg { color: #f8f8f2 } /* Name.Variable.Global */ + .vi { color: #f8f8f2 } /* Name.Variable.Instance */ + .il { color: #ae81ff } /* Literal.Number.Integer.Long */ +} diff --git a/static/css/code/native.less b/static/css/code/native.less new file mode 100644 --- /dev/null +++ b/static/css/code/native.less @@ -0,0 +1,73 @@ +.highlight &.native { + background: @almostBlack; + + .hll { background-color: #404040 } + .c { color: #999999; font-style: italic } /* Comment */ + .err { color: #a61717; background-color: #e3d2d2 } /* Error */ + .g { color: #d0d0d0 } /* Generic */ + .k { color: #6ab825; font-weight: bold } /* Keyword */ + .l { color: #d0d0d0 } /* Literal */ + .n { color: #d0d0d0 } /* Name */ + .o { color: #d0d0d0 } /* Operator */ + .x { color: #d0d0d0 } /* Other */ + .p { color: #d0d0d0 } /* Punctuation */ + .cm { color: #999999; font-style: italic } /* Comment.Multiline */ + .cp { color: #cd2828; font-weight: bold } /* Comment.Preproc */ + .c1 { color: #999999; font-style: italic } /* Comment.Single */ + .cs { color: #e50808; font-weight: bold; background-color: #520000 } /* Comment.Special */ + .gd { color: #d22323 } /* Generic.Deleted */ + .ge { color: #d0d0d0; font-style: italic } /* Generic.Emph */ + .gr { color: #d22323 } /* Generic.Error */ + .gh { color: #ffffff; font-weight: bold } /* Generic.Heading */ + .gi { color: #589819 } /* Generic.Inserted */ + .go { color: #cccccc } /* Generic.Output */ + .gp { color: #aaaaaa } /* Generic.Prompt */ + .gs { color: #d0d0d0; font-weight: bold } /* Generic.Strong */ + .gu { color: #ffffff; text-decoration: underline } /* Generic.Subheading */ + .gt { color: #d22323 } /* Generic.Traceback */ + .kc { color: #6ab825; font-weight: bold } /* Keyword.Constant */ + .kd { color: #6ab825; font-weight: bold } /* Keyword.Declaration */ + .kn { color: #6ab825; font-weight: bold } /* Keyword.Namespace */ + .kp { color: #6ab825 } /* Keyword.Pseudo */ + .kr { color: #6ab825; font-weight: bold } /* Keyword.Reserved */ + .kt { color: #6ab825; font-weight: bold } /* Keyword.Type */ + .ld { color: #d0d0d0 } /* Literal.Date */ + .m { color: #3677a9 } /* Literal.Number */ + .s { color: #ed9d13 } /* Literal.String */ + .na { color: #bbbbbb } /* Name.Attribute */ + .nb { color: #24909d } /* Name.Builtin */ + .nc { color: #447fcf; text-decoration: underline } /* Name.Class */ + .no { color: #40ffff } /* Name.Constant */ + .nd { color: #ffa500 } /* Name.Decorator */ + .ni { color: #d0d0d0 } /* Name.Entity */ + .ne { color: #bbbbbb } /* Name.Exception */ + .nf { color: #447fcf } /* Name.Function */ + .nl { color: #d0d0d0 } /* Name.Label */ + .nn { color: #447fcf; text-decoration: underline } /* Name.Namespace */ + .nx { color: #d0d0d0 } /* Name.Other */ + .py { color: #d0d0d0 } /* Name.Property */ + .nt { color: #6ab825; font-weight: bold } /* Name.Tag */ + .nv { color: #40ffff } /* Name.Variable */ + .ow { color: #6ab825; font-weight: bold } /* Operator.Word */ + .w { color: #666666 } /* Text.Whitespace */ + .mf { color: #3677a9 } /* Literal.Number.Float */ + .mh { color: #3677a9 } /* Literal.Number.Hex */ + .mi { color: #3677a9 } /* Literal.Number.Integer */ + .mo { color: #3677a9 } /* Literal.Number.Oct */ + .sb { color: #ed9d13 } /* Literal.String.Backtick */ + .sc { color: #ed9d13 } /* Literal.String.Char */ + .sd { color: #ed9d13 } /* Literal.String.Doc */ + .s2 { color: #ed9d13 } /* Literal.String.Double */ + .se { color: #ed9d13 } /* Literal.String.Escape */ + .sh { color: #ed9d13 } /* Literal.String.Heredoc */ + .si { color: #ed9d13 } /* Literal.String.Interpol */ + .sx { color: #ffa500 } /* Literal.String.Other */ + .sr { color: #ed9d13 } /* Literal.String.Regex */ + .s1 { color: #ed9d13 } /* Literal.String.Single */ + .ss { color: #ed9d13 } /* Literal.String.Symbol */ + .bp { color: #24909d } /* Name.Builtin.Pseudo */ + .vc { color: #40ffff } /* Name.Variable.Class */ + .vg { color: #40ffff } /* Name.Variable.Global */ + .vi { color: #40ffff } /* Name.Variable.Instance */ + .il { color: #3677a9 } /* Literal.Number.Integer.Long */ +} diff --git a/static/css/code/tango.less b/static/css/code/tango.less new file mode 100644 --- /dev/null +++ b/static/css/code/tango.less @@ -0,0 +1,71 @@ +.highlight &.tango { + .hll { background-color: #ffffcc } + .c { color: #8f5902; font-style: italic } /* Comment */ + .err { color: #a40000; border: 1px solid #ef2929 } /* Error */ + .g { color: #000000 } /* Generic */ + .k { color: #204a87; font-weight: bold } /* Keyword */ + .l { color: #000000 } /* Literal */ + .n { color: #000000 } /* Name */ + .o { color: #ce5c00; font-weight: bold } /* Operator */ + .x { color: #000000 } /* Other */ + .p { color: #000000; font-weight: bold } /* Punctuation */ + .cm { color: #8f5902; font-style: italic } /* Comment.Multiline */ + .cp { color: #8f5902; font-style: italic } /* Comment.Preproc */ + .c1 { color: #8f5902; font-style: italic } /* Comment.Single */ + .cs { color: #8f5902; font-style: italic } /* Comment.Special */ + .gd { color: #a40000 } /* Generic.Deleted */ + .ge { color: #000000; font-style: italic } /* Generic.Emph */ + .gr { color: #ef2929 } /* Generic.Error */ + .gh { color: #000080; font-weight: bold } /* Generic.Heading */ + .gi { color: #00A000 } /* Generic.Inserted */ + .go { color: #000000; font-style: italic } /* Generic.Output */ + .gp { color: #8f5902 } /* Generic.Prompt */ + .gs { color: #000000; font-weight: bold } /* Generic.Strong */ + .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ + .gt { color: #a40000; font-weight: bold } /* Generic.Traceback */ + .kc { color: #204a87; font-weight: bold } /* Keyword.Constant */ + .kd { color: #204a87; font-weight: bold } /* Keyword.Declaration */ + .kn { color: #204a87; font-weight: bold } /* Keyword.Namespace */ + .kp { color: #204a87; font-weight: bold } /* Keyword.Pseudo */ + .kr { color: #204a87; font-weight: bold } /* Keyword.Reserved */ + .kt { color: #204a87; font-weight: bold } /* Keyword.Type */ + .ld { color: #000000 } /* Literal.Date */ + .m { color: #0000cf; font-weight: bold } /* Literal.Number */ + .s { color: #4e9a06 } /* Literal.String */ + .na { color: #c4a000 } /* Name.Attribute */ + .nb { color: #204a87 } /* Name.Builtin */ + .nc { color: #000000 } /* Name.Class */ + .no { color: #000000 } /* Name.Constant */ + .nd { color: #5c35cc; font-weight: bold } /* Name.Decorator */ + .ni { color: #ce5c00 } /* Name.Entity */ + .ne { color: #cc0000; font-weight: bold } /* Name.Exception */ + .nf { color: #000000 } /* Name.Function */ + .nl { color: #f57900 } /* Name.Label */ + .nn { color: #000000 } /* Name.Namespace */ + .nx { color: #000000 } /* Name.Other */ + .py { color: #000000 } /* Name.Property */ + .nt { color: #204a87; font-weight: bold } /* Name.Tag */ + .nv { color: #000000 } /* Name.Variable */ + .ow { color: #204a87; font-weight: bold } /* Operator.Word */ + .w { color: #f8f8f8; text-decoration: underline } /* Text.Whitespace */ + .mf { color: #0000cf; font-weight: bold } /* Literal.Number.Float */ + .mh { color: #0000cf; font-weight: bold } /* Literal.Number.Hex */ + .mi { color: #0000cf; font-weight: bold } /* Literal.Number.Integer */ + .mo { color: #0000cf; font-weight: bold } /* Literal.Number.Oct */ + .sb { color: #4e9a06 } /* Literal.String.Backtick */ + .sc { color: #4e9a06 } /* Literal.String.Char */ + .sd { color: #8f5902; font-style: italic } /* Literal.String.Doc */ + .s2 { color: #4e9a06 } /* Literal.String.Double */ + .se { color: #4e9a06 } /* Literal.String.Escape */ + .sh { color: #4e9a06 } /* Literal.String.Heredoc */ + .si { color: #4e9a06 } /* Literal.String.Interpol */ + .sx { color: #4e9a06 } /* Literal.String.Other */ + .sr { color: #4e9a06 } /* Literal.String.Regex */ + .s1 { color: #4e9a06 } /* Literal.String.Single */ + .ss { color: #4e9a06 } /* Literal.String.Symbol */ + .bp { color: #3465a4 } /* Name.Builtin.Pseudo */ + .vc { color: #000000 } /* Name.Variable.Class */ + .vg { color: #000000 } /* Name.Variable.Global */ + .vi { color: #000000 } /* Name.Variable.Instance */ + .il { color: #0000cf; font-weight: bold } /* Literal.Number.Integer.Long */ +} diff --git a/static/css/code/vibrant.less b/static/css/code/vibrant.less new file mode 100644 --- /dev/null +++ b/static/css/code/vibrant.less @@ -0,0 +1,240 @@ +// Modified version of the vibrant pygments stylesheet +.highlight &.vibrant { + color: @white; + background: @almostBlack; + .box-shadow(inset 0 0 40px rgba(0, 0, 0, 0.7)); + + // Comments + .c { + color: #3A6EF2; + font-style: italic; + } + + // Errors + .err { + color: #A61717; + background-color: #E3D2D2; + } + + // Keywords + .k { + color: @white; + font-weight: bold; + } + + // Operator + .o { + color: @white; + font-weight: bold; + } + + // Multi-line comment + .cm { + color: #3A6EF2; + font-style: italic; + } + + // Preprocessor comment + .cp { + color: #3A6EF2; + font-weight: bold; + } + + // Inline comment + .c1 { + color: #3A6EF2; + font-style: italic; + } + + // Special comment + .cs { + color: #3A6EF2; + font-weight: bold; + font-style: italic; + } + + // Generic deletion + .gd { + color: @black; + background-color: #FFDDDD; + } + + // Generic deletion (specific) + .gd .x { + background-color: #FFAAAA; + } + + // Generic emphasis + .ge { + font-style: italic; + } + + // Generic error + .gr { + color: #AA0000; + } + + // Generic heading + .gh { + color: #999999; + } + + // Generic insertion + .gi { + color: @black; + background-color: #DDFFDD; + } + + // Generic insertion (specific) + .gi .x { + background-color: #AAFFAA; + } + + // Generic output + .go { + color: #888; + } + + // Generic prompt + .gp { + color: #555; + } + + // Generic strong + .gs { + font-weight: bold; + } + + // Generic subheading + .gu { + font-weight: #AAA; + } + + // Generic traceback + .gt { + color: #AA0000; + } + + // Keyword.Constant + .kc { + font-weight: bold; + } + + // Keyword.Declaration + .kd { + font-weight: bold; + } + + // Keyword.Pseudo + .kp { + font-weight: bold; + } + + // Keyword.Reserved + .kr { + font-weight: bold; + } + + // Keyword.Type + .kt { + color: #445588; + font-weight: bold; + } + + // Literal.Number + .m { + color: #009999; + } + + // Literal.String + .s { + color: #66FF00; + } + + // Name.Attribute + .na { + color: #99CC99; + } + + // Name.Builtin + .nb { + color: #00AA00; + } + + // Name.Class + .nc { + color: @white; + font-weight: bold; + } + + // Name.Constant + .no { + color: @white; + } + + // Name.Entity + .ni { + color: #339999; + } + + // Name.Exception + .ne { + color: #FF0000; + font-weight: bold; + } + + // Name.Function + .nf { + color: #FFCC00; + font-weight: bold; + } + + // Name.Namespace + .nn { + color: #AAA; + } + + // Name.Tag + .nt { + color: #FF6600; + } + + // Name.Variable + .nv { + color: #BBB; + } + + // Operator.Word + .ow { + font-weight: bold; + } + + // Text.Whitespace + .w { + color: #BBB; + } + + // Literal.Number.Float + .mf { + color: #CCFF33; + } + .mh { color: #CCFF33 } /* Literal.Number.Hex */ + .mi { color: #CCFF33 } /* Literal.Number.Integer */ + .mo { color: #CCFF33 } /* Literal.Number.Oct */ + .sb { background: #CCCC33; color: #000000 } /* Literal.String.Backtick */ + .sc { color: #66FF00 } /* Literal.String.Char */ + .sd { color: #66FF00 } /* Literal.String.Doc */ + .s2 { color: #66FF00 } /* Literal.String.Double */ + .se { color: #66FF00 } /* Literal.String.Escape */ + .sh { color: #66FF00 } /* Literal.String.Heredoc */ + .si { color: #d555555 } /* Literal.String.Interpol */ + .sx { color: #66FF00 } /* Literal.String.Other */ + .sr { color: #009926 } /* Literal.String.Regex */ + .s1 { color: #66FF00 } /* Literal.String.Single */ + .ss { color: #339999 } /* Literal.String.Symbol */ + .bp { color: @lightBlue; font-weight: bold; } /* Name.Builtin.Pseudo */ + .vc { color: #008080 } /* Name.Variable.Class */ + .vg { color: #008080 } /* Name.Variable.Global */ + .vi { color: #008080 } /* Name.Variable.Instance */ + .il { color: #009999 } /* Literal.Number.Integer.Long */ +} diff --git a/static/css/code/vs.less b/static/css/code/vs.less new file mode 100644 --- /dev/null +++ b/static/css/code/vs.less @@ -0,0 +1,35 @@ +.highlight &.vs { + .hll { background-color: #ffffcc } + .c { color: #008000 } /* Comment */ + .err { border: 1px solid #FF0000 } /* Error */ + .k { color: #0000ff } /* Keyword */ + .cm { color: #008000 } /* Comment.Multiline */ + .cp { color: #0000ff } /* Comment.Preproc */ + .c1 { color: #008000 } /* Comment.Single */ + .cs { color: #008000 } /* Comment.Special */ + .ge { font-style: italic } /* Generic.Emph */ + .gh { font-weight: bold } /* Generic.Heading */ + .gp { font-weight: bold } /* Generic.Prompt */ + .gs { font-weight: bold } /* Generic.Strong */ + .gu { font-weight: bold } /* Generic.Subheading */ + .kc { color: #0000ff } /* Keyword.Constant */ + .kd { color: #0000ff } /* Keyword.Declaration */ + .kn { color: #0000ff } /* Keyword.Namespace */ + .kp { color: #0000ff } /* Keyword.Pseudo */ + .kr { color: #0000ff } /* Keyword.Reserved */ + .kt { color: #2b91af } /* Keyword.Type */ + .s { color: #a31515 } /* Literal.String */ + .nc { color: #2b91af } /* Name.Class */ + .ow { color: #0000ff } /* Operator.Word */ + .sb { color: #a31515 } /* Literal.String.Backtick */ + .sc { color: #a31515 } /* Literal.String.Char */ + .sd { color: #a31515 } /* Literal.String.Doc */ + .s2 { color: #a31515 } /* Literal.String.Double */ + .se { color: #a31515 } /* Literal.String.Escape */ + .sh { color: #a31515 } /* Literal.String.Heredoc */ + .si { color: #a31515 } /* Literal.String.Interpol */ + .sx { color: #a31515 } /* Literal.String.Other */ + .sr { color: #a31515 } /* Literal.String.Regex */ + .s1 { color: #a31515 } /* Literal.String.Single */ + .ss { color: #a31515 } /* Literal.String.Symbol */ +} diff --git a/static/css/imports.less b/static/css/imports.less --- a/static/css/imports.less +++ b/static/css/imports.less @@ -1,5 +1,15 @@ @import "variables.less"; @import "mixins.less"; -@import "code.less"; @import "agora.less"; @import "grid.less"; +@import "code.less"; + +// Add extra stylesheets here +@import "code/vibrant.less"; +@import "code/autumn.less"; +@import "code/borland.less"; +@import "code/fruity.less"; +@import "code/tango.less"; +@import "code/native.less"; +@import "code/vs.less"; +@import "code/monokai.less"; diff --git a/static/css/mixins.less b/static/css/mixins.less --- a/static/css/mixins.less +++ b/static/css/mixins.less @@ -91,3 +91,7 @@ .box-shadow(inset 0 0 2px 0 @lightBlue); } } + +.hidden { + display: none; +} diff --git a/static/css/variables.less b/static/css/variables.less --- a/static/css/variables.less +++ b/static/css/variables.less @@ -1,5 +1,6 @@ // Colour scheme @black: #000; +@almostBlack: #1B1B1B; @darkerGrey: #333; @darkGrey: #555; @mediumGrey: #AAA; @@ -21,7 +22,7 @@ @fixedWidth: 960px; @headerHeight: 100px; @headerIconHoverY: -60px; -@sidebarWidth: 250px; +@sidebarWidth: 230px; @sidebarLeftSpace: 20px; @nonSidebarWidth: @fixedWidth - @sidebarWidth - @sidebarLeftSpace; @inputPadding: 5px; diff --git a/templates/base.djhtml b/templates/base.djhtml --- a/templates/base.djhtml +++ b/templates/base.djhtml @@ -90,9 +90,10 @@ source and start contributing. :: About

+ + + {% block script_footer %} {% endblock %} - - diff --git a/templates/snippet/explore.html b/templates/snippet/explore.html new file mode 100644 --- /dev/null +++ b/templates/snippet/explore.html @@ -0,0 +1,45 @@ +{% extends "snippet/base.djhtml" %} + +{% load i18n %} + +{% block title %} +Explore +{% endblock %} + +{% block content %} +

{% trans "Recent snippets" %}

+ +{% if recent_snippets %} + + + + + + + + + + + {% for snippet in recent_snippets %} + + + + + + + {% endfor %} +
{% trans "Snippet title" %}{% trans "Language" %}{% trans "Created on" %}{% trans "User" %}
+ {{ snippet.get_title }} + {{ snippet.get_lexer_display }} + N/A{% if snippet.author %} + + {{ snippet.author }} + + {% else %} + {% trans "anonymous" %} + {% endif %} +
+{% else %} +

{% trans "No snippets have been created yet!" %}

+{% endif %} +{% endblock %} diff --git a/templates/snippet/snippet_details.djhtml b/templates/snippet/snippet_details.djhtml --- a/templates/snippet/snippet_details.djhtml +++ b/templates/snippet/snippet_details.djhtml @@ -5,7 +5,7 @@ {% block extrahead %} {% if request.session.userprefs %}