diff --git a/README.md b/README.md index d49137d..604e697 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,7 @@ Appleシリコン版Macや、Intel版Macの場で動作確認しています。 ```ts export default { + size: "JIS-B5", // B5判と"105mm 173mm"(新書)サイズのみ対応 title: "(本のタイトル)", author: "(著者名)", publisher: "(サークル名)", @@ -120,6 +121,13 @@ brタグで改行ができます。`, image: "../images/(プロファイル画像を置いて指定する).png", }, ], + cover: { + // TODO: 表紙画像が必要な場合は置いて指定してください + // front: "front-cover.png", + // back: "back-cover.png", + // start: "start-cover.png", + // end: "end-cover.png", + }, copyright: "(コピーライトを書く)", }; ``` diff --git a/docs/99-1_samples.md b/docs/99-1_samples.md index b7e6fc2..a2a96c5 100644 --- a/docs/99-1_samples.md +++ b/docs/99-1_samples.md @@ -1,6 +1,6 @@ --- description: - 利用できるのマークダウンの構文とカスタム構文のサンプル集です。 + 利用できるマークダウンの構文とカスタム構文のサンプル集です。 追加のプラグインやHandlebar.jsで拡張した構文もふくめて、全ての構文を確認するためのサンプルになります。 color: primary: diff --git a/docs/_finally.md b/docs/_finally.md index f290bd3..178d296 100644 --- a/docs/_finally.md +++ b/docs/_finally.md @@ -3,3 +3,5 @@ columns: true --- # さいごに + +TODO: 作成する本の最後に記述する内容を記述します。作成する本に合わせて内容を変更してください。 diff --git a/docs/_introduction.md b/docs/_introduction.md index 3394767..a7df83e 100644 --- a/docs/_introduction.md +++ b/docs/_introduction.md @@ -3,3 +3,27 @@ columns: true --- # はじめに + +TODO: 作成する本のイントロダクションを記述します。作成する本に合わせて内容を変更してください。 + +お手にとっていただきありがとうございます。 + +
+サークル名 編 著/20yy-mm-dd 発行 v1.0.0 +
+ +## この本の内容について + +## お問い合わせ先 + +X(旧Twitter): [@xxx](https://twitter.com/xxx){{footnote 'https://twitter.com/xxx'}} + + + +## 本書のフォントについて + +「Mgen+」を使用しています。 + +Licensed under SIL Open Font License 1.1 (http://scripts.sil.org/OFL) +© 2015 自家製フォント工房、© 2014, 2015 Adobe Systems Incorporated、© 2015 M+ FONTS PROJECT +(http://jikasei.me/font/mgenplus/) diff --git a/src/chapter-template.html b/src/chapter-template.html index e930421..eb06d75 100644 --- a/src/chapter-template.html +++ b/src/chapter-template.html @@ -63,7 +63,7 @@
-
+
@@ -83,7 +83,7 @@

{{split data.matter.description 1 " " 2}}

-
+
{{{body}}} diff --git a/src/cli.ts b/src/cli.ts index 4b1b12d..98bfd2d 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,6 +1,9 @@ import { Command } from 'commander'; import concurrently from 'concurrently'; +import config from "../techbook.config"; + const program = new Command(); +const cssSrcFileName = config.size === "JIS-B5" ? "global.css" : config.size === "105mm 173mm" ? "global-105x173.css" : "global.css"; program .name('techbook-cli') @@ -17,7 +20,7 @@ program.command('dev') { command: "npx --yes vite-node src/main.ts", name: "init" }, { command: "npx --yes chokidar-cli \"src/**/*.ts\" \"src/**/*.html\" \"docs/**/*.md\" -c \"npx --yes vite-node src/main.ts\"", name: "main" }, { command: `npx --yes listhen --host 0.0.0.0 --port ${h3Port} --watch ./src/viewer.ts`, name: "h3" }, - { command: "npx --yes wait-on --interval 500 ./dist/lockfile && npx --yes tailwindcss@latest -i ./src/global.css -o ./dist/global.css --watch --no-autoprefixer --postcss ./postcss.config.cjs", name: "tailwind" }, + { command: `npx --yes wait-on --interval 500 ./dist/lockfile && npx --yes tailwindcss@latest -i ./src/${cssSrcFileName} -o ./dist/global.css --watch --no-autoprefixer --postcss ./postcss.config.cjs`, name: "tailwind" }, { command: `npx --yes wait-on --interval 500 ./dist/global.css ./dist/lockfile && npx --yes browser-sync start --no-ui --port ${syncPort} --config 'bs-config.js' --files="dist/lockfile,dist/global.css,images/*" --reload-delay=4000 --reload-throttle=4000 --startPath="/index.html#src=/dist/publication.json&bookMode=true&renderAllPages=true&style=/dist/global.css" --browser "google chrome"`, name: "browser-sync" }, // { command: `npx --yes wait-on --interval 500 ./dist/global.css ./dist/lockfile && npx --yes browser-sync start --no-ui --port ${syncPort} --config 'bs-config.js' --files="dist/*" --reload-delay=4000 --reload-throttle=4000 --startPath="/index.html#src=/dist/publication.json&bookMode=true&renderAllPages=true&style=/dist/global.css" --browser "google chrome"`, name: "browser-sync" }, ], @@ -36,7 +39,7 @@ program.command('build') const { result } = concurrently( [ { command: "npx --yes vite-node src/main.ts", name: "main" }, - { command: "npx --yes tailwindcss@latest -i ./src/global.css -o ./dist/global.css --no-autoprefixer --postcss ./postcss.config.cjs", name: "tailwind" }, + { command: `npx --yes tailwindcss@latest -i ./src/${cssSrcFileName} -o ./dist/global.css --no-autoprefixer --postcss ./postcss.config.cjs`, name: "tailwind" }, { command: "npx --yes @vivliostyle/cli build --style ./dist/global.css", name: "vivliostyle" }, ], { diff --git a/src/constants.ts b/src/constants.ts index 706c94c..9a3106f 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -41,6 +41,7 @@ export const lockFileSrcPath = "src/lockfile"; export const lockFileDistPath = "dist/lockfile"; export const chapterTemplateHtmlPath = "src/chapter-template.html"; +export const simpleChapterTemplateHtmlPath = "src/simplechapter-template.html"; export const appendixTitle = "Appendix"; export const appendixDistPath = "dist/appendix.dist.html"; @@ -59,6 +60,7 @@ export const finallyDocPath = "docs/_finally.md"; export const introductionDistPath = "dist/_introduction.dist.html"; export const finallyDistPath = "dist/_finally.dist.html"; export const introductionTemplateHtmlPath = "src/introduction-template.html"; +export const simpleIntroductionTemplateHtmlPath = "src/simpleintroduction-template.html"; export const tocDistPath = "dist/toc.dist.html"; @@ -67,12 +69,6 @@ export const frontCoverDistPath = "dist/front-cover.dist.html"; export const backCoverDistPath = "dist/back-cover.dist.html"; export const startCoverDistPath = "dist/start-cover.dist.html"; export const endCoverDistPath = "dist/end-cover.dist.html"; -export const coverDistPaths = [ - { path: frontCoverDistPath, image: "front-cover.png" }, - { path: backCoverDistPath, image: "back-cover.png" }, - { path: startCoverDistPath, image: "start-cover.png" }, - { path: endCoverDistPath, image: "end-cover.png" }, -]; // unifiedのプロセッサを作成する export const processorRehype = unified() diff --git a/src/cover-template.html b/src/cover-template.html index bd77903..79a5691 100644 --- a/src/cover-template.html +++ b/src/cover-template.html @@ -9,6 +9,32 @@ + {{#if coverImage}}
+ {{/if}} + {{#unless coverImage}} + {{#switch kind}} + {{#case "start"}} +
+
{{title}}
+
{{publisher}} 編 著
+
{{lastEdition.datetimeView}} {{lastEdition.version}} {{lastEdition.name}}
+
+ {{/case}} + {{#case "front"}} +
+
{{title}}
+
+ {{/case}} + {{#case "back"}} +
+
{{publisher}}
+
{{author}}
+
+ {{/case}} + {{#default}} + {{/default}} + {{/switch}} + {{/unless}} diff --git a/src/cover.ts b/src/cover.ts index 0e61e42..7102f3d 100644 --- a/src/cover.ts +++ b/src/cover.ts @@ -1,10 +1,14 @@ import fs from "fs"; import Handlebars from "handlebars"; import { - coverDistPaths, coverTemplateHtmlPath, handlebarCompileOptions, + frontCoverDistPath, + backCoverDistPath, + startCoverDistPath, + endCoverDistPath, } from "./constants"; +import config from "../techbook.config"; // HTMLのテンプレートをHandlebarsで読み込む const templateHtml = Handlebars.compile( @@ -13,11 +17,46 @@ const templateHtml = Handlebars.compile( ); export const coverCompile = () => { - for (const { path, image } of coverDistPaths) { - // HTMLのテンプレートへ埋め込む + const edition = config.editions[config.editions.length - 1]; + { const html = templateHtml({ - coverImage: image, + kind: "front", + coverImage: config.cover.front, + title: config.title, + publisher: config.publisher, + author: config.author, + lastEdition: edition, }); - fs.writeFileSync(path, html); + fs.writeFileSync(frontCoverDistPath, html); + }{ + const html = templateHtml({ + kind: "back", + coverImage: config.cover.back, + title: config.title, + publisher: config.publisher, + author: config.author, + lastEdition: edition, + }); + fs.writeFileSync(backCoverDistPath, html); + }{ + const html = templateHtml({ + kind: "start", + coverImage: config.cover.start, + title: config.title, + publisher: config.publisher, + author: config.author, + lastEdition: edition, + }); + fs.writeFileSync(startCoverDistPath, html); + }{ + const html = templateHtml({ + kind: "end", + coverImage: config.cover.end, + title: config.title, + publisher: config.publisher, + author: config.author, + lastEdition: edition, + }); + fs.writeFileSync(endCoverDistPath, html); } }; diff --git a/src/generateVivlioStyleConfig.ts b/src/generateVivlioStyleConfig.ts index ffdcf54..b2a6a95 100644 --- a/src/generateVivlioStyleConfig.ts +++ b/src/generateVivlioStyleConfig.ts @@ -16,7 +16,7 @@ import { import { docsHeadingList } from "./toc"; export default function generateVivlioStyleConfig() { - const { title, author } = miraiBookConfig; + const { title, author, size } = miraiBookConfig; // MEMO: build(PDF生成)用にvivliostyle.config.cjsを生成する const docsEntryList = docsHeadingList.map(({ headings, dist }) => ({ path: dist, @@ -26,8 +26,7 @@ export default function generateVivlioStyleConfig() { title, author, language: "ja", - size: "JIS-B5", - // size: "105mm 173mm", + size: size, entryContext: ".", entry: [ frontCoverDistPath, diff --git a/src/global-105x173.css b/src/global-105x173.css new file mode 100644 index 0000000..47769bd --- /dev/null +++ b/src/global-105x173.css @@ -0,0 +1,797 @@ +@import "tailwindcss/base"; +@import "tailwindcss/components"; +@import "tailwindcss/utilities"; + +@page { + size: 105mm 173mm; + /* トンボを追加 */ + /* marks: crop cross; */ + /* トンボの塗り足しを3mmに設定 */ + /* bleed: 3mm; */ + margin-top: 25mm; + margin-bottom: 33mm; + @bottom-center { + content: counter(page); + } + @top-center { + content: element(topCenter); + } + @footnote { + float: bottom; + } +} + +@page :left { + /* 左ページの右余白を広げる */ + /* 上 | 右 | 下 | 左 */ + margin: 9% 10% 9% 8%; + + @top-left-corner { + content: element(topLeftCorner); + } + @top-left { + content: env(pub-title); + width: 350px; + } + @top-right-corner { + content: element(topRightCorner); + } + @top-right { + content: element(topRight); + } + /* @left-top { + content: element(leftPageLeftTop); + } + @left-middle { + content: element(leftPageLeftMiddle); + } + @left-bottom { + content: element(leftPageLeftBottom); + } */ + @bottom-left-corner { + content: element(bottomLeftCorner); + } + @bottom-left { + content: element(bottomLeft); + } + @bottom-right-corner { + content: element(bottomRightCorner); + } + @bottom-right { + content: element(bottomRight); + } +} + +@page :right { + /* 右ページの左余白を広げる */ + /* 上 | 右 | 下 | 左 */ + margin: 9% 8% 9% 10%; + + @top-right-corner { + content: element(topLeftCorner); + } + @top-right { + content: "第" counter(chapter) "章 " env(doc-title); + } + @top-left-corner { + content: element(topRightCorner); + } + @top-left { + content: element(topRight); + } + /* @right-top { + content: element(rightPageRightTop); + } + @right-middle { + content: element(rightPageRightMiddle); + } + @right-bottom { + content: element(rightPageRightBottom); + } */ + @bottom-left-corner { + content: element(bottomRightCorner); + } + @bottom-left { + content: element(bottomRight); + } + @bottom-right-corner { + content: element(bottomLeftCorner); + } + @bottom-right { + content: element(bottomLeft); + } +} + +/* cover */ +.cover { + page: cover; + page-break-before: always; /* Use if your last page is blank, else omit. */ +} +@page cover { + background-image: var(--cover-url); + background-size: cover; + background-repeat: no-repeat; + @top-left { + content: none; + } + @top-left-corner { + content: none; + } + @top-center { + content: none; + } + @top-right-corner { + content: none; + } + @top-right { + content: none; + } + @bottom-center { + content: none; + } + @bottom-left-corner { + content: none; + } + @bottom-left { + content: none; + } + @bottom-right { + content: none; + } + @bottom-right-corner { + content: none; + } +} +.coverText { + @apply h-[calc(173mm*0.8)]; +} + +:root { + @apply font-["Rounded_Mgen+_2p","Rounded_Mplus_1c","PlemolJP"] [line-height:1.75] text-[10px]; +} + +/* リンク */ +a { + @apply whitespace-pre-wrap break-all; +} + +.writing-mode-vertical-rl { + writing-mode: vertical-rl; +} + +/* インラインコード */ +p > code { + @apply px-1 py-0.5 bg-primary-200 rounded mx-1; +} + +/* タスクリスト */ +ul.contains-task-list { + @apply space-y-2; +} +ul.contains-task-list > li.task-list-item > input[type="checkbox"] { + @apply scale-150; +} +ul.contains-task-list > li.task-list-item { + @apply flex items-center flex-row gap-2 text-xl; +} +ul.contains-task-list > li.task-list-item::before { + @apply text-2xl content-["-"]; +} + +/* ソースコードの埋め込み */ +.embedCode { + @apply block mx-auto my-0 max-w-full h-auto; +} +.embedCodeCaption { + @apply text-center -mt-3 text-sm font-bold ci-[caption]; +} +.embedCodeCaption::before { + content: "コード" counter(chapter) "-" counter(caption) ". "; +} + +/* shiki */ +.astro-code, +.shiki { + @apply font-["Rounded_Mgen+_1mn","PlemolJP_Console"] rounded px-4 py-2 border border-gray-300 border-solid block whitespace-pre-wrap break-all; +} +.shiki .diff, +.shiki .highlighted { + @apply -mx-4 px-4 py-[2px]; +} + +/* DOC: https://github.com/shikijs/shiki/issues/3#issuecomment-830564854 */ +/* DOC: https://github.com/shikijs/shiki/blob/main/packages/transformers/test/fixtures/diff/a.js.output.html */ +.shiki > code { + counter-reset: shiki_line_number; + counter-increment: shiki_line_number 0; +} +.shiki > code .line:not(:last-child)::before { + @apply w-8 mr-6 inline-block text-right text-gray-600 text-xs; + content: counter(shiki_line_number); + counter-increment: shiki_line_number; +} +.shiki > code .line.diff.add { + @apply bg-[rgba(117,249,117,0.4)]; +} +.shiki > code .line.diff.add::before { + @apply text-[green] w-8; + content: counter(shiki_line_number) " +"; +} +.shiki > code .line.diff.remove { + @apply bg-[rgba(250,112,112,0.4)]; +} +.shiki > code .line.diff.remove::before { + @apply text-[red] w-8; + content: counter(shiki_line_number) " -"; +} + +/* DOC: https://github.com/shikijs/shiki/blob/main/packages/transformers/test/fixtures/highlight/a.js.output.html */ +.shiki .highlighted { @apply bg-[rgba(0,119,255,0.1)]; } + +/* DOC: https://github.com/shikijs/shiki/blob/main/packages/transformers/test/fixtures/highlight-word/occurrence.js.output.html */ +.shiki .highlighted-word { + @apply py-[2px] bg-[rgba(0,119,255,0.1)]; +} + +/* DOC: https://github.com/shikijs/shiki/blob/main/packages/transformers/test/fixtures/error-level/a.js.output.html */ +.shiki .highlighted.warning { @apply bg-[rgba(255,255,3,0.5)]; } +.shiki .highlighted.error { @apply bg-[rgba(255,0,0,0.5)]; } + +/* Page Running elements https://www.w3.org/TR/css-gcpm-3/#running-elements */ +.topCenter { + position: running(topCenter); +} +.topRight { + position: running(topRight); +} +.topRightCorner { + position: running(topRightCorner); +} +.topLeftCorner { + position: running(topLeftCorner); +} +.bottomRight { + position: running(bottomRight); +} +.bottomRightCorner { + position: running(bottomRightCorner); +} +.bottomLeft { + position: running(bottomLeft); +} +.bottomLeftCorner { + position: running(bottomLeftCorner); +} +/* .leftPageLeftTop { + @apply hidden; + position: running(leftPageLeftTop); +} +.leftPageLeftMiddle { + @apply hidden; + position: running(leftPageLeftMiddle); +} +.leftPageLeftBottom { + @apply hidden; + position: running(leftPageLeftBottom); +} +.rightPageRightTop { + @apply hidden; + position: running(rightPageRightTop); +} +.rightPageRightMiddle { + @apply hidden; + position: running(rightPageRightMiddle); +} +.rightPageRightBottom { + @apply hidden; + position: running(rightPageRightBottom); +} */ + +/* 見出しフォントサイズの調整 */ +@media print { + h1 { + @apply pt-10 text-4xl font-black mb-2; + } + h1::before { + @apply text-2xl font-bold ml-[2px]; + } + h1 + p { + @apply px-3 font-bold; + } + h2 { + @apply text-3xl; + } + /* h2 > span { + @apply pl-3 text-base; + } */ + h3 { + @apply text-2xl; + } + /* h3 > span { + @apply pl-3 text-[10px]; + } */ + h4 { + @apply text-xl; + } + h5 { + @apply text-lg; + } + h1, + h2, + h3, + h4, + h5, + h6 { + break-after: auto !important; + break-before: auto !important; + } + tr, + th, + td { + break-inside: auto !important; + } +} + +/* 著者の表示スタイル */ +.doc-author { + @apply text-right mb-7; + box-shadow: 0 0.7px 0 -0.4px theme("colors.stone.500"); +} + +/* 目次の章や節の表示 */ +#toc-body { + page: toc; +} +@page toc { + @top-right { + content: none; + } +} +#toc .header1::before { + content: "第" target-counter(attr(data-href), chapter) "章 "; +} +#toc .header2::before { + content: target-counter(attr(data-href), chapter) "-" target-counter(attr(data-href), header2) ". "; +} +#toc .header3::before { + content: target-counter(attr(data-href), chapter) "-" target-counter(attr(data-href), header2) "." target-counter(attr(data-href), header3) ". "; +} +#toc .header4::before { + content: target-counter(attr(data-href), chapter) "-" target-counter(attr(data-href), header2) "." target-counter(attr(data-href), header3) "." target-counter(attr(data-href), header4) ". "; +} +#toc .header5::before { + content: target-counter(attr(data-href), chapter) "-" target-counter(attr(data-href), header2) "." target-counter(attr(data-href), header3) "." target-counter(attr(data-href), header4) "." target-counter(attr(data-href), header5) ". "; +} + +/* 別の章(h1)や節(h2)へのリンク */ +a.chapref::after { + content: " (" target-counter(attr(href), page) "ページ)"; +} +a.chapref::before { + content: "第" target-counter(attr(href), chapter) "章 "; +} +a.h2ref::after { + content: " / "; +} +a.h2ref::before { + content: "第" target-counter(attr(href), chapter) "章 "; +} +a.h2title::before { + content: target-counter(attr(href url), header2) ". "; +} +a.h2title::after { + content: " (" target-counter(attr(href), page) "ページ)"; +} +a.imageref::before { + content: "図" target-counter(attr(href), chapter) "-" target-counter(attr(href url), caption) ". "; +} +a.imageref::after { + content: " (" target-counter(attr(href), page) "ページ)"; +} +a.coderef::before { + content: "コード" target-counter(attr(href), chapter) "-" target-counter(attr(href url), caption) ". "; +} +a.coderef::after { + content: " (" target-counter(attr(href), page) "ページ)"; +} +a.tableref::before { + content: "表" target-counter(attr(href), chapter) "-" target-counter(attr(href url), caption) ". "; +} +a.tableref::after { + content: " (" target-counter(attr(href), page) "ページ)"; +} + +/* チャプターのカウンター */ +@page chapter:first { + counter-reset: chapter; +} +@page chapter:nth(1) { + counter-increment: chapter; +} +.chapter h1::before { + @apply block mb-1 text-[50%]; + content: "第" counter(chapter) "章"; +} +.chapter { + page: chapter; +} + +/* h2〜h5のカウンター */ +.chapter body { + counter-reset: header2 header3 header4 header5 caption; +} +.chapter h1 { + counter-reset: header2 header3 header4 header5 caption; +} +.chapter h2::before { + @apply block text-[70%]; + content: counter(chapter) "-" counter(header2) ". "; +} +.chapter h2 { + counter-increment: header2; + counter-reset: header3 header4 header5; +} +.chapter h3::before { + @apply text-[70%]; + content: counter(chapter) "-" counter(header2) "." counter(header3) ". "; +} +.chapter h3 { + counter-increment: header3; + counter-reset: header4 header5; +} +.chapter h4::before { + @apply text-[70%]; + content: counter(chapter) "-" counter(header2) "." counter(header3) "." + counter(header4) ". "; +} +.chapter h4 { + counter-increment: header4; + counter-reset: header5; +} +.chapter h5::before { + @apply text-[70%]; + content: counter(chapter) "-" counter(header2) "." counter(header3) "." + counter(header4) "." counter(header5) ". "; +} +.chapter h5 { + counter-increment: header5; +} + +/* footnote */ +.footnote { + float: footnote; + footnote-display: block; + counter-increment: footnote; + background-color: #fff; + font-weight: normal; +} +.footnote::footnote-call { + content: "[" counter(footnote) "]"; + display: inline; + vertical-align: super; +} +.footnote::footnote-marker { + content: "[" counter(footnote) "] "; + display: inline; +} + +/* footnote inline */ +.footnote-inline { + background-color: #eee; + color: gray; + font-size: 10px; + padding-left: 0.5rem; + padding-right: 0.5rem; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + border-radius: 0.25rem; +} +.footnote-inline a { + word-break: break-all; +} + +/* appendix */ +#appendix-body { + page: appendix; +} +@page appendix { + @top-right { + content: none; + } +} +.appendix { + @apply px-1 py-0.5 bg-primary-200 rounded mx-1;; +} + +/* 1段組み用のスタイル */ +.colmun-count-1 { + column-count: 1; +} +/* 2段組み用のスタイル */ +.colmun-count-2 { + /* @apply pb-7; */ + column-count: 2; + column-gap: 2rem; + column-rule: solid 1px theme("colors.stone.300"); + /* column-fill: balance-all; */ + /* column-fill: balance; */ + column-fill: auto; +} +/* 2段組みをまたぐ要素(見出し、画像、ソースコード)などに指定する */ +.column-span-all { + /* INFO: https://github.com/vivliostyle/vivliostyle.js/issues/542 */ + float-reference: column; + float: top; + column-span: all; +} +.column-span-all-h5 { + background-color: lightgray; + padding: 1rem; + column-span: all; +} +.column-span-all-amber-100 { + @apply column-span-all; + background-color: theme("colors.amber.100"); + color: theme("colors.amber.800"); +} +.column-span-all-stone-100 { + @apply column-span-all; + background-color: theme("colors.stone.100"); + color: theme("colors.stone.800"); +} + +/* チャットエリアのスタイル */ +.chat { + @apply space-y-2; + padding-left: 0px; +} +.chat-header { + @apply flex content-center justify-center text-center list-none; +} +.chat-header > div { + @apply px-4 py-2 mt-4 text-xs rounded-full min-w-fit max-w-fit; + background-color: theme("colors.stone.200"); + color: theme("colors.stone.800"); + border-color: transparent; +} +.chat-left { + @apply flex justify-start pt-4; +} +.chat-left-invisible { + @apply flex justify-start; +} +.chat-left-invisible .trianle-left, +.chat-left-invisible .chat-faceicon { + @apply invisible; +} +.chat-right { + @apply flex justify-end pt-4; +} +.chat-right-invisible { + @apply flex justify-end; +} +.chat-right-invisible .trianle-right, +.chat-right-invisible .chat-faceicon { + @apply invisible; +} +.chat-contents { + @apply px-4; +} +.chat-faceicon { + @apply relative p-0; +} +.chat-faceicon > img { + @apply w-16 h-16; + border-radius: 50%; +} +.chat-faceicon-name { + @apply absolute left-0 right-0 m-auto text-[8px] text-center top-[4.125rem]; +} +.chat .qrcode { + @apply w-36; +} +.balloon { + @apply relative max-w-xl px-4 py-2 rounded-lg border-[1px] border-solid my-1; + border-color: transparent; +} +.balloon > .trianle-left { + border: 1rem solid transparent; + position: absolute; + left: -1.75rem; + top: 0; + transform: rotate(0deg); +} +.balloon > .trianle-right { + border: 1rem solid transparent; + position: absolute; + right: -1.75rem; + top: 0; + transform: rotate(180deg); +} +.balloon-indigo-200 { + @apply balloon; + background-color: theme("colors.indigo.200"); + color: theme("colors.indigo.800"); + border-color: transparent; +} +.balloon-indigo-200 > .trianle-left { + border-right: 1rem solid theme("colors.indigo.200"); +} +.balloon-indigo-200 > .trianle-right { + border-right: 1rem solid theme("colors.indigo.200"); +} +.balloon-fuchsia-200 { + @apply balloon; + background-color: theme("colors.fuchsia.200"); + color: theme("colors.fuchsia.800"); + border-color: transparent; +} +.balloon-fuchsia-200 > .trianle-left { + border-right: 1rem solid theme("colors.fuchsia.200"); +} +.balloon-fuchsia-200 > .trianle-right { + border-right: 1rem solid theme("colors.fuchsia.200"); +} +.balloon-stone-200 { + @apply balloon; + background-color: theme("colors.stone.200"); + color: theme("colors.stone.800"); + border-color: transparent; +} +.balloon-stone-200 > .trianle-left { + border-right: 1rem solid theme("colors.stone.200"); +} +.balloon-stone-200 > .trianle-right { + border-right: 1rem solid theme("colors.stone.200"); +} +.balloon-contents { + @apply p-2; +} +.balloon-contents > img { + @apply w-full mt-2; +} + +/* 画像埋め込み */ +.embedImage { + @apply block mx-auto my-0 max-w-full h-auto; +} +.embedImageCaption { + @apply text-center text-sm font-bold ci-[caption]; +} +.embedImageCaption::before { + content: "図" counter(chapter) "-" counter(caption) ". "; +} +.embedImageFigure { + @apply block text-center; +} + +/* Mermaid、PlantUML */ +img[id^="mermaid-"], img[src^="https://www.plantuml.com/plantuml/png/"] { + @apply block max-w-[75%] h-auto mx-auto my-0; +} + +/* チャプターカバー */ +.chapterCover { + @apply h-[calc(173mm*0.8)]; +} +a.chapterCoverTitle::before { + content: "Chapter" target-counter(attr(href), chapter) " "; +} + +/* 左柱 */ +a.leftPillarChapter::before { + content: "第" target-counter(attr(href), chapter) "章 "; + writing-mode: vertical-rl; +} + +/* 右柱 TODO: 時々、??になるバグがあるので使わない */ +/* a.rightPillarChapterNo::after { + content: target-counter(attr(href), chapter) "章 "; +} */ + +/* テーブル */ +table { + @apply border-collapse; +} +table caption { + @apply text-sm font-bold caption-bottom ci-[caption]; +} +table caption::before { + content: "表" counter(chapter) "-" counter(caption) ". "; +} +table th, +table td { + @apply px-1 py-2 border-0 border-solid border-x-2 border-white; +} +table th:first-child, +table td:first-child { + @apply py-2 pl-2; +} +table th { + @apply text-xs bg-primary-500 border-solid border-y-2 text-white; +} +table td { + @apply bg-primary-200 +} +table tr { + @apply border-solid border-b-2 border-white; +} +table tr:last-child { + @apply border-b-2 border-solid border-white; +} + +/* 奥付のスタイル */ +#colophon { + page: colophon; +} +@page colophon { + @top-right { + content: none; + } +} +#colophon { + @apply relative [float:bottom] [float-reference:page] mb-0; +} +#colophon .editions { + font-size: 1em; + padding: 0; + list-style: none; +} +#colophon .info { + width: 100%; +} +#colophon .info tr { + border: 0; + box-shadow: none; + background-color: white; +} +#colophon .info tr:first-child { + box-shadow: 0 -1.5px 0 -0.4px theme("colors.stone.500"); +} +#colophon .info tr:last-child { + box-shadow: 0 1.4px 0 -0.4px theme("colors.stone.500"); +} +#colophon .info td { + vertical-align: top; + padding-left: 0; + font-size: 1em; + background-color: white; +} +#colophon .info td:first-child { + text-align: center; +} + +/* 著者プロフィールのスタイル */ +#profile { + page: profile; +} +@page profile { + @top-right { + content: none; + } +} +#profile { + break-before: left; +} +#profile .author { + display: flex; + margin: 1rem 0; +} +#profile .author img { + margin: 0 10px 8px 0; + width: 45px; + height: 45px; + border-radius: 50%; + background-color: theme("colors.stone.300"); +} +#profile .profile { + flex-grow: 1; +} +#profile .profile h5 { + margin-top: 4px; + margin-bottom: 0px; +} +#profile .profile h4 { + margin-top: 3px; + margin-bottom: 0px; +} diff --git a/src/global.css b/src/global.css index b49d3f6..cb5a32b 100644 --- a/src/global.css +++ b/src/global.css @@ -6,7 +6,6 @@ @page { size: jis-b5; - /* size: 105mm 173mm; */ /* margin: 10% !important; */ /* トンボを追加 */ /* marks: crop cross; */ @@ -117,6 +116,9 @@ background-image: var(--cover-url); background-size: cover; background-repeat: no-repeat; + @top-left { + content: none; + } @top-left-corner { content: none; } @@ -145,6 +147,9 @@ content: none; } } +.coverText { + @apply h-[calc(257mm*0.8)]; +} :root { @apply font-["Rounded_Mgen+_2p","Rounded_Mplus_1c","PlemolJP"] [line-height:1.75] text-[10px]; diff --git a/src/introduction.ts b/src/introduction.ts index e44ca99..216f3ce 100644 --- a/src/introduction.ts +++ b/src/introduction.ts @@ -1,6 +1,6 @@ import fs from "fs"; import Handlebars from "handlebars"; -import miraiBookConfig from "../techbook.config"; +import config from "../techbook.config"; import { finallyDistPath, finallyDocPath, @@ -8,13 +8,14 @@ import { introductionDistPath, introductionDocPath, introductionTemplateHtmlPath, + simpleIntroductionTemplateHtmlPath, processor, } from "./constants"; import { rightPillarChapterList } from "./toc"; // HTMLのテンプレートをHandlebarsで読み込む const introductionTemplateHtml = Handlebars.compile( - fs.readFileSync(introductionTemplateHtmlPath).toString(), + fs.readFileSync(config.size === "105mm 173mm" ? simpleIntroductionTemplateHtmlPath : introductionTemplateHtmlPath).toString(), handlebarCompileOptions, ); diff --git a/src/main.ts b/src/main.ts index c9fbb2b..7588224 100644 --- a/src/main.ts +++ b/src/main.ts @@ -8,9 +8,9 @@ import { chatRegisterHelper } from "./chat"; import { colophonCompile } from "./colophon"; import { chapterTemplateHtmlPath, + simpleChapterTemplateHtmlPath, handlebarCompileOptions, lockFileDistPath, - lockFileSrcPath, processor, } from "./constants"; import { coverCompile } from "./cover"; @@ -22,6 +22,7 @@ import { profileCompile } from "./profile"; import "./split"; import "./switch"; import { docsHeadingList, rightPillarChapterList, tocCompile } from "./toc"; +import config from "../techbook.config"; // Handlebarsにヘルパーを登録する chatRegisterHelper(); @@ -34,7 +35,7 @@ pageBreakRegisterHelper(); // HTMLのテンプレートをHandlebarsで読み込む const chapterTemplateHtml = Handlebars.compile( - fs.readFileSync(chapterTemplateHtmlPath).toString(), + fs.readFileSync(config.size === "105mm 173mm" ? simpleChapterTemplateHtmlPath : chapterTemplateHtmlPath).toString(), handlebarCompileOptions, ); diff --git a/src/simplechapter-template.html b/src/simplechapter-template.html new file mode 100644 index 0000000..5700cd3 --- /dev/null +++ b/src/simplechapter-template.html @@ -0,0 +1,53 @@ + + + + + {{{globalStyle}}} + + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{title}}
+
+
+

{{data.matter.description}}

+
+
+
+ + + {{{body}}} + +
+ + \ No newline at end of file diff --git a/src/simpleintroduction-template.html b/src/simpleintroduction-template.html new file mode 100644 index 0000000..957e180 --- /dev/null +++ b/src/simpleintroduction-template.html @@ -0,0 +1,41 @@ + + + + + {{{globalStyle}}} + + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{{body}}} +
+ + \ No newline at end of file diff --git a/techbook.config.ts b/techbook.config.ts index 3f89b50..1e087a2 100644 --- a/techbook.config.ts +++ b/techbook.config.ts @@ -1,4 +1,5 @@ -export default { +const config: MiraiBookConfig = { + size: "105mm 173mm", title: "(本のタイトル)", author: "(著者名)", publisher: "(サークル名)", @@ -20,5 +21,40 @@ brタグで改行ができます。`, image: "../images/(プロファイル画像を置いて指定する).png", }, ], + cover: { + // TODO: 表紙画像が必要な場合は置いて指定してください + // front: "front-cover.png", + // back: "back-cover.png", + // start: "start-cover.png", + // end: "end-cover.png", + }, copyright: "(コピーライトを書く)", -}; \ No newline at end of file +}; +export default config; + +export interface MiraiBookConfig { + size: "JIS-B5" | "105mm 173mm"; + title: string; + author: string; + publisher: string; + printer: string; + editions: { + name: string; + datetime: string; + datetimeView: string; + version: string; + }[]; + profiles: { + position: string; + name: string; + description: string; + image: string; + }[]; + cover: { + front?: string; + back?: string; + start?: string; + end?: string; + }; + copyright: string; +} \ No newline at end of file