整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

Z-BlogPHP主题导航高亮的方法(附js、php、CSS代码)

常玩ZblogPHP的用户是不是经常在主题里发现主题自带导航高亮功能,并且还可以给文章页加上当前分类的高亮,下面我们来看看,这种方法到底是怎么实现的呢,是不是很炫酷呢。

首先我想说一下,这是我在制作主题过程中遇到的问题,我是想给我的主题加上导航高亮的小功能,要是没有这功能主题怎能变得有特色,于是我借鉴了许多主题模板后,得出了方法和代码:

首先打开模板template文件夹,找到所存放导航栏的文件,在导航栏的父级div容器,也可以是header、nav、section等,在class="" 后面加上

data-type="{if $type=='article'}article{elseif $type=='page'}page{elseif $type=='index'}index{else}category{/if}" data-infoid="{if $type=='article'}{$article.Category.ID} {elseif $type=='page'}{$article.ID}{elseif $type=='index'} {else}{$category.ID}{/if}"

加上这串代码后,恭喜你,重要的一步已经完成了。

然后找到模板下script文件夹,找到模板主js,加上如下代码。

jQuery(document).ready(function($){ var datatype=$("#hamburgermenu").attr("data-type"); $(".dhgl>li ").each(function(){ try{ var myid=$(this).attr("id"); if("index"==datatype){ if(myid=="nvabar-item-index"){ $("#nvabar-item-index a:first-child").addClass("on"); } }else if("category"==datatype){ var infoid=$("#hamburgermenu").attr("data-infoid"); if(infoid!=null){ var b=infoid.split(' '); for(var i=0;i<b.length;i++){ if(myid=="navbar-category-"+b[i]){ $("#navbar-category-"+b[i]+" a:first-child").addClass("on"); } } } }else if("article"==datatype){ var infoid=$("#hamburgermenu").attr("data-infoid"); if(infoid!=null){ var b=infoid.split(' '); for(var i=0;i<b.length;i++){ if(myid=="navbar-category-"+b[i]){ $("#navbar-category-"+b[i]+" a:first-child").addClass("on"); } } } }else if("page"==datatype){ var infoid=$("#hamburgermenu").attr("data-infoid"); if(infoid!=null){ if(myid=="navbar-page-"+infoid){ $("#navbar-page-"+infoid+" a:first-child").addClass("on"); } } }else if("tag"==datatype){ var infoid=$("#hamburgermenu").attr("data-infoid"); if(infoid!=null){ if(myid=="navbar-tag-"+infoid){ $("#navbar-tag-"+infoid+" a:first-child").addClass("on"); } } } }catch(E){} });});

这是,在你的导航栏父级div容器加上id hamburgermenu,然后在导航栏ul上加上class dhgl,这时,网站已经能够识别导航所在页面了!

这样一个简单的导航高亮逻辑判断就完成了,要显示出导航高亮,还要加上css样式。

在主题style文件夹上的主题主css样式上加入a标签的样式:

#hamburgermenu .dhgl li a.on{background:#333;color:#fff;}

background和color后面的颜色也是需要自己自定义的,你可以改成自己的颜色,看着不错就可以了哦。

原理:第一步的php判断是通过php的逻辑type判断,首页就显示index,如果是分类页文章页就输出分类id等,然后js判断li的id,是否和php的首页、分类id符合,符合就输出on class,然后css给on加上样式

来源:捷闪站长网,转载请保留出处和链接!

本文链接:http://www.z18zs.com/read/180.html

ygments是一个Python库,可以用于语法高亮和代码着色。它支持超过500种编程语言和文本格式,并提供多种输出格式。在本教程中,我们将介绍如何安装和使用Pygments。

安装

要使用Pygments库,你需要先安装它。你可以使用以下命令来安装它:

pip install pygments

使用

一旦你安装了Pygments库,你就可以开始使用它来进行语法高亮和代码着色了。

以下是一个简单的例子,演示了如何使用Pygments来对Python代码进行语法高亮:

from pygments import highlight
from pygments.lexers import PythonLexer
from pygments.formatters import HtmlFormatter

code = """
def hello_world():
    print('Hello, World!')
"""

highlighted_code = highlight(code, PythonLexer(), HtmlFormatter())
print(highlighted_code)

在这个例子中,我们首先导入了highlight函数、PythonLexer和HtmlFormatter类。接着,我们定义了一个包含Python代码的字符串。然后,我们使用highlight函数对该字符串进行语法高亮,将其转换为HTML格式,并将其打印出来。

在这个例子中,我们使用了PythonLexer来指定要高亮的语言类型。Pygments支持多种编程语言,每种语言都有一个对应的Lexer。我们还使用了HtmlFormatter类来指定输出格式。

其他输出格式

除了HTML格式外,Pygments还支持多种输出格式。以下是一些常用的输出格式:

  • TerminalFormatter:将高亮后的代码输出到终端上。
  • LatexFormatter:将高亮后的代码输出到LaTeX格式的文档中。
  • ImageFormatter:将高亮后的代码输出为图片格式。

你可以使用不同的输出格式来满足不同的需求。

自定义样式

Pygments提供了许多预定义的样式,但是你也可以自定义样式。你可以使用pygments.styles模块中的Style类来定义新的样式。下面是一个简单的例子,演示如何创建一个新的样式:

from pygments.style import Style
from pygments.token import Keyword, Name, Comment, String, Error, Number, Operator, Punctuation, Generic

class MyStyle(Style):
    default_style = ""
    styles = {
        Keyword: '#FF0000',
        Name.Function: '#00FF00',
        Comment: '#0000FF',
        String: '#FF00FF',
        Error: '#FF0000',
        Number: '#00FFFF',
        Operator: '#FFFFFF',
        Punctuation: '#FFFFFF',
        Generic: '#FFFFFF'
    }

在这个例子中,我们创建了一个名为MyStyle的新样式,并将其继承自Style类。我们定义了一些样式规则,指定了不同类型的标记应该如何着色。例如,我们将所有的Keyword标记都着为红色,将所有的Name.Function标记都着为绿色,等等。

添加新的语言支持

如果你需要支持Pygments中没有预定义的语言,你可以使用pygments.lexer模块中的RegexLexer类来创建自己的Lexer。下面是一个简单的例子,演示如何创建一个新的Lexer:

from pygments.lexer import RegexLexer
from pygments.token import *

class MyLexer(RegexLexer):
    name = 'MyLexer'
    tokens = {
        'root': [
            (r'\d+', Number),
            (r'[a-zA-Z]+', Name),
            (r'#.*', Comment),
            (r'\s+', Whitespace)
        ]
    }

在这个例子中,我们创建了一个名为MyLexer的新Lexer,并将其继承自RegexLexer类。我们定义了一些规则,指定了不同的正则表达式应该匹配哪些类型的标记。例如,我们使用\d+来匹配所有数字,并将其标记为Number类型,使用[a-zA-Z]+来匹配所有字母,并将其标记为Name类型,等等。

其他高级用法

除了自定义样式和添加新的语言支持外,Pygments还提供了一些其他的高级用法,例如使用自定义过滤器和自定义输出格式。如果你想深入了解Pygments的高级用法,请查看官方文档。

总结

Pygments是一个非常有用的Python库,可以用于语法高亮和代码着色。在本教程中,我们介绍了如何安装Pygments,以及如何使用它来对代码进行语法高亮和着色。我们还简单介绍了一些常见的输出格式和高级用法。希望这个教程对你有所帮助,让你更好地了解Pygments的用法。

在前面几期的博文中,我们讨论了如何使用面向对象的方式来编写Vue代码,以提高代码的可维护性和可扩展性。然而,随着我们探索新的语法和特性,发现在VSCode中并未找到相应的插件支持,这严重影响了我们的开发体验。因此,为了让我们的开发环境紧跟最新的语法,从本期开始,我们将陆续介绍如何自制VSCode语言插件,以适配新的语法。

VSCode语言插件的制作是一个复杂的过程,但在本系列教程中,我们将尽量简明扼要地介绍每个必要的流程和代码片段。通过自制插件,我们可以为VSCode增添针对Vue的智能提示、语法高亮、代码片段以及其他便利功能,极大地提升我们的开发效率和舒适度。

为什么需要自制VSCode语言插件?

VSCode作为一款轻量级且功能强大的代码编辑器,受到了广大开发者的喜爱。其拥有丰富的扩展生态系统,几乎涵盖了所有主流编程语言和框架。然而,随着面向对象插件的不断发展,新的语法和特性不断涌现,这些新功能可能并未得到官方插件的支持。

在Vue生态系统中,由于其灵活性和易扩展性,社区经常会提出新的语法糖、指令、装饰器等特性。这些新特性对于Vue开发者来说非常有吸引力,但由于VSCode未提供相应的官方支持,我们的开发体验可能会受到限制,比如缺乏智能提示、错误提示等功能。

为了解决这一问题,自制VSCode语言插件成为了一种解决方案。通过自己开发插件,我们可以根据需要添加新的语法支持,从而让VSCode完美适配我们使用的Vue版本,提供更加便捷的开发体验。

自制VSCode语言插件的复杂性

自制VSCode语言插件是一项挑战性的任务,需要对插件开发流程有一定了解,并且熟悉VSCode插件开发的相关API和机制。不过,本系列教程将尽量降低难度,以简单易懂的方式呈现插件开发的关键步骤和技巧。

我们将主要关注以下几个方面(分几期讲):

  1. 语法高亮:通过定义语法规则,使得Vue代码在编辑器中能够得到良好的颜色标识,增加代码的可读性。
  2. 智能提示:为Vue的特定语法和指令添加智能提示功能,让开发者在编写代码时能够得到即时的建议和补全。
  3. 错误检查:针对新语法进行错误检查,及时发现并提示代码中的问题,避免在编译过程中产生错误。
  4. 代码片段:提供常用代码片段,简化重复性的代码编写过程。

虽然插件开发过程相对复杂,但一旦掌握了相关技能,将为我们带来巨大的便利和满足感。让我们一起开启自制VSCode语言插件的奇妙之旅吧!

创建项目

  • 安装yo generator-code
bash复制代码npm install -g yo generator-code

这个脚手架会生成一个可以立马开发的项目。

  • 使用yo来生成项目骨架
bash复制代码yo code
# 根据引导 一步一步创建所需要的项目骨架
# What type of extension do you want to create? 这一步选择New Language Support
# URL or file to import, or none for new: 迁移现成的textMate语法 直接回车
# What's the name of your extension? () 输入拓展名称 这我输入vs-template-lang
# What's the identifier of your extension template-lang
# What's the description of your extension? () 输入插件描述
# Language id: () 这里先随便输入 项目中用不到
# Language name: () 这里先随便输入 项目中用不到
# File extensions: 拓展名 先随便写 后续也用不到
# Scope names: () source.后缀名
# Initialize a git repository? (Y/n) y

回答了一大堆问题之后,YO会创建一个新的插件,其结构如下

由于我们并没有创建新的语言,只是在现有的语言基础上支持新的语法,所以需要删除生成的package.json中的languages配置。

  • 运行插件

在编辑器内按F5, 这会在新的开发窗口中编译&运行拓展

可以看出,目前template是没有任何语法高亮以及智能提示的,现在vscode只会template属性值当作字符串处理,我们需要为其定义不同的语法高亮规则

语法高亮

语法高亮在代码编辑器中决定源代码的颜色和样式,它的主要职责是为关键字(例如JavaScript中的if、for)、字符串、注释、变量名等语法元素提供着色。在VSCode中,语法高亮是通过使用TextMate语法进行定义的。如果你想深入了解TextMate语法的工作原理和用法,我强烈建议阅读这篇文章:TextMate语法指南。

TextMate语法是一种强大的语法定义格式,它允许我们明确定义不同语法元素的匹配规则和样式信息。在开发自定义的语法高亮插件时,理解TextMate语法的原理对于正确实现各种代码元素的高亮非常重要。

通过TextMate语法,我们可以灵活地指定如何匹配特定的语法结构,例如,我们可以定义一个用于匹配JavaScript中的变量名的正则表达式,然后为匹配到的变量名指定特定的颜色和样式。类似地,我们可以定义其他语法元素的规则,以实现精确的代码高亮效果。

总的来说,语法高亮是代码编辑器中一个非常重要的功能,它不仅使代码更加美观,还提供了更好的可读性和编码体验。通过深入理解TextMate语法,并根据具体语言的特性来定义相应的规则,我们可以开发出功能强大、高度定制化的语法高亮插件,为开发者提供更优秀的编辑环境。

  1. 配置grammars
  2. 提炼一下我们的需求, 以需求为导向来一步步实现我们的所需的功能:
    1. 在ts文件中@Component中的template值需要支持html语法,而且在html的基础支持vue的模板语法以及我们自定义的语法
    2. 在ts文件中@Component中的style值需要支持css语法 基于以上的需求,我们在package.json中将我们定义的TextMate规则作用到ts中,package.json定义如下:
  3. json复制代码
  4. { "name": "template-lang", "displayName": "vs-template-lang", "description": "vuGualr template", "version": "0.0.1", "engines": { "vscode": "^1.81.0" }, "categories": [ "Programming Languages" ], "contributes": { "grammars": [ { "path": "./syntaxes/inline-template.json", "scopeName": "inline-template.vg", "injectTo": [ "source.ts" ], "embeddedLanguages": { "text.html": "html", "source.css": "css" } } ] } }
    1. "injectTo": ["source.ts"]:表示将这个语法规则注入到 source.ts 这个作用范围中。这意味着当在 TypeScript 文件中遇到符合"./syntaxes/inline-template.json规则时,会应用 inline-template.vg 这个语法规则来处理。
    2. "embeddedLanguages": { ... }:用于定义嵌套语言。在这里,它定义了 text.html、source.css 和 source.js 三种嵌套语言。嵌套语言表示在当前语言中可以包含其他语言的代码块,例如在 TypeScript 中嵌套 HTML、CSS。
    3. "scopeName": "inline-template.vg":表示这个语法规则的作用范围名称。作用范围名称用于标识文本的语法类型,它会被用于对文本进行语法高亮。
  5. inline-template.json
json复制代码{
    // 表示这个语法规则的作用范围名称。作用范围名称用于标识文本的语法类型
    "scopeName": "inline-template.vg",
    "injectionSelector": "L:meta.decorator.ts -comment -text.html",
    // 表示一系列的匹配规则
    "patterns": [
      {
        "include": "#inlineTemplate"
      }
    ],
    "repository": {
      "inlineTemplate": {
        // 在@Component中template:开始匹配
        "begin": "(template)\\s*(:)",
        "beginCaptures": {
          "1": {
            "name": "meta.object-literal.key.ts"
          },
          "2": {
            "name": "meta.object-literal.key.ts punctuation.separator.key-value.ts"
          }
        },
        // 用于匹配 `,` 或 `}`,但不会包含在匹配结果中
        "end": "(?=,|})",
        "patterns": [
          {
            // 引用vgTemplate规则
            "include": "#vgTemplate"
          }
        ]
      },
      "vgTemplate": {
        // 以`或者'或者"开始
        "begin": "\\G\\s*([`|'|\"])",
        "beginCaptures": {
          "1": {
            "name": "string"
          }
        },
        // `\1` 是一个反向引用,表示匹配到的内容必须与前面捕获组中的内容相同,
        // 这里指的是 `([`|'|"])` 中匹配到的单引号、双引号或反引号
        "end": "\\1",
        "endCaptures": {
          "0": {
            "name": "string"
          }
        },
        // 表示匹配到的内容应用的作用范围名称
        "contentName": "text.html",
        "patterns": [
          {
            // 引用了名为 `text.html.derivative` 的规则。
            // 这个规则定义了匹配一般的 HTML 标签内容的语法规则
            "include": "text.html.derivative"
          }
        ]
      }
    }
  }
  1. "injectionSelector": "L:meta.decorator.ts -comment -text.html":表示在哪些作用范围中注入这个语法规则。L:meta.decorator.ts 表示注入到 TypeScript 中的装饰器作用范围中,-comment -text.html 表示排除注释和 HTML 作用范围。这样配置后,inline-template.vg 的语法规则会应用于 TypeScript 文件的装饰器中,但不会影响注释和 HTML 部分,L:代表注入的语法添加在现有语法规则的左边。也就是说我们注入的语法规则会在任何现有语法规则之前生效
  2. "inlineTemplate"匹配范围是template:开始到,或者} 但不含,或者},举例说明一下:
  3. js复制代码
  4. @Component({ styleUrls: ['./demo.less'], template: `<div></div>`}) export default class AngularDemo{}
  5. 从这个例子来看,结束标志是}但不包含}也就是说真正匹配的范围是 `<div></div>`注意第一个`前还有一个空格
  6. js复制代码
  7. @Component({ template: `<div></div>`, styleUrls: ['./demo.less'], }) export default class AngularDemo{}
  8. 从这个例子来看,结束标志是,但不包含,也就是说真正匹配的范围是 `<div></div>`注意第一个`前还有一个空格
  9. 插件运行效果
  10. 我们可以看到现在template值不是字符串样式,具备了html的语法高亮了,离目标又进了一步

  11. 目前我们还只是对template值这个大的范围定义了规则,还有插值语法属性绑定语法事件绑定语法等没实现, 本文中以插值语法为例,其他语法的实现就不一一详细描述了。
  12. 实现插值语法的高亮效果
  13. 改造package.json 由于我们的template语法不仅在行内模板生效,也在单独的html的文件中生效,所以单独提取template.vg规则
  14. json复制代码
  15. "contributes": { "grammars": [ { "path": "./syntaxes/inline-template.json", "scopeName": "inline-template.vg", "injectTo": [ "source.ts" ], "embeddedLanguages": { "text.html": "html", "source.css": "css" } }, { "path": "./syntaxes/template.json", "scopeName": "template.vg", "injectTo": [ "text.html.derivative", "source.ts" ], "embeddedLanguages": { "text.html": "html", "source.css": "css" } } ] }
  16. 编写template规则
  17. json复制代码
  18. { "scopeName": "template.vg", // 在HTML 作用范围该规则生效 "injectionSelector": "L:text.html -comment", "patterns": [ { // 插值语法匹配规则 "include": "#interpolation" } ], "repository": { "interpolation": { "begin": "{{", "beginCaptures": { "0": { "name": "punctuation.definition.block.ts" } }, "end": "}}", "endCaptures": { "0": { "name": "punctuation.definition.block.ts" } }, "patterns": [ { "include": "#expression" } ] }, "expression": { "name": "meta.expression.ng", "patterns": [ { "include": "#identifiers" } ] }, "identifiers": { "patterns": [ { // 变量名匹配规则 "name": "variable.other.readwrite.ts", "match": "[_$[:alpha:]][_$[:alnum:]]*" } ] } } }
  19. injectionSelector(注入选择器)来指定在HTML作用范围内生效的规则,但这个选择器不会在注释中中生效。
    解释下为什么在inline-template.vg中不需要引用template.vg规则。 原因在于,inline-template.vg规则中已经声明了text.html范围。由于inline-template.vg是在template.vg中嵌套的,它会继承template.vg的作用范围,因此我们无需在inline-template.vg中额外引用template.vg的规则。
    通过这种方式,我们可以在不产生冲突的情况下,有效地定义不同范围内的样式,使得代码高亮在Vue模板中得到正确的应用,这样的设计使得我们能够更加灵活地管理规则,并确保在不同层级的嵌套中,样式能够正确地展示。这是Vue代码高亮插件开发中值得关注的一点,也是提高插件质量和稳定性的重要步骤。
  20. 插件运行效果如下:
  21. 我们可以看到现在变量高亮正常显示了,不过目前还有很多问题,插值语法内不仅仅只有变量,还有字符串,数字等。

  22. 支持字符串(其他的类似): 在规则中加入如下规则即可
  23. json复制代码
  24. "qstringDouble": { "name": "string.quoted.double.ts", "begin": """, "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.ts" } }, "end": "(")|((?:[^\\n])$)", "endCaptures": { "1": { "name": "punctuation.definition.string.end.ts" }, "2": { "name": "invalid.illegal.newline.ts" } }, "patterns": [ { "include": "#stringCharacterEscape" } ] }, "qstringSingle": { "name": "string.quoted.single.ts", "begin": "'", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.ts" } }, "end": "(\')|((?:[^\\n])$)", "endCaptures": { "1": { "name": "punctuation.definition.string.end.ts" }, "2": { "name": "invalid.illegal.newline.ts" } }, "patterns": [ { "include": "#stringCharacterEscape" } ] }, "stringCharacterEscape": { "name": "constant.character.escape.ts", "match": "\(x\h{2}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.|$)" }

总结

本文详细介绍了如何编写语法高亮插件,为VSCode中的Vue 面向对象插件代码提供良好的颜色标识,以提升代码的可读性。尽管我们在此只给出了一个简单的示例,但是实际开发一个完整的语言插件是相当复杂的过程。

在插件开发的过程中,我们面临着诸多挑战,包括对语法规则的定义、智能提示的实现、错误检查的处理以及代码片段的提供。这些都需要深入理解VSCode插件开发的相关API和机制,以及对目标语言的深刻理解。

本文虽然无法详尽地展示每个细节,但我们希望通过抛砖引玉,给各位道友提供了关键的思路和基本的开发过程。自制VSCode语言插件是一项具有挑战性但又极具成就感的任务。随着我们逐步学习和实践,我们相信能够越来越熟练地开发出功能强大的插件,为自己和其他开发者带来更加优秀的开发体验。

工具篇的道路任重而道远,本文只是一个起点,未来还有许多知识和技巧等待我们探索和应用。在接下来的系列文章中,我们将持续探讨更多有关VSCode语言插件的内容,包括智能提示、错误检查和代码片段等方面的开发,敬请期待!

让我们携手共进,共同开发出更加优秀的VSCode语言插件,为开发者的工作带来更多便利与创造力。未完待续,敬请期待下一篇的精彩内容!



原文链接:https://juejin.cn/post/7264176460755566652