1 安装Hugo [Mac]

官网教程

  1. 安装brew
1
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
  1. 运行brew安装hugo
1
brew install hugo

2 生成站点

1
2
hugo new site /path/to/site -f yml \
  && cd /path/to/site

3 安装主题

在你的站点文件夹运行

1
git clone https://github.com/reorx/hugo-PaperModX themes/PaperModX --depth=1

Sample config.yml

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
baseURL: "https://examplesite.com/"
languageCode: en-us
title: My New Hugo Site
theme: PaperModX

enableRobotsTXT: true
buildDrafts: false
buildFuture: false
buildExpired: false
pygmentsUseClasses: true

googleAnalytics: UA-123-45

enableEmoji: true

minify:
    disableXML: true
    minifyOutput: true

params:
    env: production # to enable google analytics, opengraph, twitter-cards and schema.
    title: ExampleSite
    description: "ExampleSite description"
    keywords: [Blog, Portfolio, PaperModX]
    author: Me
    # author: ["Me", "You"] # multiple authors
    images: ["<link or path of image for opengraph, twitter-cards>"]
    DateFormat: "January 2, 2006"
    defaultTheme: auto # dark, light
    disableThemeToggle: false

    ShowReadingTime: true
    ShowShareButtons: true
    ShowPostNavLinks: true
    ShowBreadCrumbs: true
    ShowCodeCopyButtons: true # 显示代码复制按钮
    disableSpecial1stPost: false
    disableScrollToTop: false
    comments: false
    hidemeta: false
    hideSummary: false
    showtoc: false
    tocopen: false

    math: true # MathJex设置

    homeInfoParams:
        Title: Hi there wave
        Content: Can be Info, links, about..
    
    socialIcons: # optional
        - name: "<platform>"
          url: "<link>"
        - name: "<platform 2>"
          url: "<link2>"

    assets:
        # disableFingerprinting: true
        favicon: "<link / abs url>"
        favicon16x16: "<link / abs url>"
        favicon32x32: "<link / abs url>"
        apple_touch_icon: "<link / abs url>"
        safari_pinned_tab: "<link / abs url>"

    label:
        text: "Home"
        icon: /apple-touch-icon.png
        iconHeight: 35

    # profile-mode
    profileMode:
        enabled: false # needs to be explicitly set
        title: ExampleSite
        subtitle: "This is subtitle"
        imageUrl: "<img location>"
        imageWidth: 120
        imageHeight: 120
        imageTitle: my image
        buttons:
            - name: Posts
              url: posts
            - name: Tags
              url: tags

    # home-info mode
    homeInfoParams:
        Title: "Hi there \U0001F44B"
        Content: Welcome to my blog

    socialIcons:
        - name: twitter
          url: "https://twitter.com/"
        - name: stackoverflow
          url: "https://stackoverflow.com"
        - name: github
          url: "https://github.com/"

    analytics:
        google:
            SiteVerificationTag: "XYZabc"
        bing:
            SiteVerificationTag: "XYZabc"
        yandex:
            SiteVerificationTag: "XYZabc"

    cover:
        hidden: true # hide everywhere but not in structured data
        hiddenInList: true # hide on list pages and home
        hiddenInSingle: true # hide on single page
        # responsiveImages: false # To reduce generation time and size of the site, you can disable this feature
        # linkFullImages: true # To enable hyperlinks to the full image size on post pages

    editPost:
        URL: "https://github.com/<path_to_repo>/content"
        Text: "Suggest Changes" # edit text
        appendFilePath: true # to append file path to Edit link

    # for search
    # https://fusejs.io/api/options.html
    fuseOpts:
        isCaseSensitive: false
        shouldSort: true
        location: 0
        distance: 1000
        threshold: 0.4
        minMatchCharLength: 0
        keys: ["title", "permalink", "summary", "content"]
menu:
    main:
        - identifier: Archives
          name: Archives
          url: /archives/
          weight: 10
        # - identifier: categories
        #   name: categories
        #   url: /categories/
        #   weight: 10
        - identifier: Tags
          name: Tags
          url: /tags/
          weight: 20
        # - identifier: example
        #   name: example.org
        #   url: https://example.org
        #   weight: 30
        - identifier: Search
          name: Search
          url: /search
          weight: 30

outputs:
    home:
        - HTML
        - RSS
        - JSON # is necessary

# Read: https://github.com/reorx/hugo-PaperModX/wiki/FAQs#using-hugos-syntax-highlighter-chroma
pygmentsUseClasses: true
markup:
    highlight:      # 代码高亮
        # anchorLineNos: true
        codeFences: true
        guessSyntax: true
        lineNos: true
        style: monokai
    goldmark:       
      renderer:
        unsafe: true    # 关闭安全模式

新建文章

1
hugo new posts/yourarticlename.md

本地调试

执行命令后,在浏览器打开http://localhost:1313可预览网站

1
hugo server -D

-D可看到草稿文章

部署Github

1
hugo    ##生成静态页面文件

在命令执行后,出现一个public文件夹,里面就是网站的静态页面文件 进入public文件夹,使用git上传文件

1
2
3
4
5
6
cd public
git init    ##初始化仓库
git remote add origin https://github.com/caecarxu/caecarxu.github.io.git    ##链接远程仓库
git add .
git commit -m "first commit"
git push -u origin master

在此之后更新文章,使用hugo生成新的静态页面,并使用git push进行同步

1
2
3
4
5
cd public
git add .
git status
git commit -m "add blog post"
git push

5 主题设置

MathJex

创建partials/math.html文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!-- Mathjex -->
<script>
    MathJax = {
      tex: {
        inlineMath: [['$', '$'], ['\\(', '\\)']],
        displayMath: [['$$','$$'], ['\\[', '\\]']],
        processEscapes: true,
        processEnvironments: true
      },
      options: {
        skipHtmlTags: ['script', 'noscript', 'style', 'textarea', 'pre']
      }
    };
  
    window.addEventListener('load', (event) => {
        document.querySelectorAll("mjx-container").forEach(function(x){
          x.parentElement.classList += 'has-jax'})
      });
  
  </script>
  <script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
  <script type="text/javascript" id="MathJax-script" async
    src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>

blank.css中添加

1
2
3
4
5
6
code.has-jax {
    -webkit-font-smoothing: antialiased;
    background: inherit !important;
    border: none !important;
    font-size: 100%;
}

全局开启公式渲染,在partials/extend_head.html中加入

1
2
3
{{ if or .Params.math .Site.Params.math }}
{{ partial "math.html" . }}
{{ end }}

config.yml中加入

1
2
params:
    math: true

图片caption居中

blank.css中添加

1
2
3
figcaption {
    text-align: center;
}

进一步更改图片caption样式可以在main.css中更改.post-warp .post-content .image-caption:not(:empty) 元素的值,例如

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
.post-warp .post-content .image-caption:not(:empty) {
    min-width: 20%;
    max-width: max-content;    
    /* display: inline-block; */
    padding: 3px;
    margin: 8px auto;
    border-bottom: 1px solid #d9d9d9;
    font-size: 14px;
    color: #969696;
    line-height: 1.7;
}

显示代码copy按钮

1
ShowCodeCopyButtons: true

可以在main.css中修改codecopybutton样式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
.copy-code {
    display: none;
    position: absolute;
    top: 4px;
    right: 4px;
    color: rgba(255, 255, 255, 0.8);
    background: rgba(78, 78, 78, 0.8);
    border-radius: var(--radius);
    padding: 0 5px;
    font-size: 14px;
    user-select: none;
}
div.highlight:hover .copy-code,
pre:hover .copy-code {
    display: block;
}

代码块滚动

通过css控制,给代码块设置个最大高度。在blank.css中添加:

1
2
3
pre {
    max-height: 500px;
}

shortcode

  1. 标签,源文件来自@martignoni
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
{{/* Available notice types: warning, info, note, tip */}}
{{- $noticeType := .Get 0 | default "note" -}}
{{- $title := .Get 1 | default $noticeType -}}
{{/* Workaround markdownify inconsistency for single/multiple paragraphs */}}
{{- $raw := (markdownify .Inner | chomp) -}}
{{- $block := findRE "(?is)^<(?:address|article|aside|blockquote|canvas|dd|div|dl|dt|fieldset|figcaption|figure|footer|form|h(?:1|2|3|4|5|6)|header|hgroup|hr|li|main|nav|noscript|ol|output|p|pre|section|table|tfoot|ul|video)\\b" $raw 1 -}}
{{/* Count how many times we've called this shortcode and load the css if it's the first time */}}
{{- if not ($.Page.Scratch.Get "noticecount") -}}
<!-- <style type="text/css">.notice{--root-color:#444;--root-background:#e8e3f6b3;--title-color:#444;--title-background:#e8e3f6;--warning-title:#c33;--warning-content:#fee;--info-title:#fb7;--info-content:#fec;--note-title:#6be;--note-content:#e8e3f6b3;--tip-title:#5a5;--tip-content:#efe}@media (prefers-color-scheme:dark){.notice{--root-color:#ddd;--root-background:#eff;--title-color:#fff;--title-background:#7bd;--warning-title:#800;--warning-content:#400;--info-title:#a50;--info-content:#420;--note-title:#069;--note-content:#023;--tip-title:#363;--tip-content:#121}}body.dark .notice{--root-color:#ddd;--root-background:#eff;--title-color:#fff;--title-background:#7bd;--warning-title:#800;--warning-content:#400;--info-title:#a50;--info-content:#420;--note-title:#069;--note-content:#023;--tip-title:#363;--tip-content:#121}.notice{padding:18px;line-height:24px;margin-bottom:24px;border-radius:4px;color:var(--root-color);background:var(--root-background)}.notice p:last-child{margin-bottom:0}.notice-title{margin:-18px -18px 12px;padding:4px 18px;border-radius:4px 4px 0 0;font-weight:700;color:var(--title-color);background:var(--title-background)}.notice.warning .notice-title{background:var(--warning-title)}.notice.warning{background:var(--warning-content)}.notice.info .notice-title{background:var(--info-title)}.notice.info{background:var(--info-content)}.notice.note .notice-title{background:var(--note-title)}.notice.note{background:var(--note-content)}.notice.tip .notice-title{background:var(--tip-title)}.notice.tip{background:var(--tip-content)}.icon-notice{display:inline-flex;align-self:center;margin-right:8px}.icon-notice img,.icon-notice svg{height:1em;width:1em;fill:currentColor}.icon-notice img,.icon-notice.baseline svg{top:.125em;position:relative}</style> -->
<style type="text/css">.notice{--root-color:#444;--root-background:#eff;--title-color:#fff;--title-background:#7bd;--warning-title:#c33;--warning-content:#fee;--info-title:#fb7;--info-content:#fec;--note-title:#6be;--note-content:#e7f2fa;--tip-title:#5a5;--tip-content:#efe}@media (prefers-color-scheme:dark){.notice{--root-color:#ddd;--root-background:#eff;--title-color:#fff;--title-background:#7bd;--warning-title:#800;--warning-content:#400;--info-title:#a50;--info-content:#420;--note-title:#069;--note-content:#023;--tip-title:#363;--tip-content:#121}}body.dark .notice{--root-color:#ddd;--root-background:#eff;--title-color:#fff;--title-background:#7bd;--warning-title:#800;--warning-content:#400;--info-title:#a50;--info-content:#420;--note-title:#069;--note-content:#023;--tip-title:#363;--tip-content:#121}.notice{padding:18px;line-height:24px;margin-bottom:24px;border-radius:4px;color:var(--root-color);background:var(--root-background)}.notice p:last-child{margin-bottom:0}.notice-title{margin:-18px -18px 12px;padding:4px 18px;border-radius:4px 4px 0 0;font-weight:700;color:var(--title-color);background:var(--title-background)}.notice.warning .notice-title{background:var(--warning-title)}.notice.warning{background:var(--warning-content)}.notice.info .notice-title{background:var(--info-title)}.notice.info{background:var(--info-content)}.notice.note .notice-title{background:var(--note-title)}.notice.note{background:var(--note-content)}.notice.tip .notice-title{background:var(--tip-title)}.notice.tip{background:var(--tip-content)}.icon-notice{display:inline-flex;align-self:center;margin-right:8px}.icon-notice img,.icon-notice svg{height:1em;width:1em;fill:currentColor}.icon-notice img,.icon-notice.baseline svg{top:.125em;position:relative}</style>
<div><svg width="0" height="0" display="none" xmlns="http://www.w3.org/2000/svg"><symbol id="tip-notice" viewBox="0 0 512 512" preserveAspectRatio="xMidYMid meet"><path d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"/></symbol><symbol id="note-notice" viewBox="0 0 512 512" preserveAspectRatio="xMidYMid meet"><path d="M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"/></symbol><symbol id="warning-notice" viewBox="0 0 576 512" preserveAspectRatio="xMidYMid meet"><path d="M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"/></symbol><symbol id="info-notice" viewBox="0 0 512 512" preserveAspectRatio="xMidYMid meet"><path d="M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z"/></symbol></svg></div>
{{- end -}}
{{- $.Page.Scratch.Add "noticecount" 1 -}} 
<div class="notice {{ $noticeType }}" {{ if len .Params | eq 3 }} id="{{ .Get 2 }}" {{ end }}>
<p class="first notice-title"><span class="icon-notice baseline"><svg><use href="#{{- $noticeType -}}-notice"></use></svg></span>{{ $title }}</p>
{{- if or $block (not $raw) }}{{ $raw }}{{ else }}<p>{{ $raw }}</p>{{ end -}}
</div>

效果如下:

title

This is a tip.

title

This is a notice.

title

This is a warning.

title

This is a info.


参考链接