├── layout ├── includes │ ├── page │ │ ├── default-page.pug │ │ ├── categories.pug │ │ ├── notice.pug │ │ ├── tags.pug │ │ ├── stars.pug │ │ └── 404.pug │ ├── widget │ │ ├── card_ad.pug │ │ ├── card_announcement.pug │ │ ├── card_top_self.pug │ │ ├── card_categories.pug │ │ ├── card_bottom_self.pug │ │ ├── card_newest_comment.pug │ │ ├── card_clock.pug │ │ ├── card_weibo.pug │ │ ├── card_archives.pug │ │ ├── card_history.pug │ │ ├── card_post_toc.pug │ │ ├── card_tags.pug │ │ ├── card_post_series.pug │ │ ├── card_recent_post.pug │ │ └── card_author.pug │ ├── head │ │ ├── site_verification.pug │ │ ├── google_adsense.pug │ │ ├── pwa.pug │ │ ├── Open_Graph.pug │ │ ├── config_site.pug │ │ └── preconnect.pug │ ├── third-party │ │ ├── chat │ │ │ ├── index.pug │ │ │ ├── crisp.pug │ │ │ ├── chatra.pug │ │ │ └── tidio.pug │ │ ├── abcjs │ │ │ ├── index.pug │ │ │ └── abcjs.pug │ │ ├── search │ │ │ ├── index.pug │ │ │ ├── algolia.pug │ │ │ ├── local-search.pug │ │ │ └── docsearch.pug │ │ ├── share │ │ │ ├── index.pug │ │ │ ├── share-js.pug │ │ │ └── addtoany.pug │ │ ├── math │ │ │ ├── index.pug │ │ │ ├── katex.pug │ │ │ ├── mathjax.pug │ │ │ └── mermaid.pug │ │ ├── card-post-count │ │ │ ├── index.pug │ │ │ ├── remark42.pug │ │ │ ├── valine.pug │ │ │ ├── fb.pug │ │ │ ├── waline.pug │ │ │ ├── artalk.pug │ │ │ ├── disqus.pug │ │ │ └── twikoo.pug │ │ ├── pangu.pug │ │ ├── prismjs.pug │ │ ├── comments │ │ │ ├── livere.pug │ │ │ ├── js.pug │ │ │ ├── valine.pug │ │ │ ├── gitalk.pug │ │ │ ├── index.pug │ │ │ ├── utterances.pug │ │ │ ├── giscus.pug │ │ │ ├── artalk.pug │ │ │ ├── disqus.pug │ │ │ ├── facebook_comments.pug │ │ │ ├── remark42.pug │ │ │ └── disqusjs.pug │ │ ├── aplayer.pug │ │ ├── newest-comments │ │ │ ├── index.pug │ │ │ ├── remark42.pug │ │ │ ├── waline.pug │ │ │ ├── disqus-comment.pug │ │ │ ├── twikoo-comment.pug │ │ │ ├── valine.pug │ │ │ └── github-issues.pug │ │ ├── effect.pug │ │ └── pjax.pug │ ├── loading │ │ ├── index.pug │ │ ├── pace.pug │ │ ├── fullpage-loading.pug │ │ └── spinner-loading.pug │ ├── header │ │ ├── social.pug │ │ ├── menu_item.pug │ │ └── nav.pug │ ├── post │ │ ├── reward.pug │ │ └── post-copyright.pug │ ├── sidebar.pug │ ├── swiper-notice.pug │ ├── layout.pug │ ├── pagination.pug │ └── additional-js.pug ├── index.pug ├── archive.pug ├── category.pug ├── tag.pug ├── post.pug └── page.pug ├── source ├── img │ ├── 404.jpg │ ├── favicon.ico │ ├── error-page.png │ ├── friend_404.gif │ └── butterfly-icon.png ├── css │ ├── _tags │ │ ├── series.styl │ │ ├── inlineImg.styl │ │ ├── plugins │ │ │ ├── ghcard.styl │ │ │ ├── image.styl │ │ │ ├── notation.styl │ │ │ ├── poem.styl │ │ │ ├── inline-labels.styl │ │ │ ├── bubble.styl │ │ │ ├── media.styl │ │ │ ├── progress.styl │ │ │ ├── span.styl │ │ │ ├── link.styl │ │ │ └── site-card.styl │ │ ├── label.styl │ │ ├── hexo.styl │ │ ├── hide.styl │ │ ├── button.styl │ │ ├── tabs.styl │ │ └── timeline.styl │ ├── _layout │ │ ├── chat.styl │ │ ├── relatedposts.styl │ │ ├── footer.styl │ │ ├── rightside.styl │ │ ├── reward.styl │ │ ├── rightmenu.styl │ │ ├── sidebar.styl │ │ ├── comments.styl │ │ └── pagination.styl │ ├── index.styl │ ├── _highlight │ │ ├── prismjs │ │ │ ├── index.styl │ │ │ └── line-number.styl │ │ └── highlight │ │ │ ├── index.styl │ │ │ └── diff.styl │ ├── _page │ │ ├── tags.styl │ │ ├── categories.styl │ │ ├── shuoshuo.styl │ │ ├── common.styl │ │ └── 404.styl │ └── _search │ │ ├── index.styl │ │ ├── local-search.styl │ │ └── algolia.styl └── js │ └── eurkon │ ├── rgbaster.min.js │ └── refresh.js ├── scripts ├── tag │ ├── plugins │ │ ├── notation.js │ │ ├── iconfont.js │ │ ├── span.js │ │ ├── tip.js │ │ ├── poem.js │ │ ├── progress.js │ │ ├── bubble.js │ │ ├── inline-labels.js │ │ ├── carousel.js │ │ ├── ghbdage.js │ │ ├── media.js │ │ ├── btns.js │ │ ├── reference.js │ │ ├── folding.js │ │ ├── link.js │ │ ├── issues.js │ │ ├── ghcard.js │ │ ├── checkbox.js │ │ └── site.js │ ├── label.js │ ├── mermaid.js │ ├── score.js │ ├── inlineImg.js │ ├── button.js │ ├── note.js │ ├── flink.js │ ├── timeline.js │ ├── chartjs.js │ ├── gallery.js │ ├── series.js │ ├── tabs.js │ └── hide.js ├── events │ ├── 404.js │ ├── comment.js │ ├── init.js │ ├── welcome.js │ └── stylus.js ├── helpers │ ├── catalog_list.js │ ├── stars.js │ ├── year.js │ ├── series.js │ ├── random.js │ └── getArchiveLength.js ├── filters │ ├── post_lazyload.js │ └── random_cover.js └── common │ └── postDesc.js ├── .github ├── ISSUE_TEMPLATE │ ├── feature_request.yml │ ├── config.yml │ └── bug_report.yml ├── workflows │ ├── publish.yml │ └── stale.yml └── FUNDING.yml └── package.json /layout/includes/page/default-page.pug: -------------------------------------------------------------------------------- 1 | #article-container 2 | != page.content -------------------------------------------------------------------------------- /source/img/404.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Eurkon/hexo-theme-butterfly-eurkon/HEAD/source/img/404.jpg -------------------------------------------------------------------------------- /source/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Eurkon/hexo-theme-butterfly-eurkon/HEAD/source/img/favicon.ico -------------------------------------------------------------------------------- /layout/includes/widget/card_ad.pug: -------------------------------------------------------------------------------- 1 | if theme.ad && theme.ad.aside 2 | .card-widget.ads-wrap 3 | != theme.ad.aside 4 | -------------------------------------------------------------------------------- /source/img/error-page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Eurkon/hexo-theme-butterfly-eurkon/HEAD/source/img/error-page.png -------------------------------------------------------------------------------- /source/img/friend_404.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Eurkon/hexo-theme-butterfly-eurkon/HEAD/source/img/friend_404.gif -------------------------------------------------------------------------------- /source/img/butterfly-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Eurkon/hexo-theme-butterfly-eurkon/HEAD/source/img/butterfly-icon.png -------------------------------------------------------------------------------- /layout/index.pug: -------------------------------------------------------------------------------- 1 | extends includes/layout.pug 2 | 3 | block content 4 | include ./includes/mixins/indexPostUI.pug 5 | +indexPostUI -------------------------------------------------------------------------------- /source/css/_tags/series.styl: -------------------------------------------------------------------------------- 1 | #article-container 2 | .series-items 3 | a 4 | &:hover 5 | color: var(--pseudo-hover) -------------------------------------------------------------------------------- /layout/includes/head/site_verification.pug: -------------------------------------------------------------------------------- 1 | if theme.site_verification 2 | each item in theme.site_verification 3 | meta(name=item.name content=item.content) -------------------------------------------------------------------------------- /source/css/_tags/inlineImg.styl: -------------------------------------------------------------------------------- 1 | #article-container 2 | .inline-img 3 | display: inline 4 | margin: 0 3px 5 | height: 1.1em 6 | vertical-align: text-bottom -------------------------------------------------------------------------------- /layout/includes/third-party/chat/index.pug: -------------------------------------------------------------------------------- 1 | case theme.chat.use 2 | when 'chatra' 3 | include ./chatra.pug 4 | when 'tidio' 5 | include ./tidio.pug 6 | when 'crisp' 7 | include ./crisp.pug -------------------------------------------------------------------------------- /layout/includes/third-party/abcjs/index.pug: -------------------------------------------------------------------------------- 1 | if theme.abcjs.enable 2 | if theme.abcjs.per_page 3 | if is_post() || is_page() 4 | include ./abcjs.pug 5 | else if page.abcjs 6 | include ./abcjs.pug 7 | -------------------------------------------------------------------------------- /layout/includes/third-party/search/index.pug: -------------------------------------------------------------------------------- 1 | case theme.search.use 2 | when 'algolia_search' 3 | include ./algolia.pug 4 | when 'local_search' 5 | include ./local-search.pug 6 | when 'docsearch' 7 | include ./docsearch.pug -------------------------------------------------------------------------------- /layout/includes/loading/index.pug: -------------------------------------------------------------------------------- 1 | if theme.preloader.enable 2 | if theme.preloader.source === 1 3 | include ./fullpage-loading.pug 4 | if theme.preloader.source === 3 5 | include ./spinner-loading.pug 6 | else 7 | include ./pace.pug -------------------------------------------------------------------------------- /source/css/_tags/plugins/ghcard.styl: -------------------------------------------------------------------------------- 1 | a.ghcard 2 | display: inline-block 3 | line-height: 0 4 | 5 | .md .ghcard-group 6 | column-count: 2 7 | column-gap: 0 8 | margin: 0 0 - 16px * 0.5 9 | .ghcard 10 | margin: 16px * 0.5 11 | -------------------------------------------------------------------------------- /layout/includes/page/categories.pug: -------------------------------------------------------------------------------- 1 | .category-lists!= list_categories() 2 | 3 | //-
4 | //- #categories-chart(data-parent="true" style="height: 300px; padding: 10px;") -------------------------------------------------------------------------------- /source/css/_tags/plugins/image.styl: -------------------------------------------------------------------------------- 1 | .md .img 2 | object-fit: contain 3 | 4 | img.inline 5 | display: inline !important 6 | vertical-align: middle 7 | transform: translateY(-4px) 8 | p .img-alt 9 | display: inline-block 10 | width: 100% 11 | -------------------------------------------------------------------------------- /layout/includes/third-party/share/index.pug: -------------------------------------------------------------------------------- 1 | - const { use } = theme.share 2 | 3 | if use 4 | .post-share 5 | case use 6 | when 'addtoany' 7 | !=partial('includes/third-party/share/addtoany', {}, {cache: true}) 8 | when 'sharejs' 9 | include ./share-js.pug -------------------------------------------------------------------------------- /layout/includes/widget/card_announcement.pug: -------------------------------------------------------------------------------- 1 | if theme.aside.card_announcement.enable 2 | .card-widget.card-announcement 3 | .item-headline 4 | i.fas.fa-bullhorn.fa-shake 5 | span= _p('aside.card_announcement') 6 | .announcement_content!= theme.aside.card_announcement.content -------------------------------------------------------------------------------- /source/css/_tags/label.styl: -------------------------------------------------------------------------------- 1 | .hl-label 2 | padding: 2px 4px 3 | color: $btn-color 4 | addBorderRadius(3) 5 | 6 | &.default 7 | background-color: $btn-default-color 8 | 9 | for $type in $color-types 10 | &.{$type} 11 | background-color: lookup('$tagsP-' + $type + '-color') 12 | -------------------------------------------------------------------------------- /layout/includes/widget/card_top_self.pug: -------------------------------------------------------------------------------- 1 | if site.data.widget && site.data.widget.top 2 | each item in site.data.widget.top 3 | .card-widget(class=item.class_name id=item.id_name) 4 | .item-headline 5 | i(class=item.icon) 6 | span=item.name 7 | .item-content 8 | !=item.html -------------------------------------------------------------------------------- /layout/includes/widget/card_categories.pug: -------------------------------------------------------------------------------- 1 | if theme.aside.card_categories.enable 2 | if site.categories.length 3 | .card-widget.card-categories 4 | !=aside_categories({ limit: theme.aside.card_categories.limit === 0 ? 0 : theme.aside.card_categories.limit || 8 , expand: theme.aside.card_categories.expand }) 5 | -------------------------------------------------------------------------------- /source/css/_layout/chat.styl: -------------------------------------------------------------------------------- 1 | // chat 2 | if hexo-config('chat.rightside_button') == true 3 | if hexo-config('chat.use') == 'chatra' 4 | #chatra:not(.chatra--expanded) 5 | visibility: hidden !important 6 | width: 1px !important 7 | height: 1px !important 8 | opacity: 0 !important 9 | pointer-events: none -------------------------------------------------------------------------------- /scripts/tag/plugins/notation.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function Nota(args) { 4 | args = args.join(' ').split(',') 5 | let p0 = args[0].trim() 6 | let p1 = args[1].trim() 7 | return `${p0}`; 8 | } 9 | 10 | hexo.extend.tag.register('nota', Nota); 11 | // {% nota 注释词汇 ,'注释内容,使用逗号间隔开了即可' %} 12 | -------------------------------------------------------------------------------- /scripts/tag/label.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Butterfly 3 | * label 4 | * {% label text color %} 5 | */ 6 | 7 | 'use strict' 8 | 9 | const addLabel = args => { 10 | const [text, className = 'default'] = args 11 | return `${text}` 12 | } 13 | 14 | hexo.extend.tag.register('label', addLabel, { ends: false }) 15 | -------------------------------------------------------------------------------- /layout/includes/third-party/share/share-js.pug: -------------------------------------------------------------------------------- 1 | - const coverVal = page.cover_type === 'img' ? page.cover : theme.avatar.img 2 | .social-share(data-image=url_for(coverVal) data-sites= theme.share.sharejs.sites) 3 | link(rel='stylesheet' href=url_for(theme.asset.sharejs_css) media="print" onload="this.media='all'") 4 | script(src=url_for(theme.asset.sharejs) defer) -------------------------------------------------------------------------------- /layout/includes/loading/pace.pug: -------------------------------------------------------------------------------- 1 | script. 2 | window.paceOptions = { 3 | restartOnPushState: false 4 | } 5 | 6 | btf.addGlobalFn('pjaxSend', () => { 7 | Pace.restart() 8 | }, 'pace_restart') 9 | 10 | 11 | link(rel="stylesheet", href=url_for(theme.preloader.pace_css_url || theme.asset.pace_default_css)) 12 | script(src=url_for(theme.asset.pace_js)) -------------------------------------------------------------------------------- /scripts/tag/plugins/iconfont.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function iconFont(args) { 4 | args = args.join(' ').split(',') 5 | let p0 = args[0] 6 | let p1 = args[1]?args[1]:1 7 | return ``; 8 | } 9 | 10 | hexo.extend.tag.register('icon',iconFont); 11 | -------------------------------------------------------------------------------- /layout/includes/page/notice.pug: -------------------------------------------------------------------------------- 1 | #article-container 2 | h1= _p('aside.card_announcement') 3 | .timeline.notice 4 | if site.data.notice 5 | each i in site.data.notice 6 | .timeline-item 7 | .timeline-item-title 8 | .item-circle 9 | p!=i.date 10 | .timeline-item-content 11 | p!=i.msg -------------------------------------------------------------------------------- /layout/includes/page/tags.pug: -------------------------------------------------------------------------------- 1 | .tag-cloud-list.text-center 2 | !=cloudTags({source: site.tags, orderby: page.orderby || 'random', order: page.order || 1, minfontsize: 1.2, maxfontsize: 1.5, limit: 0, unit: 'em'}) 3 | 4 | //- 5 | //- #tags-chart(data-length="10" style="height: 300px; padding: 10px;") -------------------------------------------------------------------------------- /layout/includes/third-party/share/addtoany.pug: -------------------------------------------------------------------------------- 1 | .addtoany 2 | .a2a_kit.a2a_kit_size_32.a2a_default_style 3 | - let addtoanyItem = theme.addtoany.item.split(',') 4 | each name in addtoanyItem 5 | a(class="a2a_button_" + name) 6 | 7 | a.a2a_dd(href="https://www.addtoany.com/share") 8 | script(async src='https://static.addtoany.com/menu/page.js') 9 | 10 | 11 | -------------------------------------------------------------------------------- /layout/includes/widget/card_bottom_self.pug: -------------------------------------------------------------------------------- 1 | if site.data.widget && site.data.widget.bottom 2 | each item in site.data.widget.bottom 3 | .card-widget(class=item.class_name id=item.id_name style=item.order ? `order: ${item.order}` : '') 4 | .item-headline 5 | i(class=item.icon) 6 | span=item.name 7 | .item-content 8 | !=item.html 9 | 10 | -------------------------------------------------------------------------------- /layout/includes/header/social.pug: -------------------------------------------------------------------------------- 1 | each url, icon in theme.social 2 | - 3 | const [link, title, color] = url.split('||').map(i => trim(i)) 4 | const href = url_for(link) 5 | const iconStyle = color ? `color: ${color.replace(/[\'\"]/g, '')};` : '' 6 | const iconTitle = title || '' 7 | a.social-icon(href=href target="_blank" title=iconTitle) 8 | i(class=icon style=iconStyle) -------------------------------------------------------------------------------- /layout/includes/head/google_adsense.pug: -------------------------------------------------------------------------------- 1 | if (theme.google_adsense && theme.google_adsense.enable) 2 | script(async src=theme.google_adsense.js) 3 | 4 | if theme.google_adsense.auto_ads 5 | script. 6 | (adsbygoogle = window.adsbygoogle || []).push({ 7 | google_ad_client: '!{theme.google_adsense.client}', 8 | enable_page_level_ads: '!{theme.google_adsense.enable_page_level_ads}' 9 | }); -------------------------------------------------------------------------------- /layout/includes/widget/card_newest_comment.pug: -------------------------------------------------------------------------------- 1 | if theme.aside.card_newest_comments.enable && theme.comments.use && !['Livere','Facebook Comments','Giscus'].includes(theme.comments.use[0]) 2 | .card-widget#card-newest-comments 3 | .item-headline 4 | i.fas.fa-comment-dots 5 | span= _p('aside.card_newest_comments.headline') 6 | .aside-list 7 | span= _p('aside.card_newest_comments.loading_text') 8 | -------------------------------------------------------------------------------- /scripts/events/404.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Butterfly 3 | * 404 error page 4 | */ 5 | 6 | 'use strict' 7 | 8 | hexo.extend.generator.register('404', function (locals) { 9 | if (!hexo.theme.config.error_404.enable) return 10 | return { 11 | path: '404.html', 12 | layout: ['page'], 13 | data: { 14 | type: '404', 15 | top_img: false, 16 | comments: false, 17 | aside: false 18 | } 19 | } 20 | }) 21 | -------------------------------------------------------------------------------- /scripts/tag/mermaid.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Butterfly 3 | * mermaid 4 | * https://github.com/mermaid-js/mermaid 5 | */ 6 | 7 | 'use strict' 8 | 9 | const { escapeHTML } = require('hexo-util') 10 | 11 | const mermaid = (args, content) => { 12 | return `
13 | ${escapeHTML(content)}
14 | ${p1}
`; 8 | } 9 | function postSpan(args) { 10 | args = args.join(' ').split(',') 11 | let p0 = args[0].trim() 12 | let p1 = args[1].trim() 13 | return `${p1}`; 14 | } 15 | 16 | hexo.extend.tag.register('p', postP); 17 | hexo.extend.tag.register('span', postSpan); 18 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: npm publish 2 | 3 | on: 4 | release: 5 | types: [created] 6 | jobs: 7 | build: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v2 11 | # Setup .npmrc file to publish to npm 12 | - uses: actions/setup-node@v1 13 | with: 14 | node-version: '12.x' 15 | registry-url: 'https://registry.npmjs.org' 16 | - run: npm install 17 | - run: npm publish 18 | env: 19 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} -------------------------------------------------------------------------------- /layout/archive.pug: -------------------------------------------------------------------------------- 1 | extends includes/layout.pug 2 | 3 | block content 4 | div 5 | include ./includes/mixins/article-sort.pug 6 | #archive 7 | //- 二选一 8 | //- 9 | //- #posts-chart(data-start="2021-01" style="height: 300px; padding: 10px;") 10 | .article-sort-title= `${_p('page.articles')} - ${getArchiveLength()}` 11 | +articleSort(page.posts, page.current) 12 | include includes/pagination.pug -------------------------------------------------------------------------------- /scripts/events/comment.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Capitalize the first letter of comment name 3 | */ 4 | 5 | hexo.extend.filter.register('before_generate', () => { 6 | const themeConfig = hexo.theme.config 7 | let { use } = themeConfig.comments 8 | if (!use) return 9 | 10 | // 確保 use 是一個陣列 11 | use = Array.isArray(use) ? use : use.split(',') 12 | 13 | // 將每個項目轉換為小寫並將首字母大寫 14 | themeConfig.comments.use = use.map(item => 15 | item.trim().toLowerCase().replace(/\b[a-z]/g, s => s.toUpperCase()) 16 | ) 17 | }) 18 | -------------------------------------------------------------------------------- /scripts/helpers/year.js: -------------------------------------------------------------------------------- 1 | hexo.extend.helper.register('getAnimalIcon', function (year) { 2 | var index = parseInt(year) % 12; 3 | var icon = { 4 | 0: 'icon-monkey', 5 | 1: 'icon-rooster', 6 | 2: 'icon-dog', 7 | 3: 'icon-boar', 8 | 4: 'icon-rat', 9 | 5: 'icon-ox', 10 | 6: 'icon-tiger', 11 | 7: 'icon-rabbit', 12 | 8: 'icon-dragon', 13 | 9: 'icon-snake', 14 | 10: 'icon-horse', 15 | 11: 'icon-goat', 16 | } 17 | return icon[index] 18 | }); -------------------------------------------------------------------------------- /scripts/tag/plugins/tip.js: -------------------------------------------------------------------------------- 1 | // 'use strict' 2 | // 3 | // function poem (args, content) { 4 | // return `)+|(\s|<\/p>)+$/g, '')}
${carouselname}
${escapeHTML(chartConfig)}
45 | ${descDOM}
46 | ${descr}
57 | 58 |${args}
${content}