From 79a0651c396ffd98165c0d4df6bb94cc1f22d4b4 Mon Sep 17 00:00:00 2001
From: liangliangyy
\n' % mistune.escape(text)
-
- try:
- lexer = get_lexer_by_name(lang, stripall=True)
- formatter = html.HtmlFormatter(
- noclasses=inlinestyles, linenos=linenos
- )
- code = highlight(text, lexer, formatter)
- if linenos:
- return '%s
\n' % (
- lang, mistune.escape(text)
- )
-
-
@cache_decorator()
def get_current_site():
site = Site.objects.get_current()
return site
-class BlogMarkDownRenderer(mistune.Renderer):
- '''
- markdown渲染
- '''
+class CommonMarkdown:
+ @staticmethod
+ def _convert_markdown(value):
+ import markdown
+ md = markdown.Markdown(
+ extensions=[
+ 'extra',
+ 'codehilite',
+ 'toc',
+ 'tables',
+ ]
+ )
+ body = md.convert(value)
+ toc = md.toc
+ return body, toc
- def block_code(self, text, lang=None):
- # renderer has an options
- inlinestyles = self.options.get('inlinestyles')
- linenos = self.options.get('linenos')
- return block_code(text, lang, inlinestyles, linenos)
-
- def autolink(self, link, is_email=False):
- text = link = escape(link)
-
- if is_email:
- link = 'mailto:%s' % link
- if not link:
- link = "#"
- site = get_current_site()
- nofollow = "" if link.find(site.domain) > 0 else "rel='nofollow'"
- return '%s' % (link, nofollow, text)
-
- def link(self, link, title, text):
- link = escape_link(link)
- site = get_current_site()
- nofollow = "" if link.find(site.domain) > 0 else "rel='nofollow'"
- if not link:
- link = "#"
- if not title:
- return '%s' % (link, nofollow, text)
- title = escape(title, quote=True)
- return '%s' % (
- link, title, nofollow, text)
-
-
-class CommonMarkdown():
@staticmethod
- def get_markdown(value):
- renderer = BlogMarkDownRenderer(inlinestyles=False)
+ def get_markdown_with_toc(value):
+ body, toc = CommonMarkdown._convert_markdown(value)
+ return body, toc
- mdp = mistune.Markdown(escape=True, renderer=renderer)
- return mdp(value)
+ @staticmethod
+ def get_markdown(value):
+ body, toc = CommonMarkdown._convert_markdown(value)
+ return body
def send_email(emailto, title, content):
diff --git a/blog/models.py b/blog/models.py
index 067de72..c04a4cd 100644
--- a/blog/models.py
+++ b/blog/models.py
@@ -1,16 +1,17 @@
import logging
-from abc import ABCMeta, abstractmethod, abstractproperty
+from abc import abstractmethod
-from django.db import models
-from django.urls import reverse
from django.conf import settings
-from uuslug import slugify
from django.core.exceptions import ValidationError
-from django.utils.translation import gettext_lazy as _
-from DjangoBlog.utils import get_current_site
-from DjangoBlog.utils import cache_decorator, cache
+from django.db import models
+from django.urls import reverse
from django.utils.timezone import now
+from django.utils.translation import gettext_lazy as _
from mdeditor.fields import MDTextField
+from uuslug import slugify
+
+from DjangoBlog.utils import cache_decorator, cache
+from DjangoBlog.utils import get_current_site
logger = logging.getLogger(__name__)
@@ -94,6 +95,7 @@ class Article(BaseModel):
on_delete=models.CASCADE)
article_order = models.IntegerField(
'排序,数字越大越靠前', blank=False, null=False, default=0)
+ show_toc = models.BooleanField("是否显示toc目录", blank=False, null=False, default=False)
category = models.ForeignKey(
'Category',
verbose_name='分类',
diff --git a/blog/static/blog/css/style.css b/blog/static/blog/css/style.css
index 0cc1df1..d43f7f3 100644
--- a/blog/static/blog/css/style.css
+++ b/blog/static/blog/css/style.css
@@ -2479,17 +2479,26 @@ li #reply-title {
}
.breadcrumb {
- margin-bottom: 20px;
- list-style: none;
- border-radius: 4px;
+ margin-bottom: 20px;
+ list-style: none;
+ border-radius: 4px;
}
+
.breadcrumb > li {
- display: inline-block;
+ display: inline-block;
}
+
.breadcrumb > li + li:before {
- color: #ccc;
- content: "/\00a0";
+ color: #ccc;
+ content: "/\00a0";
}
+
.breadcrumb > .active {
- color: #777;
+ color: #777;
+}
+
+.break_line {
+ height: 1px;
+ border: none;
+ /*border-top: 1px dashed #f5d6d6;*/
}
\ No newline at end of file
diff --git a/blog/static/pygments/default.css b/blog/static/pygments/default.css
index 0f81fc8..73e6e49 100755
--- a/blog/static/pygments/default.css
+++ b/blog/static/pygments/default.css
@@ -1,59 +1,293 @@
-.highlight .hll { background-color: #ffffcc }
-.highlight { background: #ffffff; }
-.highlight .c { color: #177500 } /* Comment */
-.highlight .err { color: #000000 } /* Error */
-.highlight .k { color: #A90D91 } /* Keyword */
-.highlight .l { color: #1C01CE } /* Literal */
-.highlight .n { color: #000000 } /* Name */
-.highlight .o { color: #000000 } /* Operator */
-.highlight .ch { color: #177500 } /* Comment.Hashbang */
-.highlight .cm { color: #177500 } /* Comment.Multiline */
-.highlight .cp { color: #633820 } /* Comment.Preproc */
-.highlight .cpf { color: #177500 } /* Comment.PreprocFile */
-.highlight .c1 { color: #177500 } /* Comment.Single */
-.highlight .cs { color: #177500 } /* Comment.Special */
-.highlight .kc { color: #A90D91 } /* Keyword.Constant */
-.highlight .kd { color: #A90D91 } /* Keyword.Declaration */
-.highlight .kn { color: #A90D91 } /* Keyword.Namespace */
-.highlight .kp { color: #A90D91 } /* Keyword.Pseudo */
-.highlight .kr { color: #A90D91 } /* Keyword.Reserved */
-.highlight .kt { color: #A90D91 } /* Keyword.Type */
-.highlight .ld { color: #1C01CE } /* Literal.Date */
-.highlight .m { color: #1C01CE } /* Literal.Number */
-.highlight .s { color: #C41A16 } /* Literal.String */
-.highlight .na { color: #836C28 } /* Name.Attribute */
-.highlight .nb { color: #A90D91 } /* Name.Builtin */
-.highlight .nc { color: #3F6E75 } /* Name.Class */
-.highlight .no { color: #000000 } /* Name.Constant */
-.highlight .nd { color: #000000 } /* Name.Decorator */
-.highlight .ni { color: #000000 } /* Name.Entity */
-.highlight .ne { color: #000000 } /* Name.Exception */
-.highlight .nf { color: #000000 } /* Name.Function */
-.highlight .nl { color: #000000 } /* Name.Label */
-.highlight .nn { color: #000000 } /* Name.Namespace */
-.highlight .nx { color: #000000 } /* Name.Other */
-.highlight .py { color: #000000 } /* Name.Property */
-.highlight .nt { color: #000000 } /* Name.Tag */
-.highlight .nv { color: #000000 } /* Name.Variable */
-.highlight .ow { color: #000000 } /* Operator.Word */
-.highlight .mb { color: #1C01CE } /* Literal.Number.Bin */
-.highlight .mf { color: #1C01CE } /* Literal.Number.Float */
-.highlight .mh { color: #1C01CE } /* Literal.Number.Hex */
-.highlight .mi { color: #1C01CE } /* Literal.Number.Integer */
-.highlight .mo { color: #1C01CE } /* Literal.Number.Oct */
-.highlight .sb { color: #C41A16 } /* Literal.String.Backtick */
-.highlight .sc { color: #2300CE } /* Literal.String.Char */
-.highlight .sd { color: #C41A16 } /* Literal.String.Doc */
-.highlight .s2 { color: #C41A16 } /* Literal.String.Double */
-.highlight .se { color: #C41A16 } /* Literal.String.Escape */
-.highlight .sh { color: #C41A16 } /* Literal.String.Heredoc */
-.highlight .si { color: #C41A16 } /* Literal.String.Interpol */
-.highlight .sx { color: #C41A16 } /* Literal.String.Other */
-.highlight .sr { color: #C41A16 } /* Literal.String.Regex */
-.highlight .s1 { color: #C41A16 } /* Literal.String.Single */
-.highlight .ss { color: #C41A16 } /* Literal.String.Symbol */
-.highlight .bp { color: #5B269A } /* Name.Builtin.Pseudo */
-.highlight .vc { color: #000000 } /* Name.Variable.Class */
-.highlight .vg { color: #000000 } /* Name.Variable.Global */
-.highlight .vi { color: #000000 } /* Name.Variable.Instance */
-.highlight .il { color: #1C01CE } /* Literal.Number.Integer.Long */
\ No newline at end of file
+.codehilite .hll {
+ background-color: #ffffcc
+}
+
+.codehilite {
+ background: #ffffff;
+}
+
+.codehilite .c {
+ color: #177500
+}
+
+/* Comment */
+.codehilite .err {
+ color: #000000
+}
+
+/* Error */
+.codehilite .k {
+ color: #A90D91
+}
+
+/* Keyword */
+.codehilite .l {
+ color: #1C01CE
+}
+
+/* Literal */
+.codehilite .n {
+ color: #000000
+}
+
+/* Name */
+.codehilite .o {
+ color: #000000
+}
+
+/* Operator */
+.codehilite .ch {
+ color: #177500
+}
+
+/* Comment.Hashbang */
+.codehilite .cm {
+ color: #177500
+}
+
+/* Comment.Multiline */
+.codehilite .cp {
+ color: #633820
+}
+
+/* Comment.Preproc */
+.codehilite .cpf {
+ color: #177500
+}
+
+/* Comment.PreprocFile */
+.codehilite .c1 {
+ color: #177500
+}
+
+/* Comment.Single */
+.codehilite .cs {
+ color: #177500
+}
+
+/* Comment.Special */
+.codehilite .kc {
+ color: #A90D91
+}
+
+/* Keyword.Constant */
+.codehilite .kd {
+ color: #A90D91
+}
+
+/* Keyword.Declaration */
+.codehilite .kn {
+ color: #A90D91
+}
+
+/* Keyword.Namespace */
+.codehilite .kp {
+ color: #A90D91
+}
+
+/* Keyword.Pseudo */
+.codehilite .kr {
+ color: #A90D91
+}
+
+/* Keyword.Reserved */
+.codehilite .kt {
+ color: #A90D91
+}
+
+/* Keyword.Type */
+.codehilite .ld {
+ color: #1C01CE
+}
+
+/* Literal.Date */
+.codehilite .m {
+ color: #1C01CE
+}
+
+/* Literal.Number */
+.codehilite .s {
+ color: #C41A16
+}
+
+/* Literal.String */
+.codehilite .na {
+ color: #836C28
+}
+
+/* Name.Attribute */
+.codehilite .nb {
+ color: #A90D91
+}
+
+/* Name.Builtin */
+.codehilite .nc {
+ color: #3F6E75
+}
+
+/* Name.Class */
+.codehilite .no {
+ color: #000000
+}
+
+/* Name.Constant */
+.codehilite .nd {
+ color: #000000
+}
+
+/* Name.Decorator */
+.codehilite .ni {
+ color: #000000
+}
+
+/* Name.Entity */
+.codehilite .ne {
+ color: #000000
+}
+
+/* Name.Exception */
+.codehilite .nf {
+ color: #000000
+}
+
+/* Name.Function */
+.codehilite .nl {
+ color: #000000
+}
+
+/* Name.Label */
+.codehilite .nn {
+ color: #000000
+}
+
+/* Name.Namespace */
+.codehilite .nx {
+ color: #000000
+}
+
+/* Name.Other */
+.codehilite .py {
+ color: #000000
+}
+
+/* Name.Property */
+.codehilite .nt {
+ color: #000000
+}
+
+/* Name.Tag */
+.codehilite .nv {
+ color: #000000
+}
+
+/* Name.Variable */
+.codehilite .ow {
+ color: #000000
+}
+
+/* Operator.Word */
+.codehilite .mb {
+ color: #1C01CE
+}
+
+/* Literal.Number.Bin */
+.codehilite .mf {
+ color: #1C01CE
+}
+
+/* Literal.Number.Float */
+.codehilite .mh {
+ color: #1C01CE
+}
+
+/* Literal.Number.Hex */
+.codehilite .mi {
+ color: #1C01CE
+}
+
+/* Literal.Number.Integer */
+.codehilite .mo {
+ color: #1C01CE
+}
+
+/* Literal.Number.Oct */
+.codehilite .sb {
+ color: #C41A16
+}
+
+/* Literal.String.Backtick */
+.codehilite .sc {
+ color: #2300CE
+}
+
+/* Literal.String.Char */
+.codehilite .sd {
+ color: #C41A16
+}
+
+/* Literal.String.Doc */
+.codehilite .s2 {
+ color: #C41A16
+}
+
+/* Literal.String.Double */
+.codehilite .se {
+ color: #C41A16
+}
+
+/* Literal.String.Escape */
+.codehilite .sh {
+ color: #C41A16
+}
+
+/* Literal.String.Heredoc */
+.codehilite .si {
+ color: #C41A16
+}
+
+/* Literal.String.Interpol */
+.codehilite .sx {
+ color: #C41A16
+}
+
+/* Literal.String.Other */
+.codehilite .sr {
+ color: #C41A16
+}
+
+/* Literal.String.Regex */
+.codehilite .s1 {
+ color: #C41A16
+}
+
+/* Literal.String.Single */
+.codehilite .ss {
+ color: #C41A16
+}
+
+/* Literal.String.Symbol */
+.codehilite .bp {
+ color: #5B269A
+}
+
+/* Name.Builtin.Pseudo */
+.codehilite .vc {
+ color: #000000
+}
+
+/* Name.Variable.Class */
+.codehilite .vg {
+ color: #000000
+}
+
+/* Name.Variable.Global */
+.codehilite .vi {
+ color: #000000
+}
+
+/* Name.Variable.Instance */
+.codehilite .il {
+ color: #1C01CE
+}
+
+/* Literal.Number.Integer.Long */
\ No newline at end of file
diff --git a/blog/templatetags/blog_tags.py b/blog/templatetags/blog_tags.py
index 73df621..c899099 100644
--- a/blog/templatetags/blog_tags.py
+++ b/blog/templatetags/blog_tags.py
@@ -13,24 +13,24 @@
@time: 2016/11/2 下午11:10
"""
+import hashlib
+import logging
+import random
+import urllib
+
from django import template
-from django.db.models import Q
from django.conf import settings
+from django.db.models import Q
+from django.shortcuts import get_object_or_404
from django.template.defaultfilters import stringfilter
-from django.utils.safestring import mark_safe
-import random
from django.urls import reverse
+from django.utils.safestring import mark_safe
+
+from DjangoBlog.utils import cache
+from DjangoBlog.utils import get_current_site
from blog.models import Article, Category, Tag, Links, SideBar, LinkShowType
-from django.utils.encoding import force_text
-from django.shortcuts import get_object_or_404
-import hashlib
-import urllib
from comments.models import Comment
-from DjangoBlog.utils import cache_decorator, cache
-from django.contrib.auth import get_user_model
from oauth.models import OAuthUser
-from DjangoBlog.utils import get_current_site
-import logging
logger = logging.getLogger(__name__)
@@ -64,6 +64,13 @@ def custom_markdown(content):
return mark_safe(CommonMarkdown.get_markdown(content))
+@register.simple_tag
+def get_markdown_toc(content):
+ from DjangoBlog.utils import CommonMarkdown
+ body, toc = CommonMarkdown.get_markdown_with_toc(content)
+ return mark_safe(toc), mark_safe(body)
+
+
@register.filter(is_safe=True)
@stringfilter
def truncatechars_content(content):
diff --git a/blog/tests.py b/blog/tests.py
index 6c90727..acf6ad8 100644
--- a/blog/tests.py
+++ b/blog/tests.py
@@ -1,17 +1,18 @@
+import os
+
+from django.conf import settings
+from django.core.files.uploadedfile import SimpleUploadedFile
+from django.core.management import call_command
+from django.core.paginator import Paginator
from django.test import Client, RequestFactory, TestCase
-from blog.models import Article, Category, Tag, SideBar, Links
-from django.contrib.auth import get_user_model
+from django.urls import reverse
+from django.utils import timezone
+
from DjangoBlog.utils import get_current_site, get_sha256
+from accounts.models import BlogUser
from blog.forms import BlogSearchForm
-from django.core.paginator import Paginator
+from blog.models import Article, Category, Tag, SideBar, Links
from blog.templatetags.blog_tags import load_pagination_info, load_articletags
-from accounts.models import BlogUser
-from django.core.files.uploadedfile import SimpleUploadedFile
-from django.conf import settings
-from django.urls import reverse
-from django.utils import timezone
-import os
-from django.core.management import call_command
# Create your tests here.
@@ -147,8 +148,7 @@ class ArticleTest(TestCase):
response = self.client.get('/sitemap.xml')
self.assertEqual(response.status_code, 200)
- from DjangoBlog.utils import block_code
- block = block_code("`python`", 'python')
+
self.client.get("/admin/blog/article/1/delete/")
self.client.get('/admin/servermanager/emailsendlog/')
self.client.get('admin/admin/logentry/')
diff --git a/requirements.txt b/requirements.txt
index d1f77d7ce1d1f98a7ec908431bba47e71390284a..675479f54c8617aa95350daeb4a1bdc9328df3bb 100644
GIT binary patch
literal 1078
zcmZ{k%TB^z5QS%L;-f&g3NG9jw%s