Repository: zchen9/hexo-theme-hollow
Branch: master
Commit: 23bf05a05b33
Files: 39
Total size: 35.0 KB
Directory structure:
gitextract_d7sopokl/
├── .gitignore
├── LICENSE
├── README.md
├── languages/
│ ├── default.yml
│ ├── en.yml
│ ├── zh-CN.yml
│ ├── zh-Hans.yml
│ └── zh-TW.yml
├── layout/
│ ├── _partial/
│ │ ├── article-archive.ejs
│ │ ├── article-categories.ejs
│ │ ├── article-full.ejs
│ │ ├── article-index.ejs
│ │ ├── article-tags.ejs
│ │ ├── backhome.ejs
│ │ ├── comment.ejs
│ │ ├── google-analytics.ejs
│ │ ├── gosite.ejs
│ │ ├── head.ejs
│ │ ├── img-viewer.ejs
│ │ ├── pagination.ejs
│ │ ├── scripts.ejs
│ │ ├── search.ejs
│ │ ├── service-worker.ejs
│ │ └── toc.ejs
│ ├── archive.ejs
│ ├── index.ejs
│ ├── layout.ejs
│ ├── page.ejs
│ └── post.ejs
└── source/
├── css/
│ ├── article.styl
│ ├── base.styl
│ ├── custom.styl
│ ├── darkmode.styl
│ ├── mixins.styl
│ ├── more.styl
│ ├── style.styl
│ ├── toc.styl
│ └── variables.styl
└── sw.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
node_modules
_config.yml
================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2016 zchen9(zhao.zchen9@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
================================================
FILE: README.md
================================================
# Hexo-theme-hollow
一款极致简洁的博客主题,可访问 [My Fragment](https://www.chen9.info/fragment/) 查看效果
## 安装
在你的 Hexo 博客仓库下 clone 主题
```
git clone https://github.com/zchen9/hexo-theme-hollow.git themes/hollow
```
在博客下的 _config.yml 文件修改主题为 hollow
```
theme: hollow
```
启动博客
```
hexo clean
hexo generate
hexo server
```
发布博客
```
hexo deploy
```
## 配置
主题下的 _config.yml 文件
```
# Camera icon for website
# 填写 baseurl 开启主页小相机,也可以在博客根目录的 _config.yml 文件末尾添加
baseurl:
# Default post title
# 默认文章标题
default_post_title: Halo
# Date Format
# 文章时间戳格式
# 也可以在博客主体的 _config.yml 配置,优先取博客主体的时间配置
date_format: YYYY 年 MM 月 DD 日
# Comment.
comments:
# Disqus comment
# 填写 disqus_shortname 即可使用 disqus
disqus_shortname:
# Google Analytics Tracking ID
# 填写谷歌分析跟踪 ID,使用谷歌分析应用
google_analytics:
# Register service worker
# 使用 Service Workers
service_worker: false
# Local search with atom.xml, dependency hexo-generator-feed plugin
# 主页搜索服务,依赖插件 hexo-generator-feed
# 需要运行 npm install hexo-generator-feed --save 安装此插件
local_search: true
# using viewer.js to view image
# https://fengyuanchen.github.io/viewerjs/
# 使用 viewer.js 查看图片
image_viewer: true
# Table of content
# Maybe support more toc style in future.
# 文章目录
# 也许在之后的更新中会支持更多目录样式
toc:
enable: true
```
## 文章格式
以下为 markdown 格式:
```
title: <文章标题>
category: <文章分类>
date: <文章日期> [YYYY-MM-DD]
---
文章预览内容
<!--more-->
文章正文在此
```
## CHANGELOG
20220202 @zchen9
- 调整 toc 样式
- 修复 Bootstrap CDN 404 问题
- 更新小相机配置
20210424 @zchen9
- 调整细节样式
- 优化深色模式配色
20210424 @fakeYanss [pull/44](https://github.com/zchen9/hexo-theme-hollow/pull/44)
- 支持文章目录
- 支持深色模式
20190526 @zchen9
- 主页开放小相机
- 微调阅读样式
- 优化搜索功能
20190519 @fakeYanss [pull/36](https://github.com/zchen9/hexo-theme-hollow/pull/36)
- 增加service worker
- 本地搜索
- 文章图片放大查看
## 其他
- 作者很懒,更新频率看心情,欢迎贡献你的设计
## LICENSE
[MIT](https://github.com/zchen9/hexo-theme-hollow/blob/master/LICENSE)
================================================
FILE: languages/default.yml
================================================
prev: 上一页
next: 下一页
comment: 留言
archive_a: 归档
archive_b: 归档:%s
================================================
FILE: languages/en.yml
================================================
prev: Older Posts
next: Newer Posts
comment: Comments
archive_a: Archives
archive_b: "Archives: %s"
================================================
FILE: languages/zh-CN.yml
================================================
prev: 上一页
next: 下一页
comment: 留言
archive_a: 归档
archive_b: 归档:%s
================================================
FILE: languages/zh-Hans.yml
================================================
prev: 上一页
next: 下一页
comment: 留言
archive_a: 归档
archive_b: 归档:%s
================================================
FILE: languages/zh-TW.yml
================================================
prev: 上一頁
next: 下一頁
comment: 留言
archive_a: 彙整
archive_b: 彙整:%s
================================================
FILE: layout/_partial/article-archive.ejs
================================================
<div class="post-preview archive">
<a href="<%- config.root %><%- item.path %>">
<h1 class="post-title archive">
<%- item.title || theme.default_post_title || "Untitled" %>
</h1>
</a>
</div>
================================================
FILE: layout/_partial/article-categories.ejs
================================================
<%
var categories = [];
item.categories.forEach(function(category){
categories.push('<a href="' + config.root + category.path + '">' + category.name + '</a>');
});
%>
<%- categories.join('/ ') %>
================================================
FILE: layout/_partial/article-full.ejs
================================================
<section class="article-container">
<!-- Back Home -->
<%- partial('_partial/backhome') %>
<!-- Page Header -->
<header class="intro-header">
<div class="container">
<div class="row">
<div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
<div class="post-heading">
<h1>
<%- item.title || theme.default_post_title || "Untitled" %>
</h1>
</div>
</div>
</div>
</div>
</header>
<!-- Post Content -->
<article>
<div class="container">
<div class="row">
<!-- Post Main Content -->
<div class="post-content col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
<%- item.content %>
<!-- Meta -->
<div class="post-meta">
<hr>
<br>
<div class="post-tags">
<% if (item.tags && item.tags.length){ %>
<%- partial('article-tags', {item: item}) %>
<% } else if (item.categories && item.categories.length) { %>
<%- partial('article-categories', {item: item}) %>
<% } %>
</div>
<div class="post-date">
<% if (item.date){ %>
<%- item.date.format(config.date_format || theme.date_format) %>
<% } %>
</div>
</div>
</div>
<!-- Comments -->
<div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
<%- partial("_partial/comment.ejs") %>
</div>
</div>
</div>
</article>
</section>
<!-- Image viewer-->
<%- partial('_partial/img-viewer') %>
<!-- TOC -->
<%- partial("_partial/toc", {post: item}) %>
================================================
FILE: layout/_partial/article-index.ejs
================================================
<div class="post-preview">
<a href="<%- config.root %><%- item.path %>">
<h2 class="post-title">
<%- item.title || theme.default_post_title || "Untitled" %>
</h2>
<%- item.excerpt %>
</a>
</div>
================================================
FILE: layout/_partial/article-tags.ejs
================================================
<%
var tags = [];
item.tags.forEach(function(tag){
tags.push('<a href="' + config.root + tag.path + '">#' + tag.name + '</a>');
});
%>
<%- tags.join(' ') %>
================================================
FILE: layout/_partial/backhome.ejs
================================================
<a class="nav-back" href="<%- config.root %>">
<i class="fa fa-puzzle-piece"></i>
</a>
================================================
FILE: layout/_partial/comment.ejs
================================================
<!-- Disqus Comments -->
<% if (theme.comments && theme.comments.disqus_shortname){ %>
<div id="disqus_thread" class="comment"></div>
<script>
var disqus_shortname = '<%= theme.comments.disqus_shortname %>';
var disqus_website = '<%= theme.baseurl %>';
var disqus_config = function () {
this.page.url = disqus_website;
this.page.identifier = disqus_shortname;
};
(function () {
var d = document, s = d.createElement('script');
s.src = 'https://' + disqus_shortname + '.disqus.com/embed.js';
s.setAttribute('data-timestamp', +new Date());
(d.head || d.body).appendChild(s);
})();
</script>
<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript">comments powered by
Disqus.</a></noscript>
<% } %>
================================================
FILE: layout/_partial/google-analytics.ejs
================================================
<% if (theme.google_analytics){ %>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', '<%= theme.google_analytics %>', 'auto');
ga('send', 'pageview');
</script>
<% } %>
================================================
FILE: layout/_partial/gosite.ejs
================================================
<% if (config.baseurl || theme.baseurl) { %>
<a class="nav-back" href="<%- config.baseurl || theme.baseurl %>">
<i class="fa fa-camera-retro"></i>
</a>
<% } %>
================================================
FILE: layout/_partial/head.ejs
================================================
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!--Description-->
<% if (page.description){ %>
<meta name="description" content="<%= page.description %>">
<% } else if (config.description){ %>
<meta name="description" content="<%= config.description %>">
<% } else if (page.excerpt){ %>
<meta name="description" content="<%= strip_html(page.excerpt).replace(/^\s*/, '').replace(/\s*$/, '') %>">
<% } else if (page.content){ %>
<meta name="description" content="<%= strip_html(page.content).replace(/^\s*/, '').replace(/\s*$/, '').substring(0, 150) %>">
<% } %>
<!--Author-->
<% if (config.author){ %>
<meta name="author" content="<%= config.author %>">
<% } %>
<!-- Title -->
<%
var title = [];
if (page.current > 1) title.push(__('page', page.current));
if (page.title) title.push(page.title);
if (page.category) title.push(page.category);
if (page.tag) title.push(page.tag);
if (page.archive) {
if (page.year) title.push(__('archive_b', page.year + (page.month ? '/' + page.month : '')));
else title.push(__('archive_a'));
}
title.push(config.title);
%>
<title><%= title.join(' | ') %></title>
<!-- Bootstrap Core CSS -->
<link href="//cdn.jsdelivr.net/npm/bootstrap@3.3.6/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Custom CSS -->
<%- css('css/style.css') %>
<!-- Custom Fonts -->
<link href="//cdn.jsdelivr.net/npm/font-awesome@4.5.0/css/font-awesome.min.css" rel="stylesheet" type="text/css">
<link href='//fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800' rel='stylesheet' type='text/css'>
<link href='//fonts.googleapis.com/css?family=Noto+Serif:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800' rel='stylesheet' type='text/css'>
<!-- jQuery -->
<script src="//cdn.bootcss.com/jquery/2.2.1/jquery.min.js"></script>
<!-- Bootstrap -->
<script src="//cdn.jsdelivr.net/npm/bootstrap@3.3.6/dist/js/bootstrap.min.js"></script>
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
================================================
FILE: layout/_partial/img-viewer.ejs
================================================
<% if (theme.image_viewer){ %>
<!-- Custom picture view-->
<link href="<%= config.root %>css/viewer.min.css" rel="stylesheet" />
<script
src="<%= config.root %>js/viewer.min.js"
type="text/javascript"
charset="utf-8"
></script>
<script type="text/javascript">
// set image viewer
Viewer.setDefaults({
zoomRatio: [0.5],
navbar: false,
toolbar: false,
button: false,
title: [2, (image, imageData) => `${image.alt}`],
show: function() {
this.viewer.zoomTo(0.5);
}
});
var imageList = document.getElementsByTagName("img");
Array.prototype.forEach.call(imageList, element => {
var viewer = new Viewer(element);
});
</script>
<% } %>
================================================
FILE: layout/_partial/pagination.ejs
================================================
<ul class="pagiantion">
<% if (page.prev){ %>
<li class="previous"><a href="<%- config.root %><%- page.prev_link %>"><%- __('prev')%></a></li>
<% } %>
<% if (page.next){ %>
<li class="next"><a href="<%- config.root %><%- page.next_link %>"><%- __('next')%></a></li>
<% } %>
</ul>
================================================
FILE: layout/_partial/scripts.ejs
================================================
<script type="text/javascript">
console.log("© zchen9 🙋 2015-" + new Date().getFullYear());
</script>
================================================
FILE: layout/_partial/search.ejs
================================================
<% if (theme.local_search){ %>
<a class="nav-search" data-toggle="modal" data-target="#searchModalCenter">
<i class="fa fa-search"></i>
</a>
<div
class="modal fade"
id="searchModalCenter"
tabindex="-1"
role="dialog"
aria-labelledby="searchModalCenterTitle"
aria-hidden="true"
>
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<input
type="text"
id="local-search-input"
class="form-control"
placeholder="<%- config.search_placeholder %>"
/>
</div>
<div class="modal-body">
<div id="local-search-result"></div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
// define the search function
var searchFunc = function(path, search_id, content_id) {
"use strict";
$.ajax({
url: path,
dataType: "xml",
success: function(xmlResponse) {
// get the contents from search data
var datas = $("entry", xmlResponse)
.map(function() {
return {
title: $("title", this).text(),
content: $("content", this).text(),
url: $("id", this).text()
};
})
.get();
var $input = document.getElementById(search_id);
var $resultContent = document.getElementById(content_id);
$input.addEventListener("input", function() {
var str = '<ul class="search-result-list">';
var keywords = this.value
.trim()
.toLowerCase()
.split(/[\s\-]+/);
$resultContent.innerHTML = "";
if (this.value.trim().length <= 0) {
return;
}
// perform local searching
datas.forEach(function(data) {
var isMatch = true;
var content_index = [];
var data_title = data.title.trim().toLowerCase();
var data_content = data.content
.trim()
.replace(/<[^>]+>/g, "")
.toLowerCase();
var data_url = data.url;
var index_title = -1;
var index_content = -1;
var first_occur = -1;
// only match artiles with not empty titles and contents
if (data_title != "" && data_content != "") {
keywords.forEach(function(keyword, i) {
index_title = data_title.indexOf(keyword);
index_content = data_content.indexOf(keyword);
if (index_title < 0 && index_content < 0) {
isMatch = false;
} else {
if (index_content < 0) {
index_content = 0;
}
if (i == 0) {
first_occur = index_content;
}
}
});
}
// show search results
if (isMatch) {
str +=
"<li><a href='" +
data_url +
"' class='search-result-title'>" +
data_title;
var content = data.content.trim().replace(/<[^>]+>/g, "");
if (first_occur >= 0) {
// cut out 30 characters
var start = first_occur - 15;
var end = first_occur + 15;
if (start < 0) {
start = 0;
}
if (start == 0) {
end = 30;
}
if (end > content.length) {
end = content.length;
}
var match_content = content.substr(start, end);
// highlight all keywords
keywords.forEach(function(keyword) {
var regS = new RegExp(keyword, "gi");
match_content = match_content.replace(
regS,
'<em class="search-keyword">' + keyword + "</em>"
);
});
str += '<p class="search-result">' + match_content + "...</p>";
}
str += "</a></li>";
}
});
str += "</ul>";
$resultContent.innerHTML = str;
});
}
});
};
// use atom.xml to search blog
searchFunc("<%- config.root %>atom.xml", "local-search-input", "local-search-result");
$("#searchModalCenter").on("shown.bs.modal", function(e) {
setTimeout(function() {
$("#local-search-input").focus();
}, 1);
});
</script>
<% } %>
================================================
FILE: layout/_partial/service-worker.ejs
================================================
<!-- if using service worker -->
<% if (theme.service_worker){ %>
<script text="module">
if ("serviceWorker" in navigator) {
navigator.serviceWorker
.register("/sw.js")
.then(function() {
console.log("A new service worker is being installed.");
})
.catch(function(error) {
console.log("Service worker registration failed:", error);
});
} else {
console.log("Service workers are not supported.");
}
</script>
<% } %>
================================================
FILE: layout/_partial/toc.ejs
================================================
<% if (theme.toc.enable){ %>
<aside id="article-toc" role="navigation" class="fixed">
<div id="article-toc-inner">
<%- toc(post.content, {list_number: false}) %>
</div>
</aside>
<% } %>
================================================
FILE: layout/archive.ejs
================================================
<%
var title = '';
if (page.category) title = page.category;
if (page.tag) title = "#" + page.tag;
if (page.archive) {
if (page.year) title = page.year + (page.month ? '/' + page.month : '');
else title = __('archive_a');
}
%>
<!-- Back Home -->
<%- partial('_partial/backhome') %>
<!-- Page Header -->
<header class="intro-header">
<div class="container">
<div class="row">
<div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
<div class="site-heading">
<h1><%- title %></h1>
</div>
</div>
</div>
</div>
</header>
<!-- Main Content -->
<div class="container">
<div class="row">
<div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
<% page.posts.each(function(item){ %>
<%- partial('_partial/article-archive', {item: item}) %>
<% }); %>
<div class="archive-before-pagination"></div>
<%- partial('_partial/pagination') %>
</div>
</div>
</div>
================================================
FILE: layout/index.ejs
================================================
<!-- Go Site -->
<%- partial('_partial/gosite') %>
<!-- Main Content -->
<section class="intro">
<div class="container">
<div class="row">
<div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
<% page.posts.each(function(item){ %>
<%- partial('_partial/article-index', {item: item}) %>
<% }); %>
</div>
</div>
<!-- Pagination -->
<%- partial('_partial/pagination') %>
<!-- Search -->
<%- partial('_partial/search') %>
</div>
</section>
================================================
FILE: layout/layout.ejs
================================================
<!DOCTYPE html>
<html lang="zh-Hans">
<!-- Head tag -->
<%- partial('_partial/head') %>
<body>
<!-- Content -->
<%- body %>
<!-- Scripts -->
<%- partial('_partial/scripts') %>
<!-- Google Analytics -->
<%- partial('_partial/google-analytics') %>
<!-- Service Worker -->
<%- partial('_partial/service-worker') %>
</body>
</html>
================================================
FILE: layout/page.ejs
================================================
<%- partial('_partial/article-full', {item: page}) %>
================================================
FILE: layout/post.ejs
================================================
<%- partial('_partial/article-full', {item: page}) %>
================================================
FILE: source/css/article.styl
================================================
@import "mixins.styl"
@import "variables.styl"
.article-container
@extend .animation
article
.container
.row
// Responsive Images
img
position relative
margin 30px auto
max-width 55% !important
height auto
display inline-block
box-shadow 0 0 0 5px #FFF, 0 0 15px 0 gray-dark
@media only screen and (max-width: 768px)
img {
max-width 80% !important
}
// Video Containers
.video-container
position relative
padding-bottom 56.25%
padding-top 30px
height 0
overflow hidden
iframe, object, embed
position absolute
top 0
left 0
width 100%
height 100%
margin-top 0
blockquote
font-family font-serif
font-size 1em
padding 3px 30px 15px
color gray
text-align left
footer
border-top none
font-size 0.8em
line-height 1
margin 20px 0 0
padding-top 0
cite
&:before
content '—'
color #ccc
padding 0 0.5em
.pullquote
float right
border none
padding 0
margin 1em 0 0.5em 1.5em
text-align left
width 45%
font-size 1.5em
&.left
float left
ul
padding-left 36px
line-height 1.8
figure.highlight
background #eee
border 1px solid color-border
margin-top 15px
padding 7px 15px
border-radius 2px
text-shadow 0 0 1px #fff
line-height 1.6
overflow auto
position relative
font-size 0.9em
figcaption
color color-meta
font-family font-mono
margin-bottom 5px
text-shadow 0 0 1px #fff
a
position absolute
right 15px
pre
border none
padding 0
margin 0
background none
table
margin-top 0
border-spacing 0
.gutter
color color-meta
padding-right 15px
border-right 1px solid color-border
text-align right
.code
padding-left 15px
border-left 1px solid #fff
color #666
.line
height: 20px
.line.marked
background: #d6d6d6
pre
// Theme: Solarized - Light
// More theme here: http://softwaremaniacs.org/media/soft/highlight/test.html
.comment
.template_comment
.diff .header
.doctype
.pi
.lisp .string
.javadoc
color #93a1a1
font-style italic
.keyword
.winutils
.method
.addition
.css .tag
.request
.status
.nginx .title
color #859900
.number
.command
.string
.tag .value
.phpdoc
.tex .formula
.regexp
.hexcolor
color #2aa198
.title
.localvars
.chunk
.decorator
.built_in
.identifier
.vhdl
.literal
.id
color #268bd2
.attribute
.variable
.lisp .body
.smalltalk .number
.constant
.class .title
.parent
.haskell .type
color #b58900
.preprocessor
.preprocessor .keyword
.shebang
.symbol
.symbol .string
.diff .change
.special
.attr_selector
.important
.subst
.cdata
.clojure .title
color #cb4b16
.deletion
color #dc322f
================================================
FILE: source/css/base.styl
================================================
@import "variables.styl"
@import "mixins.styl"
body,
html
width 100%
font-size 18px
color gray-dark
@extend .serif
p
letter-spacing .1px
line-height 1.8
margin 20px 0
a
text-decoration underline
h1, h2, h3
@extend .serif
font-weight 800
margin 32px 0 20px
h4, h5, h6
@extend .serif
font-weight 500
margin 20px 0
a
color red
&:hover, &:focus
color gray-dark
text-decoration none
&:visited, &:link
color red
a img
&:hover, &:focus
cursor zoom-in
hr.small
max-width 100px
margin 20px auto
border-width 4px
border-color white
a.nav-back
position absolute
top 15px
left 15px
color white-faded
z-index 99
&:hover, &:focus
color red
nav
position absolute
top 0
left 0
width 100%
z-index 3
@extend .serif
.intro
width 100%
height 100%
position relative
margin: 80px auto 0
.intro-header
background-color transparent
background no-repeat center center
background-attachment scroll
background-size 100%
@extend .background-cover
margin-bottom 50px
.site-heading, .post-heading, .page-heading
padding 100px 0 20px
color gray-dark
&.archives
color white-faded
margin-top 60px
.site-heading, .page-heading
text-align center
h1
margin-top 0
font-size 2em
color red
.subheading
font-size 24px
line-height 1.1
display block
@extend .serif
font-weight 300
margin 10px 0 0
@media only screen and (min-width: 768px)
h1
font-size 2.2em
.post-heading
h1
font-size 35px
.subheading
line-height 1.1
display block
@extend .serif
font-size 24px
margin 10px 0 30px
font-weight 600
@media only screen and (min-width: 768px)
h1
font-size 55px
.subheading
font-size 30px
.post-preview
position relative
padding 25px 0 35px
min-height 14em
overflow hidden
clear both
@extend .animation
&.archive
padding 12px 0
p
margin-left 36%
padding-left .6em
font-size 1.1em
line-height 1.5
blockquote
margin-left 36%
padding .7em
margin-top 10px
border none
font-size 1em
p
margin 0
padding 0
> a
width 100%
height 100%
color gray-dark
&:hover, &:focus
text-decoration none
> .post-title
color red
> .post-title
float left
width 32%
height 100%
font-size 2em
margin 21px 0
word-wrap break-word
overflow hidden
text-overflow ellipsis
display -webkit-box
-webkit-line-clamp 2
-webkit-box-orient vertical
&.archive
font-size 22px
width 100%
img
display: none
.section-heading
font-size 36px
margin-top 60px
font-weight 700
.caption
text-align center
font-size 14px
padding 10px
font-style italic
margin 0
display block
border-bottom-right-radius 5px
border-bottom-left-radius 5px
.post-content
padding-bottom 100px
.post-meta
padding-top 50px
.post-tags, .post-categories, .post-date
text-align right
font-size 1em
margin 10px 0
a
text-transform uppercase
color red
&:hover, &:visited, &:focus
text-decoration none
.archive-before-pagination
height 50px
.comment
margin 20px 0 100px
footer
padding 50px 0 65px
color white-faded
text-align center
.floating-label-form-group
font-size 14px
position relative
margin-bottom 0
padding-bottom 0.5em
border-bottom 1px solid gray-light
input, textarea
z-index 1
position relative
padding-right 0
padding-left 0
border none
border-radius 0
font-size 1.5em
background none
box-shadow none !important
resize none
label
display block
z-index 0
position relative
top 2em
margin 0
font-size 0.85em
line-height 1.764705882em
vertical-align middle
vertical-align baseline
opacity 0
-webkit-transition top 0.3s ease,opacity 0.3s ease
-moz-transition top 0.3s ease,opacity 0.3s ease
-ms-transition top 0.3s ease,opacity 0.3s ease
transition top 0.3s ease,opacity 0.3s ease
&::not(:first-child)
padding-left 14px
border-left 1px solid gray-light
.floating-label-form-group-with-value
label
top 0
opacity 1
.floating-label-form-group-with-focus
label
color brand-primary
form .row:first-child .floating-label-form-group
border-top 1px solid gray-light
.btn
@extend .serif
text-transform uppercase
font-size 14px
font-weight 800
letter-spacing 1px
border-radius 0
padding 15px 25px
.btn-lg
font-size 16px
padding 25px 35px
.btn-default
&:hover, &:focus
background-color brand-primary
border 1px solid brand-primary
color white
.pagiantion
display block
padding 55px 0
margin 0
text-align center
list-style none
li
display inline
> a, > span
@extend .serif
text-transform uppercase
font-size 14px
font-weight 800
letter-spacing 1px
padding 15px 25px
color white-faded
border none
border-radius none
> a:hover, > a:focus
text-decoration none
color red
background-color transparent
.disabled
> a, > a:hover, > a:focus, > span
color gray
cursor not-allowed
::-moz-selection
color white
text-shadow none
background brand-primary
::selection
color white
text-shadow none
background brand-primary
img::selection
color white
background transparent
img::-moz-selection
color white
background transparent
body
webkit-tap-highlight-color brand-primary
================================================
FILE: source/css/custom.styl
================================================
// write you own style here
================================================
FILE: source/css/darkmode.styl
================================================
@media (prefers-color-scheme: dark) {
// change color here
:root {
--bg-color: #222831;
--font-color: #94a1b4;
--link-color: #a7dfe4;
--line-color: #161d27;
}
a {
.fa-camera-retro, .fa-search, .fa-puzzle-piece {
color: var(--font-color);
}
&:focus, &:hover {
.fa-camera-retro, .fa-search, .fa-puzzle-piece {
color: var(--link-color);
}
}
}
body {
color: var(--font-color);
background: var(--bg-color);
}
.modal-content {
color: var(--font-color);
background: var(--bg-color);
border-bottom: 1px solid var(--font-color);
box-shadow: none;
.form-control {
color: var(--font-color);
background: var(--bg-color);
caret-color: var(--link-color);
}
.search-result-list {
.search-result-title {
color: var(--link-color);
&:focus, &:hover {
color: var(--link-color);
}
}
.search-result {
color: var(--font-color);
.search-keyword {
color: var(--link-color);
}
}
}
}
.post-heading h1,
.intro-header .site-heading h1 {
color: var(--font-color);
}
a,
p a,
.pagiantion li > a,
#article-toc-inner .toc-link {
color: var(--font-color);
text-decoration: none;
&:focus, &:hover,
&:visited, &:link {
color: var(--link-color);
}
}
.post-tags a {
color: var(--link-color);
&:focus, &:hover {
color: var(--link-color);
}
}
.post-preview a {
color: var(--font-color);
&:focus, &:hover {
.post-title {
color: var(--link-color);
}
}
}
// code block
figure.highlight {
background-color: var(--bg-color);
color: var(--font-color);
border-color: var(--line-color);
text-shadow: var(--bg-color) 0px 0px 1px;
}
figure.highlight table .line {
color: var(--font-color);
}
// code inline
code {
color: var(--font-color);
background-color: #273435;
}
article .container .row blockquote {
color: var(--font-color);
background: var(--line-color);
}
article .container .row img {
opacity: .7;
transition: opacity .5s ease-in-out;
}
article .container .row img:hover {
opacity: 1;
}
}
================================================
FILE: source/css/mixins.styl
================================================
transition-all()
-webkit-transition all 0.5s
-moz-transition all 0.5s
transition all 0.5s
.transition-all
transition-all()
background-cover()
-webkit-background-size cover
-moz-background-size cover
background-size cover
-o-background-size cover
.background-cover
background-cover()
serif()
font-family 'Noto Serif', 'Times New Roman', serif
.serif
serif()
sans-serif()
font-family 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif
.sans-serif
sans-serif()
animation()
animation bodyshow .9s linear
.animation
animation()
@keyframes 'bodyshow' {
0% {
top: -60px;
opacity: 0;
}
33% {
top: -40px;
opacity: .2;
}
66% {
top: -20px;
opacity: .6;
}
100% {
top: 0;
opacity: 1;
}
}
================================================
FILE: source/css/more.styl
================================================
/*
* @author fakeyanss, zchen9
*/
@import "variables.styl"
// gist embed
.blob-num
border none !important
// search icon
a.nav-search
position fixed
bottom 15px
right 15px
color white-faded
cursor pointer
z-index 99
&:hover, &:focus
color red
@media only screen and (max-width: 1024px)
display none
opacity 0
// search result
.modal-dialog
margin 120px auto
@media only screen and (min-width: 1280px)
width 50%
@media only screen and (min-width: 1024px) and (max-width: 1280px)
width 75%
.modal-content
border none
border-radius 0
overflow hidden
box-shadow 2px 2px 22px gray
.modal-body
padding 0
.form-control
border none
outline none
caret-color red
box-shadow none
&:focus
box-shadow none
.search-result-title
display block
font-size 18px
.search-result-list
padding 20px
margin 0 auto
list-style none
font-size 14px
.search-keyword
font-style normal
font-weight 500
color red
.search-result
margin 5px 0 20px
overflow hidden
line-height 1.8
color gray-dark
max-height 7.2em
font-size 16px
// github table style
th
text-align center
border 1px solid #dfe2e5
padding 6px 13px
td
border 1px solid #dfe2e5
padding 6px 13px
// fix conflict between table and code
.gutter
padding 0
padding-right 15px
border none
border-right 1px solid #ddd
.code
padding 0
padding-left 15px
border none
border-left 1px solid #fff
================================================
FILE: source/css/style.styl
================================================
@import "base.styl"
@import "article.styl"
@import "more.styl"
@import "custom.styl"
@import "toc.styl"
@import "darkmode.styl"
================================================
FILE: source/css/toc.styl
================================================
#article-toc-inner:after,#article-toc-inner:before,.inner:after,.inner:before {
content: "";
display: table
}
#article-toc-inner:after,.inner:after {
clear: both
}
#article-toc {
display: block;
position: fixed;
top: 0;
bottom: 0;
right: 0;
width: 16%;
}
@media screen and (max-width:986px) {
#article-toc {
display: none;
}
}
#article-toc-inner {
width: 100%;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
#article-toc-inner .toc {
font-size: 15px;
list-style-type: circle;
padding: 0;
margin: 0;
}
#article-toc-inner .toc-item {
line-height: 2em;
padding: 0;
margin: 0;
}
#article-toc-inner .toc-child {
padding: 0;
margin-left: 1em;
line-height: 2em;
}
#article-toc-inner .toc-child .toc-item {
margin: 0;
padding: 0;
list-style-type: square;
}
#article-toc-inner .toc-link {
color: gray-dark;
font-weight: 700;
&:focus, &:hover {
color: red;
text-decoration: none;
}
}
================================================
FILE: source/css/variables.styl
================================================
brand-primary = lighten(rgba(206, 35, 35, .9), 20%)
gray-dark = lighten(rgba(0, 0, 0, 1), 30%)
gray = lighten(rgba(0, 0, 0, .9), 45%)
white-faded = rgba(0, 0, 0, .5)
gray-light = rgba(235, 235, 235, .8)
color-border = #EEE
color-meta = #CCC
red = #CE2323
font-mono = Monaco, Menlo, Consolas, Courier New, monospace
font-serif = "Georgia", serif
================================================
FILE: source/sw.js
================================================
"use strict";
(function() {
var cacheVersion = "-180503";
var staticCacheName = "asset" + cacheVersion;
var maxEntries = 100;
self.importScripts("https://cdn.jsdelivr.net/npm/sw-toolbox@3.6.0/sw-toolbox.js");
self.toolbox.options.debug = false;
self.toolbox.options.networkTimeoutSeconds = 1;
/* staticImageCache */
self.toolbox.router.get("/(.*)", self.toolbox.cacheFirst, {
cache: {
name: staticCacheName,
maxEntries: maxEntries
}
});
})();
gitextract_d7sopokl/
├── .gitignore
├── LICENSE
├── README.md
├── languages/
│ ├── default.yml
│ ├── en.yml
│ ├── zh-CN.yml
│ ├── zh-Hans.yml
│ └── zh-TW.yml
├── layout/
│ ├── _partial/
│ │ ├── article-archive.ejs
│ │ ├── article-categories.ejs
│ │ ├── article-full.ejs
│ │ ├── article-index.ejs
│ │ ├── article-tags.ejs
│ │ ├── backhome.ejs
│ │ ├── comment.ejs
│ │ ├── google-analytics.ejs
│ │ ├── gosite.ejs
│ │ ├── head.ejs
│ │ ├── img-viewer.ejs
│ │ ├── pagination.ejs
│ │ ├── scripts.ejs
│ │ ├── search.ejs
│ │ ├── service-worker.ejs
│ │ └── toc.ejs
│ ├── archive.ejs
│ ├── index.ejs
│ ├── layout.ejs
│ ├── page.ejs
│ └── post.ejs
└── source/
├── css/
│ ├── article.styl
│ ├── base.styl
│ ├── custom.styl
│ ├── darkmode.styl
│ ├── mixins.styl
│ ├── more.styl
│ ├── style.styl
│ ├── toc.styl
│ └── variables.styl
└── sw.js
Condensed preview — 39 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (41K chars).
[
{
"path": ".gitignore",
"chars": 25,
"preview": "node_modules\n_config.yml\n"
},
{
"path": "LICENSE",
"chars": 1095,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2016 zchen9(zhao.zchen9@gmail.com)\n\nPermission is hereby granted, free of charge, t"
},
{
"path": "README.md",
"chars": 1875,
"preview": "# Hexo-theme-hollow\n\n一款极致简洁的博客主题,可访问 [My Fragment](https://www.chen9.info/fragment/) 查看效果\n\n## 安装\n\n在你的 Hexo 博客仓库下 clone 主"
},
{
"path": "languages/default.yml",
"chars": 63,
"preview": "prev: 上一页\nnext: 下一页\ncomment: 留言\narchive_a: 归档\narchive_b: 归档:%s\n"
},
{
"path": "languages/en.yml",
"chars": 99,
"preview": "prev: Older Posts\nnext: Newer Posts\ncomment: Comments\narchive_a: Archives\narchive_b: \"Archives: %s\""
},
{
"path": "languages/zh-CN.yml",
"chars": 63,
"preview": "prev: 上一页\nnext: 下一页\ncomment: 留言\narchive_a: 归档\narchive_b: 归档:%s\n"
},
{
"path": "languages/zh-Hans.yml",
"chars": 62,
"preview": "prev: 上一页\nnext: 下一页\ncomment: 留言\narchive_a: 归档\narchive_b: 归档:%s"
},
{
"path": "languages/zh-TW.yml",
"chars": 62,
"preview": "prev: 上一頁\nnext: 下一頁\ncomment: 留言\narchive_a: 彙整\narchive_b: 彙整:%s"
},
{
"path": "layout/_partial/article-archive.ejs",
"chars": 228,
"preview": "<div class=\"post-preview archive\">\n <a href=\"<%- config.root %><%- item.path %>\">\n <h1 class=\"post-title archi"
},
{
"path": "layout/_partial/article-categories.ejs",
"chars": 217,
"preview": "<%\n var categories = [];\n item.categories.forEach(function(category){\n categories.push('<a href=\"' + config"
},
{
"path": "layout/_partial/article-full.ejs",
"chars": 2418,
"preview": "<section class=\"article-container\">\n <!-- Back Home -->\n <%- partial('_partial/backhome') %>\n\n <!-- Page He"
},
{
"path": "layout/_partial/article-index.ejs",
"chars": 238,
"preview": "<div class=\"post-preview\">\n <a href=\"<%- config.root %><%- item.path %>\">\n <h2 class=\"post-title\">\n "
},
{
"path": "layout/_partial/article-tags.ejs",
"chars": 179,
"preview": "<%\n var tags = [];\n item.tags.forEach(function(tag){\n tags.push('<a href=\"' + config.root + tag.path + '\">#"
},
{
"path": "layout/_partial/backhome.ejs",
"chars": 90,
"preview": "<a class=\"nav-back\" href=\"<%- config.root %>\">\n <i class=\"fa fa-puzzle-piece\"></i>\n</a>"
},
{
"path": "layout/_partial/comment.ejs",
"chars": 804,
"preview": "<!-- Disqus Comments -->\n<% if (theme.comments && theme.comments.disqus_shortname){ %>\n <div id=\"disqus_thread\" class=\""
},
{
"path": "layout/_partial/google-analytics.ejs",
"chars": 532,
"preview": "<% if (theme.google_analytics){ %>\n <script>\n (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]|"
},
{
"path": "layout/_partial/gosite.ejs",
"chars": 164,
"preview": "<% if (config.baseurl || theme.baseurl) { %>\n<a class=\"nav-back\" href=\"<%- config.baseurl || theme.baseurl %>\">\n <i c"
},
{
"path": "layout/_partial/head.ejs",
"chars": 2620,
"preview": "<head>\n <meta charset=\"utf-8\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n <meta name=\"viewport\" co"
},
{
"path": "layout/_partial/img-viewer.ejs",
"chars": 789,
"preview": "<% if (theme.image_viewer){ %>\n <!-- Custom picture view-->\n <link href=\"<%= config.root %>css/viewer.min.css\" rel"
},
{
"path": "layout/_partial/pagination.ejs",
"chars": 311,
"preview": "<ul class=\"pagiantion\">\n <% if (page.prev){ %>\n <li class=\"previous\"><a href=\"<%- config.root %><%- page.prev_"
},
{
"path": "layout/_partial/scripts.ejs",
"chars": 108,
"preview": "<script type=\"text/javascript\">\n console.log(\"© zchen9 🙋 2015-\" + new Date().getFullYear());\n</script>\n "
},
{
"path": "layout/_partial/search.ejs",
"chars": 5152,
"preview": "<% if (theme.local_search){ %>\n <a class=\"nav-search\" data-toggle=\"modal\" data-target=\"#searchModalCenter\">\n <i "
},
{
"path": "layout/_partial/service-worker.ejs",
"chars": 536,
"preview": "<!-- if using service worker -->\n<% if (theme.service_worker){ %>\n <script text=\"module\">\n if (\"serviceWorker\" i"
},
{
"path": "layout/_partial/toc.ejs",
"chars": 221,
"preview": "<% if (theme.toc.enable){ %>\n <aside id=\"article-toc\" role=\"navigation\" class=\"fixed\">\n <div id=\"article-toc-i"
},
{
"path": "layout/archive.ejs",
"chars": 1093,
"preview": "<%\n var title = '';\n if (page.category) title = page.category;\n if (page.tag) title = \"#\" + page.tag;\n if (p"
},
{
"path": "layout/index.ejs",
"chars": 580,
"preview": "<!-- Go Site -->\n<%- partial('_partial/gosite') %>\n\n<!-- Main Content -->\n<section class=\"intro\">\n <div class=\"contai"
},
{
"path": "layout/layout.ejs",
"chars": 363,
"preview": "<!DOCTYPE html>\n<html lang=\"zh-Hans\">\n\n<!-- Head tag -->\n<%- partial('_partial/head') %>\n\n<body>\n\n <!-- Content -->\n "
},
{
"path": "layout/page.ejs",
"chars": 53,
"preview": "<%- partial('_partial/article-full', {item: page}) %>"
},
{
"path": "layout/post.ejs",
"chars": 53,
"preview": "<%- partial('_partial/article-full', {item: page}) %>"
},
{
"path": "source/css/article.styl",
"chars": 3178,
"preview": "@import \"mixins.styl\"\n@import \"variables.styl\"\n\n.article-container\n @extend .animation\n\narticle\n .container\n .row\n "
},
{
"path": "source/css/base.styl",
"chars": 5657,
"preview": "@import \"variables.styl\"\n@import \"mixins.styl\"\n\nbody,\nhtml\n width 100%\n font-size 18px\n color gray-dark\n @extend .se"
},
{
"path": "source/css/custom.styl",
"chars": 27,
"preview": "// write you own style here"
},
{
"path": "source/css/darkmode.styl",
"chars": 2673,
"preview": "@media (prefers-color-scheme: dark) {\n // change color here\n :root {\n --bg-color: #222831;\n --font-c"
},
{
"path": "source/css/mixins.styl",
"chars": 780,
"preview": "transition-all()\n -webkit-transition all 0.5s\n -moz-transition all 0.5s\n transition all 0.5s\n\n.transition-all\n trans"
},
{
"path": "source/css/more.styl",
"chars": 1465,
"preview": "/*\n * @author fakeyanss, zchen9\n */\n\n@import \"variables.styl\"\n\n// gist embed\n.blob-num \n border none !important\n\n// sea"
},
{
"path": "source/css/style.styl",
"chars": 128,
"preview": "\n@import \"base.styl\"\n@import \"article.styl\"\n@import \"more.styl\"\n@import \"custom.styl\"\n@import \"toc.styl\"\n@import \"darkmo"
},
{
"path": "source/css/toc.styl",
"chars": 1049,
"preview": "#article-toc-inner:after,#article-toc-inner:before,.inner:after,.inner:before {\n content: \"\";\n display: table\n}\n\n#"
},
{
"path": "source/css/variables.styl",
"chars": 346,
"preview": "brand-primary = lighten(rgba(206, 35, 35, .9), 20%)\ngray-dark = lighten(rgba(0, 0, 0, 1), 30%)\ngray = lighten(rgba(0, 0,"
},
{
"path": "source/sw.js",
"chars": 483,
"preview": "\"use strict\";\n(function() {\n var cacheVersion = \"-180503\";\n var staticCacheName = \"asset\" + cacheVersion;\n var maxEnt"
}
]
About this extraction
This page contains the full source code of the zchen9/hexo-theme-hollow GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 39 files (35.0 KB), approximately 10.7k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.