Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Support themes for HTML inputs and toc #111

Merged
merged 7 commits into from
Jan 29, 2021
Merged

Conversation

spring-raining
Copy link
Member

@spring-raining spring-raining commented Jan 25, 2021

About

fixes #66 #105

This pull request improves the auto-generating behavior of Table of Content.

toc option (vivliostyle.config.js)

If true is set, a ToC HTML will be generated on {workspaceDir}/index.html and be inserted to the first of readingOrder.

module.exports = {
  toc: true,
};
{
  "readingOrder": [
    {
      "url": "index.html",
      "title": "Table of Contents",
      "rel": "contents"
    },
    ...
  ]
}

If the string is set, a ToC HTML will be generated on {workspaceDir}/{toc} and be inserted to the first of readingOrder.

module.exports = {
  toc: 'contents.html',
};
{
  "readingOrder": [
    {
      "url": "contents.html",
      "title": "Table of Contents",
      "rel": "contents"
    },
    ...
  ]
}

tocTitle option (vivliostyle.config.js)

The title of generated ToC (default: Table of Contents)

module.exports = {
  toc: true,
  tocTitle: '目次',
};
{
  "readingOrder": [
    {
      "url": "index.html",
      "title": "目次",
      "rel": "contents"
    },
    ...
  ]
}

entry[number].rel = 'contents' (vivliostyle.config.js)

We can set the order of ToC inserted by this option. If { rel: 'contents' } is set but source is not set, the generated ToC will be inserted in this index.

module.exports = {
  entry: [
    'a.md',
    { rel: 'contents' },
    'b.md',
  ],
};
{
  "readingOrder": [
    { "url": "a.html" },
    {
      "url": "index.html",
      "title": "Table of Contents",
      "rel": "contents"
    },
    { "url": "b.html" }
  ]
}

If source is set, the document is simply loaded as HTML (not related to ToC feature).

module.exports = {
  entry: [
    { source: 'toc.html', rel: 'contents' },
  ],
};
{
  "readingOrder": [
    {
      "url": "toc.html",
      "rel": "contents"
    },
  ]
}

@@ -25,6 +25,7 @@
"@vivliostyle/vfm": "v1.0.0-alpha.10",
"ajv": "^6.12.2",
"chalk": "^4.1.0",
"cheerio": "^1.0.0-rc.5",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used the Cheerio parser library rather thane JSDOM to fix #105

@spring-raining spring-raining marked this pull request as ready for review January 27, 2021 18:53
@MurakamiShinyu
Copy link
Member

以下、テストして気になったことです。

vivliostyle.config.js に workspaceDir の指定がないとき、entry の HTML ファイルに theme が反映されない

vivliostyle.config.js で次のように theme の CSS と entry の HTML ファイルを指定しました。

  theme: 'style.css',
  entry: [
    'example.html'
  ],

しかし vivliostyle preview で組版結果を確認すると theme のスタイルは反映されていません。

次に vivliostyle.config.js に workspaceDir: "work" の設定を加えて試しました。
そうすると theme の CSS が反映されるようになりました。workspaceDir にできている HTML ファイルには
<link rel="stylesheet" href="themes/style.css">
が出力されていました。

また、 vivliostyle.config.js を削除して、コマンドラインで HTML と theme を指定したときも theme が反映されます。
vivliostyle.config.js の entry の HTML ファイルについてだけ workspaceDir の指定がないとき theme が反映されないようです。

'themes' ディレクトリの問題

entry の HTML や markdown ファイルと同じ場所にある CSS ファイルを theme に指定したとき、それが 'themes' ディレクトリにコピーされて
<link rel="stylesheet" href="themes/style.css">
のように 'themes' ディレクトリ内の CSS ファイルへのリンクになります。

CSS ファイル内から次のように画像ファイルなどへのリンクがある場合

  background: url(bg.png);

その画像ファイルなどは 'themes' ディレクトリ内にコピーされていないために、リンクエラーになります。

'themes' ディレクトリは廃止して workspaceDir のルートを使うようにすれば、元の CSS ファイルをそのまま使え、相対リンクが無効になることがなくてよいのでないでしょうか?

vivliostyle.config.js の theme: '' でエラー

vivliostyle.config.js を生成するのに vivliostyle init を実行して、そのentryにファイル原稿ファイルを指定してテストしたのですが、次のようにエラー:

✖ Error: Validation of vivliostyle.config failed. Please check the schema: /Users/shinyu/viv/test/clitest/vivliostyle.config.js
    at load (/Users/shinyu/viv/vivliostyle-cli--develop/dist/config.js:140:19)
    ...

デフォルトで生成される vivliostyle.config.js の次のところが原因でした:

  theme: '', // .css or local dir or npm package. default to undefined

theme指定なしで init を実行したときは、ここはコメントアウトされてるとよいのでないでしょうか。

目次について

目次のリストは ul より ol が適切

目次のリスト要素として <ul> が使われています。
目次のリストは論理的には ordered list が適切であるし、EPUB 仕様でも ol 要素を使うことになっています。
https://www.w3.org/publishing/epub/epub-packages.html#sec-package-nav-def-model

目次タイトルは見出しとして出力しない?

toc: true で生成される ToC HTML の <title> 要素にタイトル(デフォルト tocTitle: "Table of Contents")が出力されますが、見出しは出力されません。

目次タイトルは見出しとしても出力したほうがよいのでないかと思います。

例:

  <body>
    <nav id="toc" role="doc-toc">
      <h1>Table of Contents</h1>
      <ol>
        <li><a href="test1.html">Test One</a></li>
        <li><a href="test2.html">Test Two</a></li>
        <li><a href="test3.html">Test Three</a></li>
      </ol>
    </nav>
  </body>

目次出力のデフォルトでは、Webbook のトップの index.html ファイルが目次になります。
この index.html ファイルが Webbook のメインの HTML ファイルということになるので、タイトルとしては、「目次」よりも本のタイトルをタイトルにするほうが適切かもしれません。

「Vivliostyle で本を作ろう」を見ても、目次がある index.html ファイルのタイトルとメインの見出しは本のタイトルになっています。
https://vivliostyle.github.io/vivliostyle_doc/ja/vivliostyle-user-group-vol4/artifacts/content/index.html

そうすると、次のような index.html ファイルが生成されるのがよいかも:

<html>
  <head>
    <title>本のタイトル</title>
    <link href="publication.json" rel="publication" type="application/ld+json" />
    <link href="style.css" rel="stylesheet" />
  </head>
  <body>
    <h1>本のタイトル</h1>
    <nav id="toc" role="doc-toc">
      <h2>目次</h2>
      <ul>
        <li><a href="test1.html">Test One</a></li>
        <li><a href="test2.html">Test Two</a></li>
        <li><a href="test3.html">Test Three</a></li>
      </ul>
    </nav>
  </body>
</html>

entry に目次ファイルが指定されたとき

entry に指定されているファイルが目次出力のファイル(デフォルト "index.html")と一致するとき、あるいは entry に rel: "contents" でファイル名が指定されているとき、自動目次生成がされないようになっています。

これを次のように変えるとよいのでないかと思います:

entry に指定されている目次ファイル("index.html" あるいはそのソースとなる "index.md" ファイル、など)が存在するとして、

  • そのHTMLファイル(markdown の場合 HTML に変換したもの)の中の最初に見つかる <nav> 要素を生成された目次に置き換える
    • 元のファイルには <nav></nav> だけあればよい。それがプレースホルダーになる。
    • 元の nav 要素内に見出しなど目次のリスト要素(通常 ol 要素)以外のものがあれば、それらは保持する

@spring-raining
Copy link
Member Author

vivliostyle.config.js の theme: '' でエラー

目次のリストは ul より ol が適切

目次タイトルは見出しとして出力しない?

については修正しました。目次HTMLの <h1> には出版物のタイトル、 <h2> には目次タイトルが入るようになっています。

vivliostyle.config.js に workspaceDir の指定がないとき、entry の HTML ファイルに theme が反映されない

この問題は、Markdown→HTMLのように同じ場所に別ファイルを書き込む処理とは異なり、同一のHTMLファイルを書き換えることになるため、冪等性を保つための実装が難しいです。例えば、何も考えずにHTMLに <link rel="stylesheet" href="themes/style.css"> を挿入するよう実装した場合、buildを実行するたびにlinkタグが増えてしまうでしょう。がんばって工夫をすれば解決するかもしれませんが、vfmの機能が十分であればそもそもHTMLを書く必要がなくなるはずです。同様に、目次HTMLの書き換えも考えることが多くあります。

'themes' ディレクトリの問題

これについては確かに改善できるかもしれません。ただ、今回のPRとは関係ないため別途issueと立ててもらって良いでしょうか?

@MurakamiShinyu
Copy link
Member

vivliostyle.config.js に workspaceDir の指定がないとき、entry の HTML ファイルに theme が反映されない

この問題は、Markdown→HTMLのように同じ場所に別ファイルを書き込む処理とは異なり、同一のHTMLファイルを書き換えることになるため、冪等性を保つための実装が難しいです。……。同様に、目次HTMLの書き換えも考えることが多くあります。

はい、元のHTMLファイルを書き換えるべきではないと思います。
コマンドラインでHTMLファイルとthemeを指定したときには、元のHTMLファイルの書き換えはされませんが、themeが反映されます。元のHTMLファイルを変更した一時ファイルが作られるようになっていますね。vivliostyle.config.js の entry に書かれた HTML ファイルについても同様にするとよいと考えました。

しかし、コマンドラインで指定された1つのHTMLファイルだけを処理するのと違って、ちょっとめんどうなのは理解できます。
これらは別のissueにします。

'themes' ディレクトリの問題

これについては確かに改善できるかもしれません。ただ、今回のPRとは関係ないため別途issueと立ててもらって良いでしょうか?

はい、そうします。

@spring-raining spring-raining merged commit f1c78eb into develop Jan 29, 2021
@spring-raining spring-raining deleted the fix/toc-themes branch January 29, 2021 23:32
This was referenced Feb 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants