Right-To-Left Support

This commit is contained in:
Martin Mahner 2018-12-19 15:03:15 +01:00
parent 3bfb153b74
commit 0f5fbd28f4
10 changed files with 99 additions and 17 deletions

View file

@ -46,6 +46,26 @@ if (wordwrapCheckbox && snippetDiv) {
wordwrapCheckbox.onchange = toggleWordwrap;
}
// -----------------------------------------------------------------------------
// Right-To-Left
// -----------------------------------------------------------------------------
const rtlCheckbox = document.getElementById('id_rtl');
const snippetArea = document.getElementById('id_content');
function toggleRTL() {
if (rtlCheckbox.checked) {
snippetArea.dir = 'rtl';
} else {
snippetArea.dir = '';
}
}
if (rtlCheckbox && snippetArea) {
toggleRTL();
rtlCheckbox.onchange = toggleRTL;
}
// -----------------------------------------------------------------------------
// Line Highlighting
// -----------------------------------------------------------------------------

View file

@ -8,7 +8,14 @@
.snippet-form {
background-color: $bgColor;
label { display: none; }
label {
display: none;
font-size: 13px;
}
.options-rtl label {
display: inline;
}
select {
-moz-appearance: none;

View file

@ -20,24 +20,37 @@ def get_expire_values(expires):
else:
expire_type = Snippet.EXPIRE_TIME
expires = expires and expires or config.EXPIRE_DEFAULT
expires = datetime.datetime.now() + datetime.timedelta(seconds=int(expires))
expires = datetime.datetime.now() + datetime.timedelta(
seconds=int(expires)
)
return expires, expire_type
class SnippetForm(forms.ModelForm):
content = forms.CharField(
label=_('Content'),
widget=forms.Textarea(attrs={'placeholder': _('Awesome code goes here...')}),
widget=forms.Textarea(
attrs={'placeholder': _('Awesome code goes here...')}
),
max_length=config.MAX_CONTENT_LENGTH,
strip=False,
)
lexer = forms.ChoiceField(
label=_('Lexer'), initial=LEXER_DEFAULT, choices=LEXER_CHOICES
label=_('Lexer'),
initial=LEXER_DEFAULT,
choices=LEXER_CHOICES
)
expires = forms.ChoiceField(
label=_('Expires'), choices=config.EXPIRE_CHOICES, initial=config.EXPIRE_DEFAULT
label=_('Expires'),
choices=config.EXPIRE_CHOICES,
initial=config.EXPIRE_DEFAULT,
)
rtl = forms.BooleanField(
label=_('Right to Left'),
required=False
)
# Honeypot field
@ -49,7 +62,7 @@ class SnippetForm(forms.ModelForm):
class Meta:
model = Snippet
fields = ('content', 'lexer')
fields = ('content', 'lexer', 'rtl')
def __init__(self, request, *args, **kwargs):
super(SnippetForm, self).__init__(*args, **kwargs)

View file

@ -34,13 +34,14 @@ class Highlighter(object):
return l[1]
return fallback
def render(self, code_string, lexer_name, **kwargs):
def render(self, code_string, lexer_name, direction=None, **kwargs):
highlighted_string = self.highlight(code_string, lexer_name=lexer_name)
context = {
'highlighted': highlighted_string,
'highlighted_splitted': highlighted_string.splitlines(),
'lexer_name': lexer_name,
'lexer_display_name': self.get_lexer_display_name(lexer_name),
'direction': direction,
}
context.update(kwargs)
return render_to_string(self.template_name, context)
@ -76,7 +77,9 @@ class MarkdownHighlighter(PlainTextHighlighter):
return mark_safe(
misaka.html(
code_string, extensions=self.extensions, render_flags=self.render_flags
code_string,
extensions=self.extensions,
render_flags=self.render_flags
)
)

View file

@ -0,0 +1,18 @@
# Generated by Django 2.1.1 on 2018-12-19 13:39
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dpaste', '0006_auto_20180622_1051'),
]
operations = [
migrations.AddField(
model_name='snippet',
name='rtl',
field=models.BooleanField(default=False, verbose_name='Right-to-left'),
),
]

View file

@ -22,7 +22,10 @@ def generate_secret_id(length):
)
secret_id = ''.join(
[R.choice(config.SLUG_CHOICES) for i in range(length or config.SLUG_LENGTH)]
[
R.choice(config.SLUG_CHOICES)
for i in range(length or config.SLUG_LENGTH)
]
)
# Check if this slug already exists, if not, return this new slug
@ -51,13 +54,16 @@ class Snippet(models.Model):
_('Secret ID'), max_length=255, blank=True, null=True, unique=True
)
content = models.TextField(_('Content'))
lexer = models.CharField(_('Lexer'), max_length=30, default=highlight.LEXER_DEFAULT)
lexer = models.CharField(
_('Lexer'), max_length=30, default=highlight.LEXER_DEFAULT
)
published = models.DateTimeField(_('Published'), auto_now_add=True)
expire_type = models.PositiveSmallIntegerField(
_('Expire Type'), choices=EXPIRE_CHOICES, default=EXPIRE_CHOICES[0][0]
)
expires = models.DateTimeField(_('Expires'), blank=True, null=True)
view_count = models.PositiveIntegerField(_('View count'), default=0)
rtl = models.BooleanField(_('Right-to-left'), default=False)
parent = models.ForeignKey(
'self',
null=True,
@ -80,11 +86,17 @@ class Snippet(models.Model):
super(Snippet, self).save(*args, **kwargs)
def get_absolute_url(self):
return reverse('snippet_details', kwargs={'snippet_id': self.secret_id})
return reverse(
'snippet_details', kwargs={'snippet_id': self.secret_id}
)
def highlight(self):
HighlighterClass = highlight.get_highlighter_class(self.lexer)
return HighlighterClass().render(self.content, self.lexer)
return HighlighterClass().render(
code_string=self.content,
lexer_name=self.lexer,
direction='rtl' if self.rtl else 'ltr',
)
@property
def lexer_name(self):

View file

@ -1,5 +1,5 @@
<div class="snippet-text">
<article>
<article dir="{{ direction }}">
<div>{{ highlighted }}</div>
</article>
</div>

View file

@ -18,6 +18,14 @@
{{ form.expires }}
</p>
<p class="options-rtl">
{{ form.rtl }}
<label for="{{ form.rtl.auto_id }}">
{% trans "Right-to-Left" %}
<small>[beta]</small>
</label>
</p>
<p class="action">
<button class="btn" type="submit">
{% trans "Paste Snippet" %}

View file

@ -39,7 +39,6 @@ class SnippetView(FormView):
"""
Create a new snippet.
"""
form_class = SnippetForm
template_name = 'dpaste/new.html'
@ -100,7 +99,11 @@ class SnippetDetailView(SnippetView, DetailView):
def get_initial(self):
snippet = self.get_object()
return {'content': snippet.content, 'lexer': snippet.lexer}
return {
'content': snippet.content,
'lexer': snippet.lexer,
'rtl': snippet.rtl,
}
def form_valid(self, form):
snippet = form.save(parent=self.get_object())

View file

@ -7,11 +7,9 @@
"postinstall": "npm run build",
"start": "npm run build && pipenv run ./manage.py runserver",
"docs": "pipenv run sphinx-build -c docs docs docs/_build/html",
"build-css": "node-sass --output-style compressed -o build client/scss/dpaste.scss ",
"build-js": "uglifyjs --compress=\"drop_console=true,ecma=6\" --mangle=\"toplevel\" --output=build/dpaste.js client/js/dpaste.js",
"build": "npm run build-css && npm run build-js",
"watch-css": "npm run build && node-sass --source-map true -o build/ --watch client/scss/dpaste.scss",
"watch-docs": "pipenv run sphinx-autobuild -c docs docs docs/_build/html"
},