From c3bfd96e8370d5a9424b8cb07173e9e36b5f6018 Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Tue, 14 Feb 2023 14:13:31 +0100 Subject: [PATCH 01/46] Beginning ebook generation scripts and files --- ebook-files/.gitignore | 1 + ebook-files/container.xml | 6 + ebook-files/content.opf | 42 ++ ebook-files/cover_page.xhtml | 13 + ebook-files/images/btc-valuation-fallback.png | 3 + .../images/digital_bathroom_lock-fallback.png | 3 + .../images/emission-rates-fallback.png | 3 + ebook-files/images/energy-bars-fallback.png | 3 + .../images/gold-valuation-fallback.png | 3 + .../images/income-inequality-fallback.png | 3 + .../income-inequality-world-fallback.png | 3 + ebook-files/images/inflation-fallback.png | 3 + ebook-files/images/m2-fallback.png | 3 + ebook-files/images/m2.svg | 3 + ebook-files/images/us-gdp-fallback.png | 3 + ebook-files/images/usa-debt-fallback.png | 3 + .../images/venezuela-hero-wide-fallback.png | 3 + .../images/wealth-inequality-fallback.png | 3 + ebook-files/images/why-unbanked-fallback.png | 3 + ebook-files/images/y18-fallback.png | 3 + ebook-files/title_page.xhtml | 29 ++ ebook-files/toc.ncx | 249 ++++++++++++ ebookify | 383 ++++++++++++++++++ zippify | 5 + 24 files changed, 776 insertions(+) create mode 100644 ebook-files/.gitignore create mode 100644 ebook-files/container.xml create mode 100644 ebook-files/content.opf create mode 100644 ebook-files/cover_page.xhtml create mode 100644 ebook-files/images/btc-valuation-fallback.png create mode 100644 ebook-files/images/digital_bathroom_lock-fallback.png create mode 100644 ebook-files/images/emission-rates-fallback.png create mode 100644 ebook-files/images/energy-bars-fallback.png create mode 100644 ebook-files/images/gold-valuation-fallback.png create mode 100644 ebook-files/images/income-inequality-fallback.png create mode 100644 ebook-files/images/income-inequality-world-fallback.png create mode 100644 ebook-files/images/inflation-fallback.png create mode 100644 ebook-files/images/m2-fallback.png create mode 100644 ebook-files/images/m2.svg create mode 100644 ebook-files/images/us-gdp-fallback.png create mode 100644 ebook-files/images/usa-debt-fallback.png create mode 100644 ebook-files/images/venezuela-hero-wide-fallback.png create mode 100644 ebook-files/images/wealth-inequality-fallback.png create mode 100644 ebook-files/images/why-unbanked-fallback.png create mode 100644 ebook-files/images/y18-fallback.png create mode 100644 ebook-files/title_page.xhtml create mode 100644 ebook-files/toc.ncx create mode 100755 ebookify create mode 100755 zippify diff --git a/ebook-files/.gitignore b/ebook-files/.gitignore new file mode 100644 index 00000000..d7ec32ea --- /dev/null +++ b/ebook-files/.gitignore @@ -0,0 +1 @@ +!*.xml diff --git a/ebook-files/container.xml b/ebook-files/container.xml new file mode 100644 index 00000000..aba0b3e6 --- /dev/null +++ b/ebook-files/container.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/ebook-files/content.opf b/ebook-files/content.opf new file mode 100644 index 00000000..2d5612a2 --- /dev/null +++ b/ebook-files/content.opf @@ -0,0 +1,42 @@ + + + + Why cryptocurrencies? + Jonas Hietala + en-US + ◊UUID + ◊DATE + + + + + + + + + ◊MANIFEST_POSTS_TAG + ◊MANIFEST_IMG_TAG + + + + + + + + + + + + + + + + ◊MANIFEST_FONT_TAG + + + + + + ◊SPINE_TOC + + diff --git a/ebook-files/cover_page.xhtml b/ebook-files/cover_page.xhtml new file mode 100644 index 00000000..11ce863a --- /dev/null +++ b/ebook-files/cover_page.xhtml @@ -0,0 +1,13 @@ + + + + + + Why cryptocurrencies? + + +
+ +
+ + diff --git a/ebook-files/images/btc-valuation-fallback.png b/ebook-files/images/btc-valuation-fallback.png new file mode 100644 index 00000000..b6eb700b --- /dev/null +++ b/ebook-files/images/btc-valuation-fallback.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9ed15841d3c89fa0d346aaa255d65c45a1d34682349605c3991be55e7331d326 +size 65434 diff --git a/ebook-files/images/digital_bathroom_lock-fallback.png b/ebook-files/images/digital_bathroom_lock-fallback.png new file mode 100644 index 00000000..470b05e5 --- /dev/null +++ b/ebook-files/images/digital_bathroom_lock-fallback.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ccb5a944dab537e1f71aa45eaec3ec6429be4ff838e02922d9e630cbab9d53a +size 1212555 diff --git a/ebook-files/images/emission-rates-fallback.png b/ebook-files/images/emission-rates-fallback.png new file mode 100644 index 00000000..2f0bb738 --- /dev/null +++ b/ebook-files/images/emission-rates-fallback.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b6dd11de2c9f772180b7c77b0186f621f2a28feee7d95e42554ac257bab41c80 +size 68867 diff --git a/ebook-files/images/energy-bars-fallback.png b/ebook-files/images/energy-bars-fallback.png new file mode 100644 index 00000000..84167a7d --- /dev/null +++ b/ebook-files/images/energy-bars-fallback.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bfbe832e4fb951a24a53eb93cdb190d5f451964f7ec8cf86fe31ecabe0906511 +size 48376 diff --git a/ebook-files/images/gold-valuation-fallback.png b/ebook-files/images/gold-valuation-fallback.png new file mode 100644 index 00000000..acd8630c --- /dev/null +++ b/ebook-files/images/gold-valuation-fallback.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:14a5ad63ff322af90e974a110d0742eadc78cc11baf36eec8f791a6d8b4cc4ed +size 58096 diff --git a/ebook-files/images/income-inequality-fallback.png b/ebook-files/images/income-inequality-fallback.png new file mode 100644 index 00000000..f9a9c649 --- /dev/null +++ b/ebook-files/images/income-inequality-fallback.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:af523730c6cc8a94c562c7af8a6d2733a08b31df140d8a9f3d16efd385063928 +size 87856 diff --git a/ebook-files/images/income-inequality-world-fallback.png b/ebook-files/images/income-inequality-world-fallback.png new file mode 100644 index 00000000..1acbecfa --- /dev/null +++ b/ebook-files/images/income-inequality-world-fallback.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:13989cbb75722069b9484545c9845f73bf82fd2bff28adcf9030890c591f7aa1 +size 131751 diff --git a/ebook-files/images/inflation-fallback.png b/ebook-files/images/inflation-fallback.png new file mode 100644 index 00000000..14a914c4 --- /dev/null +++ b/ebook-files/images/inflation-fallback.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:132bfb2e83881fccd81a4ac4961716087e1c491afb9c40ed7f7006cbd1b34a64 +size 111104 diff --git a/ebook-files/images/m2-fallback.png b/ebook-files/images/m2-fallback.png new file mode 100644 index 00000000..3838292b --- /dev/null +++ b/ebook-files/images/m2-fallback.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:21b96fbf3a1d168b776d979735a0da6c9be4bb1ffed246326a0b2c7d47710ce9 +size 54549 diff --git a/ebook-files/images/m2.svg b/ebook-files/images/m2.svg new file mode 100644 index 00000000..43881069 --- /dev/null +++ b/ebook-files/images/m2.svg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c304def5ff8d38394b4cf5423daf24057d63eae2075d2b39eb7a7925a38c5ff4 +size 380176 diff --git a/ebook-files/images/us-gdp-fallback.png b/ebook-files/images/us-gdp-fallback.png new file mode 100644 index 00000000..b0864fee --- /dev/null +++ b/ebook-files/images/us-gdp-fallback.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2f6c2480831d0fcb92ce66a013477ec0ce2a0bb999046573a5160bb9d0d41daf +size 67184 diff --git a/ebook-files/images/usa-debt-fallback.png b/ebook-files/images/usa-debt-fallback.png new file mode 100644 index 00000000..f5d58db1 --- /dev/null +++ b/ebook-files/images/usa-debt-fallback.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:21ef23af6d8c497f97132d77f052959637cfd21db9a1931cc9e9e74e56759464 +size 46713 diff --git a/ebook-files/images/venezuela-hero-wide-fallback.png b/ebook-files/images/venezuela-hero-wide-fallback.png new file mode 100644 index 00000000..3df9bff2 --- /dev/null +++ b/ebook-files/images/venezuela-hero-wide-fallback.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:54d9795a720ef0c77189a7d05996f6f273eadcec3a475fc31d41f52f69508720 +size 707088 diff --git a/ebook-files/images/wealth-inequality-fallback.png b/ebook-files/images/wealth-inequality-fallback.png new file mode 100644 index 00000000..85829e20 --- /dev/null +++ b/ebook-files/images/wealth-inequality-fallback.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:14ead6b092c6fce31dcb7952354d7d0bb86a21a7f4c8a6642751439f2a8ae8fd +size 105469 diff --git a/ebook-files/images/why-unbanked-fallback.png b/ebook-files/images/why-unbanked-fallback.png new file mode 100644 index 00000000..f41e3041 --- /dev/null +++ b/ebook-files/images/why-unbanked-fallback.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d4e338d0feb892f9d8e53a19f9d8b404c1848afbb4f3e54704e5acd964d17b83 +size 81523 diff --git a/ebook-files/images/y18-fallback.png b/ebook-files/images/y18-fallback.png new file mode 100644 index 00000000..85dd54f9 --- /dev/null +++ b/ebook-files/images/y18-fallback.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:87734c71d1ca76d082358f7cca39bc63e1146042bf5a9bcf8d25d369f51a100b +size 623 diff --git a/ebook-files/title_page.xhtml b/ebook-files/title_page.xhtml new file mode 100644 index 00000000..e45cec9d --- /dev/null +++ b/ebook-files/title_page.xhtml @@ -0,0 +1,29 @@ + + + + + + Why cryptocurrencies? + + +
+

Why cryptocurrencies?

+

What they are, what they do and why they matter

+ +

v1.0.0

+ +

The full text of this book is available online at: whycryptocurrencies.com +

+ +

This is a self-published book, and if you’re curious about the creation process I wrote a few blog posts about it: jonashietala.se/blog/tags/why_cryptocurrencies/

+ +

Cover art by Brad Lark: blark@blark.com

+ +

Copyright © 2021 Jonas Hietala.

+ +

All rights reserved.

+ +

ISBN: 978-91-986762-1-1

+
+ + diff --git a/ebook-files/toc.ncx b/ebook-files/toc.ncx new file mode 100644 index 00000000..a749d94d --- /dev/null +++ b/ebook-files/toc.ncx @@ -0,0 +1,249 @@ + + + + + + + + + + + Why cryptocurrencies? + + + + + Acknowledgments + + + + + + About the book + + + + + + Why cryptocurrencies in five minutes + + + + + + What is a cryptocurrency? + + + + + Properties of a cryptocurrency + + + + + + How do cryptocurrencies work? + + + + + + Look out for snake oil + + + + + + What is money? + + + + + + Are cryptocurrencies money? + + + + + + + Better digital payments + + + + + Cheaper & faster + + + + + + “Undesirable” businesses + + + + + + Freezing of merchant accounts + + + + + + Uncensorable donations + + + + + + For the unbanked + + + + + + + A better currency + + + + + The financial crisis, bad loans and bailouts + + + + + + The blind leading the blind + + + + + + A defective system + + + + + + Private money + + + + + + A global currency + + + + + + + Brave new world + + + + + Darknet markets + + + + + + A Swiss bank account in your pocket + + + + + + The cashless dystopia + + + + + + Protection against government confiscation + + + + + + Separation of money and state + + + + + + + Extensions + + + + + Timestamping service + + + + + + Uncensorable Twitter + + + + + + Provably fair gambling + + + + + + Tokens + + + + + + Improved voting + + + + + + + Appendix + + + + + The Bitcoin white paper + + + + + + Challenges for cryptocurrencies + + + + + + A hitchhiker’s guide to cryptography + + + + + + Cryptocurrencies are antifragile + + + + + + + About me, the author + + + + + diff --git a/ebookify b/ebookify new file mode 100755 index 00000000..b71c53d9 --- /dev/null +++ b/ebookify @@ -0,0 +1,383 @@ +#!/usr/bin/python3 + +import glob +import subprocess +import os.path +import re +import sys +import datetime + +# See +# http://www.jedisaber.com/eBooks/Tutorial.shtml + +now = datetime.datetime.now() +uuid = "0dfc44f6-9c27-42ea-b6a8-45334b6aeeff" +# uuid = "0dfc44f6-9c27-42ea-b6a8-45334b6aeeff" + datetime.datetime.now().strftime("%y-%m-%d:%H%M") + +dirname = os.path.dirname(__file__) +site_dir = os.path.join(dirname, "_site") +ebook_files_dir = os.path.join(dirname, "ebook-files") + +ebook_dir = os.path.join(dirname, "_ebook") +meta_dir = os.path.join(ebook_dir, "META-INF") +oebps_dir = os.path.join(ebook_dir, "OEBPS") +css_dir = oebps_dir +image_dir = os.path.join(oebps_dir, "images") +font_dir = os.path.join(oebps_dir, "fonts") + +toc = [ + "acknowledgements.html", + "about_the_book.html", + "eli5.html", + "what_is_a_cryptocurrency.html", + "properties_of_a_cryptocurrency.html", + "how_do_cryptocurrencies_work.html", + "look_out_for_snake_oil.html", + "what_is_money.html", + "are_cryptocurrencies_money.html", + "better_digital_payments.html", + "cheaper_faster.html", + "undesirable_businesses.html", + "freezing_of_merchant_accounts.html", + "uncensorable_donations.html", + "for_the_unbanked.html", + "better_currency.html", + "financial_crisis.html", + "the_blind_leading_the_blind.html", + "a_defective_system.html", + "private_money.html", + "global_currency.html", + "brave_new_world.html", + "darknet_markets.html", + "swiss_bank_account_in_your_pocket.html", + "cashless_dystopia.html", + "protection_against_government_confiscation.html", + "separation_of_money_and_state.html", + "extensions.html", + "timestamping_service.html", + "uncensorable_twitter.html", + "provably_fair_gambling.html", + "tokens.html", + "voting.html", + "appendix.html", + "bitcoin_whitepaper.html", + "challenges.html", + "cryptography.html", + "antifragile.html", + "about_me.html", +] + +titles = { + "acknowledgements.html": "Acknowledgments", + "about_the_book.html": "About the book", + "eli5.html": "Why cryptocurrencies in five minutes", + "what_is_a_cryptocurrency.html": "What is a cryptocurrency?", + "properties_of_a_cryptocurrency.html": "Properties of a cryptocurrency", + "how_do_cryptocurrencies_work.html": "How do cryptocurrencies work?", + "look_out_for_snake_oil.html": "Look out for snake oil", + "what_is_money.html": "What is money?", + "are_cryptocurrencies_money.html": "Are cryptocurrencies money?", + "better_digital_payments.html": "Better digital payments", + "cheaper_faster.html": "Cheaper & faster", + "undesirable_businesses.html": "“Undesirable” businesses", + "freezing_of_merchant_accounts.html": "Freezing of merchant accounts", + "uncensorable_donations.html": "Uncensorable donations", + "for_the_unbanked.html": "For the unbanked", + "better_currency.html": "A better currency", + "financial_crisis.html": "The financial crisis, bad loans and bailouts", + "the_blind_leading_the_blind.html": "The blind leading the blind", + "a_defective_system.html": "A defective system", + "private_money.html": "Private money", + "global_currency.html": "A global currency", + "brave_new_world.html": "Brave new world", + "darknet_markets.html": "Darknet markets", + "swiss_bank_account_in_your_pocket.html": + "A Swiss bank account in your pocket", + "cashless_dystopia.html": "The cashless dystopia", + "protection_against_government_confiscation.html": + "Protection against government confiscation", + "separation_of_money_and_state.html": "Separation of money and state", + "extensions.html": "Extensions", + "timestamping_service.html": "Timestamping service", + "uncensorable_twitter.html": "Uncensorable Twitter", + "provably_fair_gambling.html": "Provably fair gambling", + "tokens.html": "Tokens", + "voting.html": "Improved voting", + "appendix.html": "Appendix", + "bitcoin_whitepaper.html": "The Bitcoin white paper", + "challenges.html": "Challenges for cryptocurrencies", + "cryptography.html": "A hitchhiker’s guide to cryptography", + "antifragile.html": "Cryptocurrencies are antifragile", + "about_me.html": "About me, the author", +} + +# {src: dst} of hrefs we need to replace +link_replace = {} +images = [] +fonts = [] + + +def main(): + clean() + setup_basics() + + setup_images() + setup_fonts() + + setup_content_opf() + setup_toc_ncx() + setup_css() + + # FIXME Fonts: + # https://www.oreilly.com/library/view/epub-3-best/9781449329129/ch04.html + + setup_post_replacements() + setup_posts() + + setup_static_pages() + setup_toc() + + create_zip() + + +def clean(): + # Clean destination directory. + subprocess.run(f"rm -r {ebook_dir}/", shell=True) + subprocess.run("rm why_cryptocurrencies.epub", shell=True) + + +def setup_basics(): + # Create mimetype file + subprocess.run(f"mkdir -p {ebook_dir}/", shell=True) + with open(os.path.join(ebook_dir, "mimetype"), 'w') as f: + f.write("application/epub+zip") + + # Create container + subprocess.run(f"mkdir -p {meta_dir}", shell=True) + subprocess.run(f"cp {ebook_files_dir}/container.xml {meta_dir}/", + shell=True) + + +def setup_images(): + subprocess.run(f"mkdir -p {image_dir}", shell=True) + subprocess.run(f"mkdir -p {image_dir}/markets", shell=True) + subprocess.run(f"mkdir -p {image_dir}/cover", shell=True) + subprocess.run(f"mkdir -p {image_dir}/donations", shell=True) + + # Manually added images + subprocess.run(f"cp {ebook_files_dir}/images/* {image_dir}/", shell=True) + + for match in ["images/*", "images/*/*"]: + for src in glob.glob(match): + if src.startswith("images/landing"): + continue + + if src.startswith("images/donations"): + continue + + if src.startswith("images/cover"): + if src != "images/cover/front.png": + continue + + if os.path.isfile(src): + dst = os.path.join(oebps_dir, src) + subprocess.run(f"cp {src} {dst}", shell=True) + + images.append(src) + + (_, ext) = os.path.splitext(dst) + if ext == ".svg": + replace_svg_data(dst) + + return images + + +svg_doc_re = re.compile(r"\w*]+>\w*") + + +def replace_svg_data(img): + with open(img, 'r') as f: + data = f.read() + + data = svg_doc_re.sub("", data) + + with open(img, 'w') as f: + f.write(data) + + +def setup_fonts(): + subprocess.run(f"mkdir -p {font_dir}", shell=True) + for src in glob.glob("fonts/*.woff*"): + dst = os.path.join(oebps_dir, src) + subprocess.run(f"cp {src} {dst}", shell=True) + + fonts.append(src) + + +def post_id(link): + base = os.path.basename(link) + (name, ext) = os.path.splitext(base) + return name + + +def manifest_post_tag(post): + id = post_id(post) + href = id + ".xhtml" + return f'' + + +def spine_toc_post(post): + id = post_id(post) + return f'' + + +def img_id(img): + (name, _) = os.path.splitext(img) + return name.replace("/", "-") + + +def manifest_img_tag(img): + (_, ext) = os.path.splitext(img) + id = img_id(img) + + fallback = "" + if ext == ".png": + t = "png" + elif ext == ".svg": + t = "svg+xml" + fallback = id + "-fallback" + elif ext == ".jpg": + t = "jpeg" + fallback = id + "-fallback" + elif ext == ".gif": + t = "gif" + fallback = id + "-fallback" + else: + sys.exit("unknown image: " + ext + " " + img) + + if fallback: + fallback = f'fallback="{fallback}"' + + properties = "" + if id == "images-cover-front": + properties = 'properties="cover-image"' + + return f'' + + +def manifest_font_tag(font): + base = os.path.basename(font) + (id, _) = os.path.splitext(base) + return f'' + + +def setup_content_opf(): + with open(f"{ebook_files_dir}/content.opf", 'r') as f: + data = f.read() + + data = data.replace("◊UUID", uuid) + data = data.replace("◊DATE", + datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%SZ")) + + # ◊MANIFEST_POSTS_TAG + # + manifest_posts = ('\n' + ' ' * 8).join( + [manifest_post_tag(post) for post in toc]) + data = data.replace("◊MANIFEST_POSTS_TAG", manifest_posts) + + # ◊MANIFEST_IMG_TAG + # + manifest_imgs = ('\n' + ' ' * 8).join( + [manifest_img_tag(img) for img in images]) + data = data.replace("◊MANIFEST_IMG_TAG", manifest_imgs) + + # ◊MANIFEST_FONT_TAG + manifest_fonts = ('\n' + ' ' * 8).join( + [manifest_font_tag(font) for font in fonts]) + data = data.replace("◊MANIFEST_FONT_TAG", manifest_fonts) + + # ◊SPINE_TOC + # + spine_toc = ('\n' + ' ' * 8).join([spine_toc_post(post) for post in toc]) + data = data.replace("◊SPINE_TOC", spine_toc) + + with open(f"{oebps_dir}/content.opf", 'w') as f: + f.write(data) + + +def post_title(post): + return titles[post] + + +def setup_toc_ncx(): + with open(f"{ebook_files_dir}/toc.ncx", 'r') as f: + data = f.read() + + data = data.replace("◊UUID", uuid) + + with open(f"{oebps_dir}/toc.ncx", 'w') as f: + f.write(data) + + +def setup_css(): + subprocess.run(f"mkdir -p {css_dir}", shell=True) + subprocess.run( + f"sassc sass/main.scss --style compressed > {css_dir}/main.css", + shell=True) + + +def setup_toc(): + with open("toc.html", 'r') as f: + data = f.read() + + data = replace_post_data(data) + + with open(f"{oebps_dir}/toc.xhtml", 'w') as f: + f.write(data) + + +def setup_static_pages(): + subprocess.run(f"cp {ebook_files_dir}/*.xhtml {oebps_dir}", shell=True) + + +def setup_post_replacements(): + for post in toc: + (name, ext) = os.path.splitext(post) + dst = f'{name}.xhtml' + link_replace[post] = dst + + +def setup_posts(): + for post in toc: + setup_post(post) + + +def setup_post(post): + (name, ext) = os.path.splitext(post) + dst = f'{oebps_dir}/{name}.xhtml' + with open(post, 'r') as f: + data = f.read() + + data = replace_post_data(data) + + with open(dst, 'w') as f: + f.write(data) + + +def replace_post_data(data): + for link, new_link in link_replace.items(): + data = data.replace(link, new_link) + data = data.replace('Cheaper & faster', 'Cheaper & faster') + data = data.replace('UUID_COPY', uuid) + # https://github.com/Scripler/scripler/issues/430 + data = data.replace(' ', ' ') + + return data + + +def create_zip(): + subprocess.run('./zippify') + + +if __name__ == '__main__': + main() diff --git a/zippify b/zippify new file mode 100755 index 00000000..96a04b30 --- /dev/null +++ b/zippify @@ -0,0 +1,5 @@ +#!/bin/bash + +cd _ebook/ +zip -X0 why_cryptocurrencies.epub mimetype +zip -Xur9D why_cryptocurrencies.epub * From 12aae761a39c18b52c1aecb46421b96618d6e779 Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Tue, 14 Feb 2023 14:17:49 +0100 Subject: [PATCH 02/46] Reformat sass files --- sass/chapter.scss | 1437 +++++++++++++++++++++++---------------------- sass/main.scss | 15 +- 2 files changed, 729 insertions(+), 723 deletions(-) diff --git a/sass/chapter.scss b/sass/chapter.scss index 729f989f..57b7f0c4 100644 --- a/sass/chapter.scss +++ b/sass/chapter.scss @@ -2,103 +2,101 @@ $fullwidth: 1220px; $sidenote-float-width: 1280px; .chapter { - max-width: 800px; - //background-color: lightyellow; - flex: 1 1 auto; - margin: 0.5rem 1.2rem; + max-width: 800px; + //background-color: lightyellow; + flex: 1 1 auto; + margin: 0.5rem 1.2rem; } %fullwidth { - width: 100%; + width: 100%; } @media (min-width: $sidenote-float-width) { - %fullwidth { - width: $fullwidth; - } + %fullwidth { + width: $fullwidth; + } } - /* * Header */ .chapter > header { - h2 { - font-weight: normal; - font-style: italic; - font-size: 1rem; + h2 { + font-weight: normal; + font-style: italic; + font-size: 1rem; - margin-top: 0.4em; - margin-bottom: 0.8em; - } + margin-top: 0.4em; + margin-bottom: 0.8em; + } } .chapter > header > .date { - text-align: right; - font-size: 0.7rem; - margin-top: -0.2rem; - margin-bottom: 0.4rem; - @extend %sans-serif; - color: $body-font-color2; + text-align: right; + font-size: 0.7rem; + margin-top: -0.2rem; + margin-bottom: 0.4rem; + @extend %sans-serif; + color: $body-font-color2; - .published { - margin-right: 0.4rem; - } + .published { + margin-right: 0.4rem; + } } @media (min-width: $sidenote-float-width) { - .chapter > header > .date { - text-align: left; - - float: right; - margin-top: -3rem; - margin-right: -420px; - width: 380px; - .published { - display: block; - } - .update { - display: block; - } + .chapter > header > .date { + text-align: left; + + float: right; + margin-top: -3rem; + margin-right: -420px; + width: 380px; + .published { + display: block; + } + .update { + display: block; } + } } .where a { - text-decoration: none; - background: none; - text-shadow: none; + text-decoration: none; + background: none; + text-shadow: none; } .where a:hover { - text-decoration: underline; + text-decoration: underline; } .where { - font-size: 0.8rem; - @extend %sans-serif; - margin-bottom: 0.8rem; - color: $eth-dark-gray; + font-size: 0.8rem; + @extend %sans-serif; + margin-bottom: 0.8rem; + color: $eth-dark-gray; } .where .home { - @extend %sans-serif; + @extend %sans-serif; } .where .up { } .where .divider { - font-size: 0.65rem; - color: $eth-light-gray; + font-size: 0.65rem; + color: $eth-light-gray; } /* * Headers */ .chapter h2 > a:hover { - color: $body-font-color; + color: $body-font-color; } .chapter h3 > a:hover { - color: $body-font-color; + color: $body-font-color; } - /* * Lists */ @@ -106,922 +104,929 @@ $first-list-offset: -1.3rem; $list-p-margin: 0.6em; .chapter { - ul, ol { - list-style: none; - margin: 1rem 0 1rem 2em; - p { - margin-bottom: $list-p-margin; - } - } - ol { - counter-reset: foobar; - } - ol li, ul li { - margin-bottom: 0.4em; - font-size: 95%; - line-height: 1.35; - } - - ol > li::before { - @extend %sans-serif; - counter-increment: foobar; - content: counter(foobar); - color: $body-list-sym-color; - } - ul > li::before { - @extend %sans-serif; - //content: "⭑"; - //content: "~"; - //content: "≈"; - //content: "→"; - //content: "»"; - //content: "*"; - content: "•"; - //content: "†"; - color: $body-list-sym-color; - } - ul > li > p:first-child, ol > li > p:first-child { - // To avoid li signifier on a line of it's own - margin-top: $first-list-offset; - } - ul > li::before, ol > li::before { - // Avoid floats here as sidenotes may interfere - margin-left: -2em; - padding-right: 1.5em; - } + ul, + ol { + list-style: none; + margin: 1rem 0 1rem 2em; + p { + margin-bottom: $list-p-margin; + } + } + ol { + counter-reset: foobar; + } + ol li, + ul li { + margin-bottom: 0.4em; + font-size: 95%; + line-height: 1.35; + } - // Description lists - dl { - font-size: 95%; - line-height: 1.35; - margin-bottom: 1rem; - } - dl > dt { - font-weight: bold; - margin-left: 1em; - } - dl > dd { - margin-left: 2em; - margin-bottom: $list-p-margin; - } + ol > li::before { + @extend %sans-serif; + counter-increment: foobar; + content: counter(foobar); + color: $body-list-sym-color; + } + ul > li::before { + @extend %sans-serif; + //content: "⭑"; + //content: "~"; + //content: "≈"; + //content: "→"; + //content: "»"; + //content: "*"; + content: "•"; + //content: "†"; + color: $body-list-sym-color; + } + ul > li > p:first-child, + ol > li > p:first-child { + // To avoid li signifier on a line of it's own + margin-top: $first-list-offset; + } + ul > li::before, + ol > li::before { + // Avoid floats here as sidenotes may interfere + margin-left: -2em; + padding-right: 1.5em; + } + + // Description lists + dl { + font-size: 95%; + line-height: 1.35; + margin-bottom: 1rem; + } + dl > dt { + font-weight: bold; + margin-left: 1em; + } + dl > dd { + margin-left: 2em; + margin-bottom: $list-p-margin; + } } .chapter > .subnav { - margin-top: 1.5rem; - @extend %sans-serif; + margin-top: 1.5rem; + @extend %sans-serif; - .chapters { - font-size: 1.1rem; - font-weight: bold; - } + .chapters { + font-size: 1.1rem; + font-weight: bold; + } - ul { - list-style: none; - margin: 0; - } - ul > li { - font-size: 100%; - margin-left: 0.6rem; - margin-top: 0.3rem; - } - ul > li::before { - display: none; - } + ul { + list-style: none; + margin: 0; + } + ul > li { + font-size: 100%; + margin-left: 0.6rem; + margin-top: 0.3rem; + } + ul > li::before { + display: none; + } - a { - background: none; - text-shadow: none; - } - a:hover { - text-decoration: underline; - } + a { + background: none; + text-shadow: none; + } + a:hover { + text-decoration: underline; + } - .planned { - color: $planned-chapter-link; - } + .planned { + color: $planned-chapter-link; + } } - /* * Horizontal rules */ .chapter hr { - margin: 1em auto; + margin: 1em auto; - border: 0; - border-bottom: 1px solid $body-hr-color; + border: 0; + border-bottom: 1px solid $body-hr-color; } - /* * Quotes */ blockquote { - font-size: 95%; - line-height: 1.4; - margin: 2em; + font-size: 95%; + line-height: 1.4; + margin: 2em; } blockquote > footer { - font-size: 80%; - text-align: right; + font-size: 80%; + text-align: right; } blockquote > footer > cite { - font-style: italic; + font-style: italic; } blockquote .emphasis { - font-size: 80%; + font-size: 80%; } blockquote.center { - text-align: center; + text-align: center; } // Should we shut it down for small text? //blockquote > footer a:link { - //text-decoration: underline; - //background: none; - //text-shadow: none; +//text-decoration: underline; +//background: none; +//text-shadow: none; //} .epigraph { - margin: 2em 0; + margin: 2em 0; - blockquote { - font-size: 1rem; - font-style: italic; // Regular shouldn't be italic? - } - blockquote > footer { - font-style: normal; - } + blockquote { + font-size: 1rem; + font-style: italic; // Regular shouldn't be italic? + } + blockquote > footer { + font-style: normal; + } } - /* * Tables */ table { - @extend %sans-serif-tnum; - font-size: 0.95rem; - margin-bottom: 1rem; + @extend %sans-serif-tnum; + font-size: 0.95rem; + margin-bottom: 1rem; - display: block; - overflow-x: auto; - white-space: nowrap; + display: block; + overflow-x: auto; + white-space: nowrap; } -th, td { - text-align: left; - padding: 0.1em 1.5em 0.1em 0em; +th, +td { + text-align: left; + padding: 0.1em 1.5em 0.1em 0em; } // Had tons of trouble centering a table which could also // overflow on x. .centered { - display: flex; - justify-content: center; + display: flex; + justify-content: center; } - /* * Code */ -pre, code { - font-family: $code-font-family; - font-size: 0.83rem; - line-height: 1.45; +pre, +code { + font-family: $code-font-family; + font-size: 0.83rem; + line-height: 1.45; } code { - //background-color: tomato; + //background-color: tomato; } pre { - overflow-wrap: normal; - overflow: auto; + overflow-wrap: normal; + overflow: auto; - margin-bottom: 1rem; - padding: 0.4rem 0.6rem; + margin-bottom: 1rem; + padding: 0.4rem 0.6rem; } li pre { - margin-bottom: $list-p-margin; + margin-bottom: $list-p-margin; } .sidenote code { - font-size: 0.65rem; - line-height: 1.4; - //white-space: nowrap; + font-size: 0.65rem; + line-height: 1.4; + //white-space: nowrap; } - /* * Misc */ .def { - font-style: italic; + font-style: italic; } cite.book { - font-style: normal; + font-style: normal; } - /* * Side content */ .side-space { - // Serves to take up space. Inline content from the chapter is floated on top. - width: 420px; - //background-color: antiquewhite; - // Avoids swallowing clicks and interactions intended for wider images - visibility: hidden; + // Serves to take up space. Inline content from the chapter is floated on top. + width: 420px; + //background-color: antiquewhite; + // Avoids swallowing clicks and interactions intended for wider images + visibility: hidden; } .sidenote { - @extend %sans-serif; - font-size: 0.8rem; + @extend %sans-serif; + font-size: 0.8rem; } -.sidenote img, { - max-width: 100%; +.sidenote img { + max-width: 100%; } .sidenote .sidenote-number { - padding-right: 0.2rem; + padding-right: 0.2rem; } -.sidenote-number, .sidenote-label { - font-family: $sans-serif-font-family; - //vertical-align: super; - font-size: 0.7em; - display: inline-block; - //background-color: tomato; +.sidenote-number, +.sidenote-label { + font-family: $sans-serif-font-family; + //vertical-align: super; + font-size: 0.7em; + display: inline-block; + //background-color: tomato; } .sidenote .talking { - .row:before { - content: "–"; - padding-right: 0.3rem; - } + .row:before { + content: "–"; + padding-right: 0.3rem; + } } @media (max-width: $sidenote-float-width - 1) { - .sidenote { - display: block; - margin: 1em 4em 1.4em 4em !important; - - img { - display: block; - margin: 0 auto; - } - code { - max-width: 101%; - } - } - //.sidenote { background-color: lightblue; } -} -@media (min-width: $sidenote-float-width) { - .side-space { - display: block; - } - .sidenote { - float: right; - clear: right; - // Approximate adjustment for notes at the last line of a paragraph. - // Will get overridden by local styles. - margin-top: -2em; - margin-bottom: 4em; - margin-right: -420px; - width: 380px; - position: relative; - display: inline-block; - //background-color: moccasin; - } - blockquote .sidenote { - margin-right: -462px; + .sidenote { + display: block; + margin: 1em 4em 1.4em 4em !important; + + img { + display: block; + margin: 0 auto; } code { - max-width: 380px; + max-width: 101%; } - //.sidenote { background-color: pink; } + } + //.sidenote { background-color: lightblue; } +} +@media (min-width: $sidenote-float-width) { + .side-space { + display: block; + } + .sidenote { + float: right; + clear: right; + // Approximate adjustment for notes at the last line of a paragraph. + // Will get overridden by local styles. + margin-top: -2em; + margin-bottom: 4em; + margin-right: -420px; + width: 380px; + position: relative; + display: inline-block; + //background-color: moccasin; + } + blockquote .sidenote { + margin-right: -462px; + } + code { + max-width: 380px; + } + //.sidenote { background-color: pink; } } +.not-investment { + margin: 1em 0 !important; + font-size: 1.1rem; + font-weight: bold; + text-align: center; +} /* * Donations */ .donations { - margin: 1rem 0; - margin-left: 0.5rem; + margin: 1rem 0; + margin-left: 0.5rem; } .donation-label { - @extend %sans-serif; - font-size: 0.9rem; - font-weight: bold; - color: $body-font-color; - cursor: pointer; - text-decoration: underline; + @extend %sans-serif; + font-size: 0.9rem; + font-weight: bold; + color: $body-font-color; + cursor: pointer; + text-decoration: underline; } .donation-label:hover { - color: $body-link-hover-color; + color: $body-link-hover-color; } .donation-toggle { - display: none; + display: none; } .donation-content { - display: none; + display: none; } .donation-toggle:checked + .donation-content { - display: block; - text-align: center; - padding-top: 0.2rem; + display: block; + text-align: center; + padding-top: 0.2rem; } .donation-content .qr { - margin-right: 0.5em; + margin-right: 0.5em; } .donation-content .address { - font-family: $triplicate; - font-size: 0.9rem; - word-wrap: break-word; + font-family: $triplicate; + font-size: 0.9rem; + word-wrap: break-word; } - /* * Images */ a.img-wrapper:link { - background: none; - text-shadow: none; + background: none; + text-shadow: none; } a.img-wrapper:hover { - @include a-background(#333); + @include a-background(#333); } - /* * Figures */ figure { - margin-bottom: 1rem; - text-align: center; + margin-bottom: 1rem; + text-align: center; - img { - max-width: 100%; - } - > figcaption { - @extend %sans-serif; - font-size: 0.9rem; - } + img { + max-width: 100%; + } + > figcaption { + @extend %sans-serif; + font-size: 0.9rem; + } } figure.fullwidth { - img { - width: 100%; - } + img { + width: 100%; + } } figure.slim { - margin: 0; + margin: 0; } figcaption.margin { - @extend %sans-serif; + @extend %sans-serif; } @media (min-width: $sidenote-float-width) { - figure.fullwidth { - width: $fullwidth; - } - figcaption.margin { - font-size: 0.8rem; - float: right; - clear: right; - margin-right: -420px; - margin-bottom: 2rem; - width: 380px; - position: relative; - display: inline-block; - text-align: left; - } - // Override the above in a fullwidth image. Not sure how to avoid this? - figure.fullwidth > figcaption.margin { - font-size: 0.9rem; - float: none; - margin: 0; - position: static; - display: block; - text-align: center; - width: 100%; - } + figure.fullwidth { + width: $fullwidth; + } + figcaption.margin { + font-size: 0.8rem; + float: right; + clear: right; + margin-right: -420px; + margin-bottom: 2rem; + width: 380px; + position: relative; + display: inline-block; + text-align: left; + } + // Override the above in a fullwidth image. Not sure how to avoid this? + figure.fullwidth > figcaption.margin { + font-size: 0.9rem; + float: none; + margin: 0; + position: static; + display: block; + text-align: center; + width: 100%; + } } figure .sidenote { - text-align: left; + text-align: left; } - /* * Misc */ .whitepaper { - display: flex; - justify-content: center; - width: 100%; - margin-bottom: 1rem; + display: flex; + justify-content: center; + width: 100%; + margin-bottom: 1rem; - a { - @extend %sans-serif; - font-size: 1.05rem; - } + a { + @extend %sans-serif; + font-size: 1.05rem; + } } .todo { - @extend %sans-serif; - font-size: 0.8rem; - margin: 1rem 1rem; + @extend %sans-serif; + font-size: 0.8rem; + margin: 1rem 1rem; - .pre { - font-weight: bold; - } - .txt { - } + .pre { + font-weight: bold; + } + .txt { + } } .story { - padding: 1rem 0; - margin: 1.5rem 0; - border-top: 1px dashed $body-hr-color; - border-bottom: 1px dashed $body-hr-color; - - .talk:before { - content: "–"; - padding-right: 0.3rem; - } - .talk:not(:first-child) { - margin-top: 0.6rem; - } + padding: 1rem 0; + margin: 1.5rem 0; + border-top: 1px dashed $body-hr-color; + border-bottom: 1px dashed $body-hr-color; - // Avoid double spacing at the bottom. - p:last-of-type { - margin-bottom: 0; - } - // Avoid ugly spacing when sidenote is placed at the end. - .sidenote:last-child { - margin-bottom: 0 !important; - } + .talk:before { + content: "–"; + padding-right: 0.3rem; + } + .talk:not(:first-child) { + margin-top: 0.6rem; + } + + // Avoid double spacing at the bottom. + p:last-of-type { + margin-bottom: 0; + } + // Avoid ugly spacing when sidenote is placed at the end. + .sidenote:last-child { + margin-bottom: 0 !important; + } } .story-talking { } - -.appendix, .error { - max-width: 600px; +.appendix, +.error { + max-width: 600px; } .fullwidth { - @extend %fullwidth; + @extend %fullwidth; } table.crypto-eval { - th, td { - padding: 0.1em 0.6em; - } - td { - text-align: left; - } - td.ths { - font-weight: bold; - text-align: center; - } - td.tds { - font-weight: bold; - } - td.poor { - background-color: $poor; - text-align: center; - } - td.good { - background-color: $good; - text-align: center; - } - td.excellent { - background-color: $excellent; - text-align: center; - } + th, + td { + padding: 0.1em 0.6em; + } + td { + text-align: left; + } + td.ths { + font-weight: bold; + text-align: center; + } + td.tds { + font-weight: bold; + } + td.poor { + background-color: $poor; + text-align: center; + } + td.good { + background-color: $good; + text-align: center; + } + td.excellent { + background-color: $excellent; + text-align: center; + } } table.legal-moral { - th, td { - padding: 0.1em 1.0em 0.1em 0.5em; - } - td { - text-align: center; - } - td.ths { - font-weight: bold; - text-align: center; - } - td.tds { - font-weight: bold; - text-align: right; - } - - .good { - background-color: $legal-moral; - } - .moral-illegal { - background-color: $illegal-moral; - } - .immoral-legal { - background-color: $legal-immoral; - } - .bad { - background-color: $illegal-immoral; - } + th, + td { + padding: 0.1em 1em 0.1em 0.5em; + } + td { + text-align: center; + } + td.ths { + font-weight: bold; + text-align: center; + } + td.tds { + font-weight: bold; + text-align: right; + } + + .good { + background-color: $legal-moral; + } + .moral-illegal { + background-color: $illegal-moral; + } + .immoral-legal { + background-color: $legal-immoral; + } + .bad { + background-color: $illegal-immoral; + } } table.address-examples { - td.ths { - font-weight: bold; - } - td.tdc { - //font-weight: bold; - } + td.ths { + font-weight: bold; + } + td.tdc { + //font-weight: bold; + } } .sans { - @extend %sans-serif; + @extend %sans-serif; } .sans-tnum { - @extend %sans-serif-tnum; + @extend %sans-serif-tnum; } .strikethrough { - text-decoration: line-through; + text-decoration: line-through; } .chapter .subscribe { - max-width: 25em; + max-width: 25em; } .money-examples .example { - width: 100%; + width: 100%; + margin-bottom: 1em; + display: flex; + + .txt { + margin: 0 0.5em; + } + + img { + flex-shrink: 0; + align-self: center; + max-width: 10em; margin-bottom: 1em; + } + h3 { + margin-top: 0; + } + .header { + font-size: 1.1rem; + @extend %sans-serif; + line-height: 1; display: flex; - - .txt { - margin: 0 0.5em; - } - - img { - flex-shrink: 0; - align-self: center; - max-width: 10em; - margin-bottom: 1em; - } - h3 { - margin-top: 0; - } - .header { - font-size: 1.1rem; - @extend %sans-serif; - line-height: 1; - display: flex; - } - .date { - margin-left: 0.5rem; - } + } + .date { + margin-left: 0.5rem; + } } .inflation-examples .example { - //margin: 0 0.5em 1em 0.5em; - margin: 1em 0; - - h3 { - margin-top: 0; - } - .header { - font-size: 1.1rem; - @extend %sans-serif; - line-height: 1; - display: flex; - } - .date { - margin-left: 0.5rem; - } - .txt { - margin-left: 0.5rem; - } + //margin: 0 0.5em 1em 0.5em; + margin: 1em 0; + + h3 { + margin-top: 0; + } + .header { + font-size: 1.1rem; + @extend %sans-serif; + line-height: 1; + display: flex; + } + .date { + margin-left: 0.5rem; + } + .txt { + margin-left: 0.5rem; + } } .wikileaks { - padding-top: 1em; - margin-bottom: 1em; - //margin: 1.5em 0; - border-top: 1px dashed $body-hr-color; - border-bottom: 1px dashed $body-hr-color; + padding-top: 1em; + margin-bottom: 1em; + //margin: 1.5em 0; + border-top: 1px dashed $body-hr-color; + border-bottom: 1px dashed $body-hr-color; } .wikileaks .entry:not(:first-child) { - margin-top: 1.5em; + margin-top: 1.5em; } .wikileaks .entry { - width: 100%; + width: 100%; - h3 { - margin-top: 0; - } - > .header { - font-size: 1.1rem; - @extend %sans-serif; - line-height: 1; - display: flex; - flex-wrap: wrap; - //margin-bottom: 0.3rem; - } - > .header > h3 { - margin-right: 0.5rem; - margin-bottom: 0.3rem; - } - > .header > .date { - margin-bottom: 0.3rem; - } - - .caution { - margin-top: 0.5em; - margin-bottom: 0.8em; - margin-left: 1em; - font-size: 90%; - } + h3 { + margin-top: 0; + } + > .header { + font-size: 1.1rem; + @extend %sans-serif; + line-height: 1; + display: flex; + flex-wrap: wrap; + //margin-bottom: 0.3rem; + } + > .header > h3 { + margin-right: 0.5rem; + margin-bottom: 0.3rem; + } + > .header > .date { + margin-bottom: 0.3rem; + } + + .caution { + margin-top: 0.5em; + margin-bottom: 0.8em; + margin-left: 1em; + font-size: 90%; + } } .snowden-leaks > li.leak > .title { - margin-top: $first-list-offset; - margin-bottom: $list-p-margin; - font-weight: bold; + margin-top: $first-list-offset; + margin-bottom: $list-p-margin; + font-weight: bold; } .wikileaks li.leak { - margin-bottom: 2em; + margin-bottom: 2em; - > .title { - margin-top: $first-list-offset; - margin-bottom: $list-p-margin; - font-weight: bold; - } + > .title { + margin-top: $first-list-offset; + margin-bottom: $list-p-margin; + font-weight: bold; + } - .transcript { - margin: 1rem 0; - padding-left: 1rem; - font-size: 95%; - line-height: 1.4; - border-left: 1px solid $body-hr-color; - } + .transcript { + margin: 1rem 0; + padding-left: 1rem; + font-size: 95%; + line-height: 1.4; + border-left: 1px solid $body-hr-color; + } } .wikileaks .transcript-wrapper { - margin: 1.5em 0; - border-top: 1px dashed $body-hr-color; - border-bottom: 1px dashed $body-hr-color; + margin: 1.5em 0; + border-top: 1px dashed $body-hr-color; + border-bottom: 1px dashed $body-hr-color; } - .wikileaks .transcript > .row { - width: 100%; - display: flex; - justify-content: flex-start; - - > .time { - margin-right: 1.5rem; - flex: none; - } - > .txt { + width: 100%; + display: flex; + justify-content: flex-start; - } + > .time { + margin-right: 1.5rem; + flex: none; + } + > .txt { + } } - - @media only screen and (min-width: 521px) { - .money-examples .example:nth-child(even) { - justify-content: space-between; - img { - order: 9; - margin-right: 0; - } + .money-examples .example:nth-child(even) { + justify-content: space-between; + img { + order: 9; + margin-right: 0; } + } } @media only screen and (max-width: 520px) { - .money-examples .example { - flex-wrap: wrap; - justify-content: flex-start; - flex-direction: column; - - .txt { - width: 100%; - order: 1; - } - img { - order: 0; - } + .money-examples .example { + flex-wrap: wrap; + justify-content: flex-start; + flex-direction: column; + + .txt { + width: 100%; + order: 1; + } + img { + order: 0; } + } } ul > li.plus:before { - font-family: $code-font-family; - content: "+"; + font-family: $code-font-family; + content: "+"; } ul > li.neg:before { - font-family: $code-font-family; - content: "-"; + font-family: $code-font-family; + content: "-"; } ul.talking > li:before { - content: "–"; + content: "–"; } .qt-tab { - padding-left: 1.2rem; + padding-left: 1.2rem; } /* * Pretty video embedding */ .video-wrapper { - //@extend %media-offset-wrapper; - //margin: 1em 0; + //@extend %media-offset-wrapper; + //margin: 1em 0; } .video-container { - position: relative; - padding-bottom: 56.25%; - padding-top: 30px; - height: 0; - overflow: hidden; + position: relative; + padding-bottom: 56.25%; + padding-top: 30px; + height: 0; + overflow: hidden; } -.video-container iframe, .video-container object, .video-container embed { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; +.video-container iframe, +.video-container object, +.video-container embed { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; } table.address-message { - font-family: $code-font-family; - font-size: 0.71rem; - line-height: 1.45; - //font-style: italic; - .msg-char { - padding: 0 0.2em; - font-weight: bold; - } + font-family: $code-font-family; + font-size: 0.71rem; + line-height: 1.45; + //font-style: italic; + .msg-char { + padding: 0 0.2em; + font-weight: bold; + } } - /* * Legacy HN */ .hn { - font-size: 0.8rem; - font-family: Verdana; + font-size: 0.8rem; + font-family: Verdana; + color: #828282; + background-color: #f6f6ef; + margin: 1rem; + overflow-x: hidden; + white-space: nowrap; + + a:link { + text-shadow: none; + background: none; + color: #000; + } + a:visited { color: #828282; - background-color: #f6f6ef; - margin: 1rem; - overflow-x: hidden; - white-space: nowrap; - - a:link { - text-shadow: none; - background: none; - color: #000; - } - a:visited { - color:#828282; - } + } } .hn table { - font-size: 0.8rem; - font-family: Verdana; - padding: 0 0 0.2rem 0.4rem; + font-size: 0.8rem; + font-family: Verdana; + padding: 0 0 0.2rem 0.4rem; + margin: 0; + overflow-x: hidden; + white-space: nowrap; + + th, + td { margin: 0; - overflow-x: hidden; - white-space: nowrap; - - th, td { - margin: 0; - padding: 0; - } - .title { - font-size: 1em; - } - .comhead { - font-size: 0.8em; - } - .subtext { - font-size: 0.7em; - } - .comhead a:link, .subtext a:link, .subtext a:visited { - color:#828282; - } - .subtext a:hover, .comhead a:hover { - text-decoration: underline; - } - .arrow { - font-size: 0.65em; - color: #b3b3b3; - margin-left: 0.4em; - margin-right: 0.3em; - position: relative; - top: -0.12em; - cursor: pointer; - } + padding: 0; + } + .title { + font-size: 1em; + } + .comhead { + font-size: 0.8em; + } + .subtext { + font-size: 0.7em; + } + .comhead a:link, + .subtext a:link, + .subtext a:visited { + color: #828282; + } + .subtext a:hover, + .comhead a:hover { + text-decoration: underline; + } + .arrow { + font-size: 0.65em; + color: #b3b3b3; + margin-left: 0.4em; + margin-right: 0.3em; + position: relative; + top: -0.12em; + cursor: pointer; + } } .hn .header { - font-size: 0.8rem; - font-family: Verdana; - background-color: #ff6600; - margin: 0; - padding: 0; - margin-bottom: 0.4rem; - height: 1.3rem; - text-align: left; - + font-size: 0.8rem; + font-family: Verdana; + background-color: #ff6600; + margin: 0; + padding: 0; + margin-bottom: 0.4rem; + height: 1.3rem; + text-align: left; + + display: flex; + justify-content: flex-start; + align-items: center; + + .logo a { display: flex; - justify-content: flex-start; + justify-content: center; align-items: center; - - .logo a { - display: flex; - justify-content: center; - align-items: center; - } - .logo a img { - border: 1px #fff solid; - max-width: 20px; - max-height: 20px; - margin: 0 0.2rem; - } - .pagetop { - font-size: 1em; - color:#222222; - } - .pagetop a:visited { - color:#000000; - } - .hn-title { - font-weight: bold; - margin-right: 0.8em; - } + } + .logo a img { + border: 1px #fff solid; + max-width: 20px; + max-height: 20px; + margin: 0 0.2rem; + } + .pagetop { + font-size: 1em; + color: #222222; + } + .pagetop a:visited { + color: #000000; + } + .hn-title { + font-weight: bold; + margin-right: 0.8em; + } } .fractional-table-ex { - @extend %sans-serif-tnum; - font-size: 0.95rem; - margin: 1em 0 1.2em 0; + @extend %sans-serif-tnum; + font-size: 0.95rem; + margin: 1em 0 1.2em 0; - .row { - width: 100%; - display: flex; - flex-wrap: nowrap; - justify-content: center; - } - .header { - font-weight: bold; - } - .cell { - width: 5em; - text-align: center; - margin-right: 1.5em; - } + .row { + width: 100%; + display: flex; + flex-wrap: nowrap; + justify-content: center; + } + .header { + font-weight: bold; + } + .cell { + width: 5em; + text-align: center; + margin-right: 1.5em; + } } .money-visualization { - margin: 1em 0; + margin: 1em 0; } .money-visualization .block { - width: 100%; - display: flex; - justify-content: center; - flex-wrap: wrap; + width: 100%; + display: flex; + justify-content: center; + flex-wrap: wrap; - .title { - @extend %sans-serif; - font-size: 1rem; - width: 100%; - text-align: center; - } - .wrapper { - width: 100%; - text-align: center; - overflow-x: auto; - } - .wrapper.small { - margin-top: -0.4rem; - margin-bottom: -0.4rem; - } + .title { + @extend %sans-serif; + font-size: 1rem; + width: 100%; + text-align: center; + } + .wrapper { + width: 100%; + text-align: center; + overflow-x: auto; + } + .wrapper.small { + margin-top: -0.4rem; + margin-bottom: -0.4rem; + } } .money-vis-small { - background: url(/images/markets/small.png) left top no-repeat; - width: 10px; - height: 10px; - display: inline-block; + background: url(/images/markets/small.png) left top no-repeat; + width: 10px; + height: 10px; + display: inline-block; } .money-vis-big { - background: url(/images/markets/big.png) left top no-repeat; - width: 12px; - height: 12px; - display: inline-block; + background: url(/images/markets/big.png) left top no-repeat; + width: 12px; + height: 12px; + display: inline-block; } /* @@ -1077,49 +1082,51 @@ table.address-message { */ .hidden-label { - @include a-background(#333); - cursor: pointer; + @include a-background(#333); + cursor: pointer; } .hidden-label:hover { - color: $body-link-hover-color; - background: none; - shadow: none; + color: $body-link-hover-color; + background: none; + shadow: none; } .hidden-toggle { - display: none; + display: none; } .hidden-content { - display: none; - @extend %sans-serif; - font-size: 0.8rem; + display: none; + @extend %sans-serif; + font-size: 0.8rem; } .hidden-toggle:checked + .hidden-content { - display: block; - text-align: center; - padding-top: 0.2rem; + display: block; + text-align: center; + padding-top: 0.2rem; } -.flex-20, .flex-25, .flex-50, .flex-33 { - display: flex; - flex-wrap: wrap; - justify-content: center; - align-items: center; +.flex-20, +.flex-25, +.flex-50, +.flex-33 { + display: flex; + flex-wrap: wrap; + justify-content: center; + align-items: center; - img { - padding: 0.2em; - } + img { + padding: 0.2em; + } } .flex-20 img { - max-width: 20%; + max-width: 20%; } .flex-25 img { - max-width: 25%; + max-width: 25%; } .flex-33 img { - max-width: 33%; + max-width: 33%; } .flex-50 img { - max-width: 50%; + max-width: 50%; } - diff --git a/sass/main.scss b/sass/main.scss index 4cd1d942..f862f71f 100644 --- a/sass/main.scss +++ b/sass/main.scss @@ -1,13 +1,12 @@ // Preparations -@import 'fonts'; -@import 'colors'; +@import "fonts"; +@import "colors"; // Site wide -@import 'global'; -@import 'code-highlight'; +@import "global"; +@import "code-highlight"; // Pages -@import 'homepage'; -@import 'chapter'; -@import 'landing'; - +@import "homepage"; +@import "chapter"; +//@import 'landing'; From 06e4301e6a66b8ecd3f47ed870c9cae6a01876fe Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Tue, 14 Feb 2023 14:19:10 +0100 Subject: [PATCH 03/46] Fix basic markup generation --- chapter.html.p | 32 +++++++++++++++----------------- landing.html.p | 5 ++--- toc-template.html.p | 32 ++++++++------------------------ 3 files changed, 25 insertions(+), 44 deletions(-) diff --git a/chapter.html.p b/chapter.html.p index 61615336..18ae047b 100644 --- a/chapter.html.p +++ b/chapter.html.p @@ -46,21 +46,20 @@ (->html (make-link #:title title (string-append "/" (symbol->string page)) txt))) - + ◊|head-title| - - + - - + +
-
-
-

This is a book that tries to explain the utility of cryptocurrencies in a beginner-friendly manner.

+ ◊;
+ ◊;
+ ◊;

This is a book that tries to explain the utility of cryptocurrencies in a beginner-friendly manner.

-

Check out the print or ebook!

-
-
+ ◊;

Check out the print or ebook!

+ ◊;
+ ◊;
- + ◊; diff --git a/landing.html.p b/landing.html.p index 95bd7d97..03b3e935 100644 --- a/landing.html.p +++ b/landing.html.p @@ -1,11 +1,10 @@ ◊(local-require pollen/tag) - + ◊|main-title| - - + diff --git a/toc-template.html.p b/toc-template.html.p index 985e10ae..66040aa5 100644 --- a/toc-template.html.p +++ b/toc-template.html.p @@ -1,33 +1,17 @@ ◊(local-require pollen/tag) - + - ◊|main-title| - - + Table of Contents + - - - - + + + + -
-
-

◊|main-title|

-

◊|subtitle|

-
- - ◊(->html doc #:splice #t) -
- - + ◊(->html doc #:splice #t) From cb5775dbd9e7c90db6fc3a163fb6e1cf8e9164aa Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Tue, 14 Feb 2023 14:20:23 +0100 Subject: [PATCH 04/46] Use image of HN instead of funky html --- timestamping_service.html.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/timestamping_service.html.pm b/timestamping_service.html.pm index f15fd592..bac4c664 100644 --- a/timestamping_service.html.pm +++ b/timestamping_service.html.pm @@ -55,7 +55,8 @@ Let's travel back in time and look at the site ◊link[hn]{Hacker News}, a tech Interestingly enough Hacker News is full of people extremely skeptical of cryptocurrencies, who often comment that cryptocurrencies don't have a single legal use-case. This skepticism and misunderstanding, even from highly technical people, was one of the reasons I started writing this book. } -◊hn-html{ +◊img[#:src "images/hn-html.png" + #:alt "Hacker News on Mars 1st, 2011."]{ The top three stories on ◊link[hn-wayback-ref]{Hacker News on Mars 1st, 2011} according to the Wayback Machine. I tried to reproduce the site appearance, but it's not pixel perfect. } From 6db3de950e99b3c0500e9cc0a0e3f914aabbcc59 Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Tue, 14 Feb 2023 14:23:06 +0100 Subject: [PATCH 05/46] TOC generation tweaks --- rkt/decode.rkt | 2 +- rkt/index.rkt | 16 +++++++++++++--- rkt/links.rkt | 2 +- rkt/tags.rkt | 1 + rkt/toc.rkt | 5 ++--- 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/rkt/decode.rkt b/rkt/decode.rkt index 95e03fd0..97f5fd9c 100644 --- a/rkt/decode.rkt +++ b/rkt/decode.rkt @@ -10,5 +10,5 @@ (decode-elements args #:txexpr-elements-proc decode-paragraphs #:string-proc string-proc - #:exclude-tags `(figure pre))) + #:exclude-tags `(figure pre nav))) diff --git a/rkt/index.rkt b/rkt/index.rkt index 55cb8716..824ed828 100644 --- a/rkt/index.rkt +++ b/rkt/index.rkt @@ -36,7 +36,7 @@ (define (make-subnav sub) (if sub - `(ul + `(ol ,@(for/list ([child (in-list sub)]) `(li ,(make-entry child)))) "")) @@ -46,10 +46,20 @@ (h1 ,(make-entry (node page))) ,(make-subnav (children page)))) +(define (page-section-toc page) + ;`((span ((class "section")) ,(make-entry (node page))) + ;,(make-subnav (children page)))) + `(,(make-entry (node page)) + ,(make-subnav (children page)))) + ;; Make a table of content, used on the homepage or dedicated toc page. (define (make-toc content) - `(nav ((class "toc")) - ,@(map page-toc content))) + `(nav ((class "toc") (epub:type "toc")) + (h1 "Contents") + (ol + ,@(map (λ (x) + `(li ,@(page-section-toc x))) + content)))) ;; Locate entry in table of content. (define (toc-entry page) diff --git a/rkt/links.rkt b/rkt/links.rkt index b44be298..d3e6a2ab 100644 --- a/rkt/links.rkt +++ b/rkt/links.rkt @@ -7,7 +7,7 @@ ;; Site links (define root-url "https://whycryptocurrencies.com") -(define toc-url `("/" "Table of contents")) +(define toc-url `("/toc.xhtml" "Table of contents")) (define feed-url `("/feed.xml" diff --git a/rkt/tags.rkt b/rkt/tags.rkt index b4699389..b87fd33a 100644 --- a/rkt/tags.rkt +++ b/rkt/tags.rkt @@ -98,6 +98,7 @@ (string=? "/" url) (string=? "/feed.xml" url) (string=? "/toc.html" url) + (string=? "/toc.xhtml" url) (regexp-match #rx"^mailto:" url) (ch-ref? url) (file-ref? url) diff --git a/rkt/toc.rkt b/rkt/toc.rkt index b60c7705..28bce5a2 100644 --- a/rkt/toc.rkt +++ b/rkt/toc.rkt @@ -8,8 +8,8 @@ `(eli5.html (about_the_book.html acknowledgements.html - how_to_use.html - free.html + ;how_to_use.html + ;free.html about_me.html) (what_is_a_cryptocurrency.html properties_of_a_cryptocurrency.html @@ -97,4 +97,3 @@ ,@(transform-list pt))) (define toc-pagetree (tree-to-pagetree toc)) - From f8e2ceb9709159bab830a0810bfd2902f0880666 Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Tue, 14 Feb 2023 14:24:59 +0100 Subject: [PATCH 06/46] Set thead as a block to prevent random p insertions --- pollen.rkt | 2 +- rkt/tags.rkt | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/pollen.rkt b/pollen.rkt index 264f4955..6210c4e7 100644 --- a/pollen.rkt +++ b/pollen.rkt @@ -34,7 +34,7 @@ (provide (all-defined-out)) - (define block-tags (append '(img table tbody tr dt dd dl) default-block-tags)) + (define block-tags (append '(img table thead tbody tr dt dd dl) default-block-tags)) ;; Use our own publish script instead... ;; Ignore stuff during 'raco pollen publish' diff --git a/rkt/tags.rkt b/rkt/tags.rkt index b87fd33a..3640c4d3 100644 --- a/rkt/tags.rkt +++ b/rkt/tags.rkt @@ -223,6 +223,19 @@ `() `((class ,(string-join classes))))) +(module+ test + (require rackunit) + (check-equal? (stable + "Person Swedish krona" "\n" "Sneaky Steve 7 000 SEK" "\n" "Honest Harry 1 000 SEK") + '(div + ((class "centered")) + (table + () + (thead (tr (th "Person") (th "Swedish krona"))) + (tbody + (tr (td "Sneaky Steve") (td "7 000 SEK")) + (tr (td "Honest Harry") (td "1 000 SEK"))))) + )) (define (epigraph . txt) `(div ((class "epigraph")) From ea3f7576264f0ed9a3a42cd87642621ffedacd92 Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Tue, 14 Feb 2023 14:25:16 +0100 Subject: [PATCH 07/46] No center tag in xhtml --- about_the_book.html.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/about_the_book.html.pm b/about_the_book.html.pm index 341052d9..ad98549b 100644 --- a/about_the_book.html.pm +++ b/about_the_book.html.pm @@ -103,8 +103,8 @@ A problem-centric view is great for an engineer or a problem solver, but it also Instead of putting on blinders and getting stuck at these problems---which I believe can be addressed---we'll focus on the potential cryptocurrencies have. Only with this vantage point can we see if the problems are worth working on, or if we instead should scrap the whole idea. -◊center{ - ◊strong[#:style "font-size: 1.1rem"]{And of course, none of this is investment advice.} +◊div[#:class "not-investment"]{ + And of course, none of this is investment advice. } Well, the only advice I'll give is to understand what you're investing in, and my hope is that this book can help with that. From d5c4467a637e6df35009305492d74da82f7d9e25 Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Tue, 14 Feb 2023 14:25:44 +0100 Subject: [PATCH 08/46] Don't keep % in href names --- rkt/refs.rkt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rkt/refs.rkt b/rkt/refs.rkt index b18ad176..13174756 100644 --- a/rkt/refs.rkt +++ b/rkt/refs.rkt @@ -73,5 +73,7 @@ (regexp-match #rx"^mailto:" x)))) (define (to-name x) - (string-replace (string-downcase x) " " "-")) + (string-replace + (string-replace (string-downcase x) " " "-") + "%" "")) From e6d787a0a4c21b779027c83c08c640e67b7ea06d Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Tue, 14 Feb 2023 14:26:22 +0100 Subject: [PATCH 09/46] Add id attribute to a (in addition to name) --- rkt/tags.rkt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/rkt/tags.rkt b/rkt/tags.rkt index 3640c4d3..4daa30d7 100644 --- a/rkt/tags.rkt +++ b/rkt/tags.rkt @@ -166,12 +166,14 @@ (define (subhead x) + (define id (to-name x)) `(h2 - (a [[name ,(to-name x)]] ,x))) + (a [[name ,id] [id ,id]] ,x))) (define (subhead3 x) + (define id (to-name x)) `(h3 - (a [[name ,(to-name x)]] ,x))) + (a [[name ,id] [id ,id]] ,x))) (define (li-plus . txt) `(li ((class "plus")) ,@txt)) From 3725c860c6cd5f76d868bb3f1fe8815844c8aa51 Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Tue, 14 Feb 2023 14:26:45 +0100 Subject: [PATCH 10/46] Minor link updates --- rkt/layout.rkt | 30 +++++++++++++++--------------- rkt/links.rkt | 10 +++++----- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/rkt/layout.rkt b/rkt/layout.rkt index 94f2b3d4..58bb936d 100644 --- a/rkt/layout.rkt +++ b/rkt/layout.rkt @@ -26,21 +26,21 @@ (value "Subscribe"))) )) -(define follow-section - `(section((class "follow")) - (div ((class "wip")) - "Here are some options f you want to keep up to date:") - ,subscription-form - (div ((class "links")) - "Subscribe to the " ,(link feed-url "feed") - ", see the source on " ,(link source-code "Github") - " or " ,(link mailto "contact me") - ".") - (div ((class "donate")) - "If you appreciate this free book please consider " - ,(link donations "donating") - ".") - )) +; (define follow-section +; `(section((class "follow")) +; (div ((class "wip")) +; "Here are some options f you want to keep up to date:") +; ,subscription-form +; (div ((class "links")) +; "Subscribe to the " ,(link feed-url "feed") +; ", see the source on " ,(link source-code "Github") +; " or " ,(link mailto "contact me") +; ".") +; (div ((class "donate")) +; "If you appreciate this free book please consider " +; ,(link donations "donating") +; ".") +; )) (define (abs-url url) (format "~a/~a" root-url url)) diff --git a/rkt/links.rkt b/rkt/links.rkt index d3e6a2ab..0de82227 100644 --- a/rkt/links.rkt +++ b/rkt/links.rkt @@ -187,10 +187,10 @@ (ch-ref 'what_is_a_cryptocurrency.html "What is a cryptocurrency?")) -(define donations - (ch-ref - 'free.html #:ref "donations-is-a-perfect-use-for-cryptocurrencies" - "Donations is a perfect use for cryptocurrencies")) +; (define donations +; (ch-ref +; 'free.html #:ref "donations-is-a-perfect-use-for-cryptocurrencies" +; "Donations is a perfect use for cryptocurrencies")) (define properties_of_a_cryptocurrency (ch-ref @@ -416,7 +416,7 @@ "Stackexchange: How is the whitepaper decoded from the blockchain")) (define bitcoin-pdf - `("/files/bitcoin.pdf" + `("https://whycryptocurrencies.com/files/bitcoin.pdf" "Bitcoin: A Peer-to-Peer Electronic Cash System")) (define electroncash From e1c7cf2f5bf8915e76b66db18128654ed10f358c Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Tue, 14 Feb 2023 14:26:56 +0100 Subject: [PATCH 11/46] Missing image and script --- images/hn-html.png | 3 +++ regen-and-check-ebook | 6 ++++++ 2 files changed, 9 insertions(+) create mode 100644 images/hn-html.png create mode 100755 regen-and-check-ebook diff --git a/images/hn-html.png b/images/hn-html.png new file mode 100644 index 00000000..8f8140f0 --- /dev/null +++ b/images/hn-html.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8ce9f307f17ce9ff9f7c8fc4e1d8227981782bf81cb4c359d4241638d474d8d1 +size 34003 diff --git a/regen-and-check-ebook b/regen-and-check-ebook new file mode 100755 index 00000000..6b8fb122 --- /dev/null +++ b/regen-and-check-ebook @@ -0,0 +1,6 @@ +#!/bin/bash + +./rebuild +./ebookify +epub-check ./_ebook/why_cryptocurrencies.epub + From 0b52a0145ee654a81f0bc01f5aefbc20cec07c8e Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Fri, 17 Feb 2023 08:56:36 +0100 Subject: [PATCH 12/46] Move out sidenote defs from li --- about_the_book.html.pm | 4 +++- are_cryptocurrencies_money.html.pm | 21 +++++++++++++++------ how_do_cryptocurrencies_work.html.pm | 4 +++- uncensorable_donations.html.pm | 8 +++++--- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/about_the_book.html.pm b/about_the_book.html.pm index ad98549b..d57a8803 100644 --- a/about_the_book.html.pm +++ b/about_the_book.html.pm @@ -64,13 +64,15 @@ I must admit I'm also being selfish---writing a book is on my bucket list. This book tries to describe what value cryptocurrencies have using several examples. In particular I'll argue that: ◊ol{ - ◊li{Cryptocurrencies aren't just scams.◊mn{scams} ◊note-pos{scams}} + ◊li{Cryptocurrencies aren't just scams.◊mn{scams}} ◊li{It's more than just a speculative asset.} ◊li{They do many things better than any alternative.} ◊li{There are legal use cases.} ◊li{They have valuable use cases.} } +◊note-pos{scams} + Of course, everything new brings positive and negative aspects with it. It's up to you to decide where on the global spectrum of good and bad cryptocurrencies lie. diff --git a/are_cryptocurrencies_money.html.pm b/are_cryptocurrencies_money.html.pm index e5aa5664..2b8c2cb9 100644 --- a/are_cryptocurrencies_money.html.pm +++ b/are_cryptocurrencies_money.html.pm @@ -27,7 +27,7 @@ To decide how well cryptocurrencies can function as money, we'll take a look at ◊ol{ ◊li{◊strong{Acceptable} - Nobody's excluded from using cryptocurrencies---they're open to everyone by design. The drawback is that you need a device with internet connection.◊mn{crypto-acceptable} ◊note-pos{crypto-acceptable} + Nobody's excluded from using cryptocurrencies---they're open to everyone by design. The drawback is that you need a device with internet connection.◊mn{crypto-acceptable} } ◊li{◊strong{Divisible} @@ -35,7 +35,7 @@ To decide how well cryptocurrencies can function as money, we'll take a look at } ◊li{◊strong{Durable} - Coins can be used an infinite amount of times. The only drawback is keeping your private key secure, so you don't lose your coins.◊mn{backups} ◊note-pos{backups} + Coins can be used an infinite amount of times. The only drawback is keeping your private key secure, so you don't lose your coins.◊mn{backups} } ◊li{◊strong{Fungible & Uniform} @@ -59,6 +59,9 @@ To decide how well cryptocurrencies can function as money, we'll take a look at } } +◊note-pos{crypto-acceptable} +◊note-pos{backups} + All in all cryptocurrencies fulfil the properties excellently. Cryptocurrencies can also be considered to be ◊def[sound-money]{sound money}---the value is entirely market driven and there's no manipulation of the supply.◊mn{backed} @@ -96,19 +99,19 @@ This is a table of how I think cryptocurrencies compare to other forms of money. I know this might be controversial, so let me motivate some of the entries: ◊ol{ - ◊li{Digital fiat gets a poor score on ◊strong{acceptable} because it requires a bank account to use. This ◊link[for_the_unbanked]{isn't something everyone can get} as banks have the right to ◊link[undesirable_businesses]{reject you if they want}.◊mn{acceptable} ◊note-pos{acceptable} + ◊li{Digital fiat gets a poor score on ◊strong{acceptable} because it requires a bank account to use. This ◊link[for_the_unbanked]{isn't something everyone can get} as banks have the right to ◊link[undesirable_businesses]{reject you if they want}.◊mn{acceptable} } ◊li{Digital money is inherently easier to ◊strong{divide} than physical variants. You can always send an exact amount without having to mix and match change.} - ◊li{Paper notes can easily wear out or burn up. While cryptocurrencies cannot themselves burn up or deteriorate, the security backups and your phone can. Therefore they score lower than gold on ◊strong{durability}, which is near indestructible.◊mn{durability} ◊note-pos{durability}} + ◊li{Paper notes can easily wear out or burn up. While cryptocurrencies cannot themselves burn up or deteriorate, the security backups and your phone can. Therefore they score lower than gold on ◊strong{durability}, which is near indestructible.◊mn{durability}} - ◊li{I see no major problems with ◊strong{fungibility} or ◊strong{uniformity}.◊mn{again-monero} ◊note-pos{again-monero}} + ◊li{I see no major problems with ◊strong{fungibility} or ◊strong{uniformity}.◊mn{again-monero}} ◊li{Both digital and physical fiat gets a poor score on ◊strong{limited supply}. Per the discussion in ◊link[prev-chapter]{the previous chapter} fiat money is unsound. } - ◊li{Cryptocurrencies are simply much more ◊strong{portable} than the other options. Carrying large amounts in cash or gold is cumbersome and digital fiat isn't easy to move across borders.◊mn{borders} ◊note-pos{borders}} + ◊li{Cryptocurrencies are simply much more ◊strong{portable} than the other options. Carrying large amounts in cash or gold is cumbersome and digital fiat isn't easy to move across borders.◊mn{borders}} ◊li{While it's possible to check for fake cash and gold coins, it requires expertise and certain tools. Therefore they get a lower ◊strong{recognizable} score. } @@ -118,10 +121,16 @@ I know this might be controversial, so let me motivate some of the entries: You could argue that because you need a device with internet access, cryptocurrencies should get a lower score on ◊em{acceptable}. But you could also argue that having to transact in person is another drawback, and to me they cancel out. } +◊note-pos{durability} + ◊ndef["durability"]{ The definition of ◊em{durability} is only concerned with reuse, where cryptocurrencies score excellently. I wanted to include the storage drawback that didn't fit anywhere else. } +◊note-pos{again-monero} + +◊note-pos{borders} + Even if you disagree about certain choices, it's hard to deny that cryptocurrencies come out of the comparison pretty well. Of course, this doesn't give the whole picture. There are other significant differences, for example: ◊ul{ diff --git a/how_do_cryptocurrencies_work.html.pm b/how_do_cryptocurrencies_work.html.pm index 81768f4b..1c1f04b3 100644 --- a/how_do_cryptocurrencies_work.html.pm +++ b/how_do_cryptocurrencies_work.html.pm @@ -504,10 +504,12 @@ A 51% can be detected and there can be severe negative consequences: ◊ul{ ◊li{The Bitcoin price might crash.} ◊li{Exchanges might blacklist the stolen funds.} - ◊li{The community might change POW and make all mining rigs worthless.◊mn{monero-POW} ◊note-pos{monero-POW}} + ◊li{The community might change POW and make all mining rigs worthless.◊mn{monero-POW}} ◊li{It's hard to keep warehouses full of mining rigs of that scale a secret---there's a big risk to get caught.} } +◊note-pos{monero-POW} + Bitcoin miners are rewarded in bitcoin and they also can't be spent until after 100 blocks---roughly 16 hours. Executing a 51% attack that crashes the price would directly affect the rewards. If the community goes for the nuclear option and change POW, the massive initial investment into mining equipment might be lost. These risks needs to weighed against what profits a 51% attack could generate. Maybe exchanges could get defrauded for $100 million (roughly a 5% return on investment)? A 51% miner would make that back in about one week---risk-free.◊mn{btg2} diff --git a/uncensorable_donations.html.pm b/uncensorable_donations.html.pm index b1e5980b..d7b218f4 100644 --- a/uncensorable_donations.html.pm +++ b/uncensorable_donations.html.pm @@ -308,10 +308,10 @@ This is ◊strong{not} a glorification of WikiLeaks---they have ◊link[wikileak 66 thousand innocent people dead in six years. That's like 22 World Trade center attacks (where 2,977 people died)---more than three a year. Or 31 innocent people dead every day during the six years. } - ◊note-pos[#:top -7]{wtc} - } + ◊note-pos[#:top -7]{wtc} + Countless numbers of civilians killed---while soldiers are laughing---and systematic cover-ups to hide it all.◊mn{purpose} ◊ndef["purpose"]{ @@ -828,9 +828,11 @@ Of course, covering up or rationalizing events isn't a U.S. only phenomena. Here It was even forbidden to talk about them negatively. } - ◊li{How the Soviet Union tried to cover up the ◊link[chernobyl-accident]{Chernobyl nuclear disaster}.◊mn{chernobyl-TV} ◊note-pos{chernobyl-TV}} + ◊li{How the Soviet Union tried to cover up the ◊link[chernobyl-accident]{Chernobyl nuclear disaster}.◊mn{chernobyl-TV}} } +◊note-pos{chernobyl-TV} + ◊ndef["dan-hitler"]{ Dan Carlin, creator of the excellent ◊link[hardcore-history]{Hardcore History} podcast, brought up an interesting question: From ec2ad507f6c791f05f2b149ac7532d78393681f1 Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Fri, 17 Feb 2023 09:14:46 +0100 Subject: [PATCH 13/46] Proper
in table --- darknet_markets.html.pm | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/darknet_markets.html.pm b/darknet_markets.html.pm index 69408774..68f60350 100644 --- a/darknet_markets.html.pm +++ b/darknet_markets.html.pm @@ -38,16 +38,13 @@ There's a concept we need to have in mind while looking at darknet markets: some Here's a table to illustrate the problem: +◊(define sbr + `(br)) + ◊table-body[#:class "legal-moral"]{ - ◊tr{◊td{} ◊ths{Legal} ◊ths{Illegal}} - ◊tr{◊tds{Moral} ◊good{Self defense - Free speech} - ◊mo-il{Some types of sex - Starving child steals food}} - ◊tr{◊tds{Immoral} ◊im-le{Mass surveillance - Civil asset forfeiture} - ◊bad{Slavery - Murder}} + ◊tr{◊td{} ◊ths{Legal} ◊ths{Illegal}} + ◊tr{◊tds{Moral} ◊good{Self defense◊|sbr|Free speech} ◊mo-il{Some types of sex◊|sbr|Starving child steals food}} + ◊tr{◊tds{Immoral} ◊im-le{Mass surveillance◊|sbr|Civil asset forfeiture} ◊bad{Slavery◊|sbr|Murder}} } It's actually quite hard to classify things as legal or illegal and moral or immoral; they both change depending on the country, the time period and who you ask. For instance most would agree that slavery is immoral and should be illegal, but it was legal and viewed as normal for thousands of years. Similarly today in the western world we take free speech for granted, but that's not the case in all countries. From 16a98bb15efae91a3886c7456bd3d83f9b4fac45 Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Fri, 17 Feb 2023 09:15:09 +0100 Subject: [PATCH 14/46] Remove image links --- rkt/tags.rkt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/rkt/tags.rkt b/rkt/tags.rkt index 4daa30d7..9c388934 100644 --- a/rkt/tags.rkt +++ b/rkt/tags.rkt @@ -395,10 +395,12 @@ (define (raw-img #:src src #:link [link #f] #:alt alt) (define img `(img ((src ,(~a src)) (alt ,alt)))) - (if link - `(a ((href ,src) (target "_blank") (class "img-wrapper")) - ,img) - img)) + img) + ; Image links not supported in ebooks? + ; (if link + ; `(a ((href ,src) (target "_blank") (class "img-wrapper")) + ; ,img) + ; img)) ;; FIXME rename to figcaption (define (decoded-figcaption . args) From 88b79734b4daa279c8091a2edb45c87bbd4363df Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Fri, 17 Feb 2023 09:15:23 +0100 Subject: [PATCH 15/46] More hacky fragment cleanups --- rkt/refs.rkt | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/rkt/refs.rkt b/rkt/refs.rkt index 13174756..983792df 100644 --- a/rkt/refs.rkt +++ b/rkt/refs.rkt @@ -73,7 +73,13 @@ (regexp-match #rx"^mailto:" x)))) (define (to-name x) - (string-replace - (string-replace (string-downcase x) " " "-") - "%" "")) - + (regexp-replace #rx"[?%#]" + (string-replace (string-downcase x) " " "-") + "")) + +(module+ test + (require rackunit) + (check-equal? (to-name "What is this?") "what-is-this") + (check-equal? (to-name "50%") "50") + (check-equal? (to-name "a#b") "ab") + ) From ff87f11825f59e9d3c3b138b195ecf8e53306f56 Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Fri, 17 Feb 2023 09:15:36 +0100 Subject: [PATCH 16/46] Simple gen script --- gen-and-check-ebook | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100755 gen-and-check-ebook diff --git a/gen-and-check-ebook b/gen-and-check-ebook new file mode 100755 index 00000000..0b224b6c --- /dev/null +++ b/gen-and-check-ebook @@ -0,0 +1,6 @@ +#!/bin/bash + +./generate +./ebookify +epub-check ./_ebook/why_cryptocurrencies.epub + From c56b6c4a5c40c44721b844876853ed2a438ff38c Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Mon, 20 Feb 2023 08:50:23 +0100 Subject: [PATCH 17/46] Disable marginnotes --- rkt/sidenotes.rkt | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/rkt/sidenotes.rkt b/rkt/sidenotes.rkt index 648b5033..1b2f56d3 100644 --- a/rkt/sidenotes.rkt +++ b/rkt/sidenotes.rkt @@ -90,11 +90,14 @@ def) (define (mn ref-in #:top [top #f] #:bottom [bottom #f]) - (define ref (ref-symbol ref-in)) - (set-marginnote ref) - (set-note-top ref top) - (set-note-bottom ref bottom) - ref) + ; Disable marginnotes in epub + ; Because we have less control over fonts, enforce sidenote refs on all notes. + (sn ref-in #:top top #:bottom bottom)) + ; (define ref (ref-symbol ref-in)) + ; (set-marginnote ref) + ; (set-note-top ref top) + ; (set-note-bottom ref bottom) + ; ref) (define (sn ref-in #:top [top #f] #:bottom [bottom #f]) (define ref (ref-symbol ref-in)) From e5ec11663322b4929da11b4cfbd6656c140bc90b Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Mon, 20 Feb 2023 08:51:14 +0100 Subject: [PATCH 18/46] Center images --- sass/chapter.scss | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sass/chapter.scss b/sass/chapter.scss index 57b7f0c4..ad7f71f6 100644 --- a/sass/chapter.scss +++ b/sass/chapter.scss @@ -459,6 +459,7 @@ figure { img { max-width: 100%; + margin: 0 auto; } > figcaption { @extend %sans-serif; @@ -1009,6 +1010,10 @@ table.address-message { width: 100%; text-align: center; overflow-x: auto; + + img { + margin: 0 auto; + } } .wrapper.small { margin-top: -0.4rem; From 1700397c9681b3e9405c7bab974309f0a0687a27 Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Mon, 20 Feb 2023 08:54:52 +0100 Subject: [PATCH 19/46] Remove published/updated dates --- chapter.html.p | 6 ------ 1 file changed, 6 deletions(-) diff --git a/chapter.html.p b/chapter.html.p index 18ae047b..635824f9 100644 --- a/chapter.html.p +++ b/chapter.html.p @@ -68,12 +68,6 @@

◊|title|

◊|subtitle|

- ◊(when side-space? (->html - `(div ((class "date")) - (span ((class "published")) ,published) - ,(if updated - `(span ((class "updated")) ,updated) - ""))))
◊(->html doc #:splice? #t) From 406f48aeafc10d88e5d9dabbb99af89bcc67850c Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Mon, 20 Feb 2023 09:09:23 +0100 Subject: [PATCH 20/46] Use absolute links to internal things instead of absolute links --- ebookify | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ebookify b/ebookify index b71c53d9..d7660f13 100755 --- a/ebookify +++ b/ebookify @@ -371,6 +371,9 @@ def replace_post_data(data): data = data.replace('UUID_COPY', uuid) # https://github.com/Scripler/scripler/issues/430 data = data.replace(' ', ' ') + # Use relative links to internal things, not absolute links + data = data.replace('href="/', 'href="') + data = data.replace('src="/', 'src="') return data From f124c613daeba1321b6239fd34b00f10998d7735 Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Mon, 20 Feb 2023 09:09:59 +0100 Subject: [PATCH 21/46] Remove favicon links --- chapter.html.p | 2 -- landing.html.p | 2 -- toc-template.html.p | 2 -- 3 files changed, 6 deletions(-) diff --git a/chapter.html.p b/chapter.html.p index 635824f9..22522646 100644 --- a/chapter.html.p +++ b/chapter.html.p @@ -53,8 +53,6 @@ - -
diff --git a/landing.html.p b/landing.html.p index 03b3e935..1dc9e43e 100644 --- a/landing.html.p +++ b/landing.html.p @@ -8,8 +8,6 @@ - -
diff --git a/toc-template.html.p b/toc-template.html.p index 66040aa5..2756a88e 100644 --- a/toc-template.html.p +++ b/toc-template.html.p @@ -8,8 +8,6 @@ - - ◊(->html doc #:splice #t) From e611bd7ccfbc4513601732c12522dc95e797f85b Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Mon, 20 Feb 2023 09:30:52 +0100 Subject: [PATCH 22/46] Reformat scss files --- sass/code-highlight.scss | 44 ++- sass/fonts.scss | 186 ++++----- sass/homepage.scss | 74 ++-- sass/landing.scss | 794 ++++++++++++++++++++------------------- 4 files changed, 562 insertions(+), 536 deletions(-) diff --git a/sass/code-highlight.scss b/sass/code-highlight.scss index 505028da..6a9404e4 100644 --- a/sass/code-highlight.scss +++ b/sass/code-highlight.scss @@ -35,20 +35,36 @@ $gb-lm-light-orange: #af3a03; $gb-lm-light-gray: #7c6f64; .highlight { - margin: 1rem 0; - border-top: 1px dashed $body-hr-color; - border-bottom: 1px dashed $body-hr-color; + margin: 1rem 0; + border-top: 1px dashed $body-hr-color; + border-bottom: 1px dashed $body-hr-color; - > pre { - padding: 0 0.6em; - margin: 1em 0; - } + > pre { + padding: 0 0.6em; + margin: 1em 0; + } - // Builtin - .nb { color: $gb-lm-light-orange; } - // Strings - .s, .s1, .s2, .sb, .sc, .sd, .sh { color: $gb-lm-light-green} - // Keywords - .k, .kc, .kd, .kn, .kp, .kr { color: $gb-lm-light-blue; } + // Builtin + .nb { + color: $gb-lm-light-orange; + } + // Strings + .s, + .s1, + .s2, + .sb, + .sc, + .sd, + .sh { + color: $gb-lm-light-green; + } + // Keywords + .k, + .kc, + .kd, + .kn, + .kp, + .kr { + color: $gb-lm-light-blue; + } } - diff --git a/sass/fonts.scss b/sass/fonts.scss index 91400460..a2a59d46 100644 --- a/sass/fonts.scss +++ b/sass/fonts.scss @@ -1,126 +1,130 @@ -$century-supra: 'century_supra_a'; +$century-supra: "century_supra_a"; @font-face { - font-family: $century-supra; - font-style: normal; - font-weight: normal; - font-stretch: normal; - font-display: auto; - src: url('/fonts/century_supra_a_regular.woff2') format('woff2'); + font-family: $century-supra; + font-style: normal; + font-weight: normal; + font-stretch: normal; + font-display: auto; + src: url("/fonts/century_supra_a_regular.woff2") format("woff2"); } @font-face { - font-family: $century-supra; - font-style: italic; - font-weight: normal; - font-stretch: normal; - font-display: auto; - src: url('/fonts/century_supra_a_italic.woff2') format('woff2'); + font-family: $century-supra; + font-style: italic; + font-weight: normal; + font-stretch: normal; + font-display: auto; + src: url("/fonts/century_supra_a_italic.woff2") format("woff2"); } @font-face { - font-family: $century-supra; - font-style: normal; - font-weight: bold; - font-stretch: normal; - font-display: auto; - src: url('/fonts/century_supra_a_bold.woff2') format('woff2'); + font-family: $century-supra; + font-style: normal; + font-weight: bold; + font-stretch: normal; + font-display: auto; + src: url("/fonts/century_supra_a_bold.woff2") format("woff2"); } @font-face { - font-family: $century-supra; - font-style: italic; - font-weight: bold; - font-stretch: normal; - font-display: auto; - src: url('/fonts/century_supra_a_bold_italic.woff2') format('woff2'); + font-family: $century-supra; + font-style: italic; + font-weight: bold; + font-stretch: normal; + font-display: auto; + src: url("/fonts/century_supra_a_bold_italic.woff2") format("woff2"); } -$concourse: 'concourse_4'; +$concourse: "concourse_4"; @font-face { - font-family: $concourse; - font-style: normal; - font-weight: normal; - font-stretch: normal; - font-display: auto; - src: url('/fonts/concourse_4_regular.woff2') format('woff2'); + font-family: $concourse; + font-style: normal; + font-weight: normal; + font-stretch: normal; + font-display: auto; + src: url("/fonts/concourse_4_regular.woff2") format("woff2"); } @font-face { - font-family: $concourse; - font-style: italic; - font-weight: normal; - font-stretch: normal; - font-display: auto; - src: url('/fonts/concourse_4_italic.woff2') format('woff2'); + font-family: $concourse; + font-style: italic; + font-weight: normal; + font-stretch: normal; + font-display: auto; + src: url("/fonts/concourse_4_italic.woff2") format("woff2"); } @font-face { - font-family: $concourse; - font-style: normal; - font-weight: bold; - font-stretch: normal; - font-display: auto; - src: url('/fonts/concourse_4_bold.woff2') format('woff2'); + font-family: $concourse; + font-style: normal; + font-weight: bold; + font-stretch: normal; + font-display: auto; + src: url("/fonts/concourse_4_bold.woff2") format("woff2"); } @font-face { - font-family: $concourse; - font-style: italic; - font-weight: bold; - font-stretch: normal; - font-display: auto; - src: url('/fonts/concourse_4_bold_italic.woff2') format('woff2'); + font-family: $concourse; + font-style: italic; + font-weight: bold; + font-stretch: normal; + font-display: auto; + src: url("/fonts/concourse_4_bold_italic.woff2") format("woff2"); } -$triplicate: 'Triplicate'; +$triplicate: "Triplicate"; @font-face { - font-family: $triplicate; - font-style: normal; - font-weight: normal; - font-stretch: normal; - font-display: auto; - src: url('/fonts/triplicate_a_code_regular.woff2') format('woff2'); + font-family: $triplicate; + font-style: normal; + font-weight: normal; + font-stretch: normal; + font-display: auto; + src: url("/fonts/triplicate_a_code_regular.woff2") format("woff2"); } @font-face { - font-family: $triplicate; - font-style: italic; - font-weight: normal; - font-stretch: normal; - font-display: auto; - src: url('/fonts/triplicate_a_code_italic.woff2') format('woff2'); + font-family: $triplicate; + font-style: italic; + font-weight: normal; + font-stretch: normal; + font-display: auto; + src: url("/fonts/triplicate_a_code_italic.woff2") format("woff2"); } @font-face { - font-family: $triplicate; - font-style: normal; - font-weight: bold; - font-stretch: normal; - font-display: auto; - src: url('/fonts/triplicate_a_code_bold.woff2') format('woff2'); + font-family: $triplicate; + font-style: normal; + font-weight: bold; + font-stretch: normal; + font-display: auto; + src: url("/fonts/triplicate_a_code_bold.woff2") format("woff2"); } @font-face { - font-family: $triplicate; - font-style: italic; - font-weight: bold; - font-stretch: normal; - font-display: auto; - src: url('/fonts/triplicate_a_code_bold_italic.woff2') format('woff2'); + font-family: $triplicate; + font-style: italic; + font-weight: bold; + font-stretch: normal; + font-display: auto; + src: url("/fonts/triplicate_a_code_bold_italic.woff2") format("woff2"); } - -$serif-font-family: $century-supra, Constantia, "Lucida Bright", Lucidabright, "Lucida Serif", Lucida, "DejaVu Serif", "Bitstream Vera Serif", "Liberation Serif", Georgia, serif; -$sans-serif-font-family: $concourse, Frutiger, "Frutiger Linotype", Univers, Calibri, "Gill Sans", "Gill Sans MT", "Myriad Pro", Myriad, "DejaVu Sans Condensed", "Liberation Sans", "Nimbus Sans L", Tahoma, Geneva, "Helvetica Neue", Helvetica, Arial, sans-serif; -$code-font-family: $triplicate, Consolas, "Andale Mono WT", "Andale Mono", "Lucida Console", "Lucida Sans Typewriter", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Liberation Mono", "Nimbus Mono L", Monaco, "Courier New", Courier, monospace; - +$serif-font-family: $century-supra, Constantia, "Lucida Bright", Lucidabright, + "Lucida Serif", Lucida, "DejaVu Serif", "Bitstream Vera Serif", + "Liberation Serif", Georgia, serif; +$sans-serif-font-family: $concourse, Frutiger, "Frutiger Linotype", Univers, + Calibri, "Gill Sans", "Gill Sans MT", "Myriad Pro", Myriad, + "DejaVu Sans Condensed", "Liberation Sans", "Nimbus Sans L", Tahoma, Geneva, + "Helvetica Neue", Helvetica, Arial, sans-serif; +$code-font-family: $triplicate, Consolas, "Andale Mono WT", "Andale Mono", + "Lucida Console", "Lucida Sans Typewriter", "DejaVu Sans Mono", + "Bitstream Vera Sans Mono", "Liberation Mono", "Nimbus Mono L", Monaco, + "Courier New", Courier, monospace; %sans-serif { - text-rendering: optimizeLegibility; - font-family: $sans-serif-font-family; - font-feature-settings: "onum" off, "kern" on; + text-rendering: optimizeLegibility; + font-family: $sans-serif-font-family; + font-feature-settings: "onum" off, "kern" on; } %sans-serif-tnum { - text-rendering: optimizeLegibility; - @extend %sans-serif; - font-feature-settings: 'kern' on, 'tnum' on; + text-rendering: optimizeLegibility; + @extend %sans-serif; + font-feature-settings: "kern" on, "tnum" on; } %serif { - text-rendering: optimizeLegibility; - font-family: $serif-font-family; - font-feature-settings: "kern" on; + text-rendering: optimizeLegibility; + font-family: $serif-font-family; + font-feature-settings: "kern" on; } - - diff --git a/sass/homepage.scss b/sass/homepage.scss index 298dbef2..53695754 100644 --- a/sass/homepage.scss +++ b/sass/homepage.scss @@ -1,57 +1,57 @@ .homepage { - max-width: 600px; - margin: 0.5rem 1.2rem; + max-width: 600px; + margin: 0.5rem 1.2rem; } .homepage > header { - margin-bottom: 1em; - padding-bottom: 0.3em; - border-bottom: 0.2em solid; + margin-bottom: 1em; + padding-bottom: 0.3em; + border-bottom: 0.2em solid; - h1 { - @extend %sans-serif; - font-size: 2rem; - margin-bottom: 0.2rem; - } - h2 { - @extend %sans-serif; - font-size: 1rem; - font-weight: normal; - font-style: italic; - margin: 0; - margin-left: 0.3rem; - margin-bottom: 0.2rem; - } + h1 { + @extend %sans-serif; + font-size: 2rem; + margin-bottom: 0.2rem; + } + h2 { + @extend %sans-serif; + font-size: 1rem; + font-weight: normal; + font-style: italic; + margin: 0; + margin-left: 0.3rem; + margin-bottom: 0.2rem; + } } .toc section:not(:first-child) { - padding-top: 1.2rem; + padding-top: 1.2rem; } .toc { - @extend %sans-serif; - a { - text-decoration: none; - background: none; - text-shadow: none; - } - a:hover { - text-decoration: underline; - } + @extend %sans-serif; + a { + text-decoration: none; + background: none; + text-shadow: none; + } + a:hover { + text-decoration: underline; + } } .toc h1 { - font-size: 1.1rem; + font-size: 1.1rem; } .toc ul { - margin-top: 0.5rem; - list-style: none; + margin-top: 0.5rem; + list-style: none; - li { - margin-left: 0.6rem; - margin-top: 0.3rem; - } + li { + margin-left: 0.6rem; + margin-top: 0.3rem; + } } .toc .planned { - color: $planned-chapter-link; + color: $planned-chapter-link; } diff --git a/sass/landing.scss b/sass/landing.scss index 72ed60db..ce8c09bc 100644 --- a/sass/landing.scss +++ b/sass/landing.scss @@ -84,52 +84,51 @@ $cover-dark5: #606060; // #606030 // #90A860 -$cover-green-hl: #C0D890; - - -$pink-050: #FFE0F0; -$pink-100: #FAB8D9; -$pink-200: #F191C1; -$pink-300: #E668A7; -$pink-400: #DA4A91; -$pink-500: #C42D78; -$pink-600: #AD2167; -$pink-700: #9B1B5A; +$cover-green-hl: #c0d890; + +$pink-050: #ffe0f0; +$pink-100: #fab8d9; +$pink-200: #f191c1; +$pink-300: #e668a7; +$pink-400: #da4a91; +$pink-500: #c42d78; +$pink-600: #ad2167; +$pink-700: #9b1b5a; $pink-800: #781244; -$pink-900: #5C0B33; - -$magenta-050: #F5E1F7; -$magenta-100: #ECBDF2; -$magenta-200: #CE80D9; -$magenta-300: #BB61C7; -$magenta-400: #AD4BB8; -$magenta-500: #A23DAD; -$magenta-600: #90279C; -$magenta-700: #7C1A87; +$pink-900: #5c0b33; + +$magenta-050: #f5e1f7; +$magenta-100: #ecbdf2; +$magenta-200: #ce80d9; +$magenta-300: #bb61c7; +$magenta-400: #ad4bb8; +$magenta-500: #a23dad; +$magenta-600: #90279c; +$magenta-700: #7c1a87; $magenta-800: #671270; -$magenta-900: #4E0754; - -$yellow-050: #FFFAEB; -$yellow-100: #FCEFC7; -$yellow-200: #F8E3A3; -$yellow-300: #F9DA8B; -$yellow-400: #F7D070; -$yellow-500: #E9B949; -$yellow-600: #C99A2E; -$yellow-700: #A27C1A; -$yellow-800: #7C5E10; -$yellow-900: #513C06; - -$warm-grey-050: #FAF9F7; -$warm-grey-100: #E8E6E1; -$warm-grey-200: #D3CEC4; -$warm-grey-300: #B8B2A7; -$warm-grey-400: #A39E93; -$warm-grey-500: #857F72; -$warm-grey-600: #625D52; -$warm-grey-700: #504A40; -$warm-grey-800: #423D33; -$warm-grey-900: #27241D; +$magenta-900: #4e0754; + +$yellow-050: #fffaeb; +$yellow-100: #fcefc7; +$yellow-200: #f8e3a3; +$yellow-300: #f9da8b; +$yellow-400: #f7d070; +$yellow-500: #e9b949; +$yellow-600: #c99a2e; +$yellow-700: #a27c1a; +$yellow-800: #7c5e10; +$yellow-900: #513c06; + +$warm-grey-050: #faf9f7; +$warm-grey-100: #e8e6e1; +$warm-grey-200: #d3cec4; +$warm-grey-300: #b8b2a7; +$warm-grey-400: #a39e93; +$warm-grey-500: #857f72; +$warm-grey-600: #625d52; +$warm-grey-700: #504a40; +$warm-grey-800: #423d33; +$warm-grey-900: #27241d; $button-hover-color: $bch-green; $button-color: $yellow-300; @@ -143,29 +142,31 @@ $large-width: 1280px; $small-screen: 1067px; .landing { - display: flex; - flex-wrap: wrap; - justify-content: center; + display: flex; + flex-wrap: wrap; + justify-content: center; } .landing { - a { - text-shadow: none; - background: none; - text-shadow: none; - text-decoration: underline; - } - a:link, a:visited, a:link:selection { - text-shadow: none; - background: none; - text-decoration: underline; - } - a:link { - color: #000; - } - a:hover { - color: $btc-orange; - } + a { + text-shadow: none; + background: none; + text-shadow: none; + text-decoration: underline; + } + a:link, + a:visited, + a:link:selection { + text-shadow: none; + background: none; + text-decoration: underline; + } + a:link { + color: #000; + } + a:hover { + color: $btc-orange; + } } .landing .books, @@ -174,446 +175,451 @@ $small-screen: 1067px; .landing .header, .landing .faq, .landing .ending { - width: 100%; - display: flex; - flex-wrap: wrap; - justify-content: center; + width: 100%; + display: flex; + flex-wrap: wrap; + justify-content: center; } .landing .hero { - width: 100%; - background-color: $body-background-color; - background-color: $warm-grey-050; + width: 100%; + background-color: $body-background-color; + background-color: $warm-grey-050; } .landing .hero .header { - padding: 8px; - display: flex; - flex-wrap: wrap; - // margin-top: 64px; + padding: 8px; + display: flex; + flex-wrap: wrap; + // margin-top: 64px; } .landing .hero .title { - margin-top: 24px; - max-width: 650px; - // background-color: red; - // flex: 1; - h1 { - font-size: 48px; - margin: 0; - margin-bottom: 8px; - // margin-bottom: 24px; - } - h2 { - @extend %sans-serif; - font-size: 24px; - font-weight: normal; - font-style: italic; - margin: 0; - margin-bottom: 24px; - // margin: 0; - // margin-left: 0.3rem; - // margin-bottom: 0.2rem; - // display: none; - } - - .sell-it { - // text-align: center; - // padding-right: 64px; - // max-width: 650px; - } - .afford { - font-weight: bold; - } + margin-top: 24px; + max-width: 650px; + // background-color: red; + // flex: 1; + h1 { + font-size: 48px; + margin: 0; + margin-bottom: 8px; + // margin-bottom: 24px; + } + h2 { + @extend %sans-serif; + font-size: 24px; + font-weight: normal; + font-style: italic; + margin: 0; + margin-bottom: 24px; + // margin: 0; + // margin-left: 0.3rem; + // margin-bottom: 0.2rem; + // display: none; + } + + .sell-it { + // text-align: center; + // padding-right: 64px; + // max-width: 650px; + } + .afford { + font-weight: bold; + } } .landing .hero .buttons { - width: 100%; - margin-top: 32px; - margin-bottom: 48px; - width: 100%; - display: flex; - flex-wrap: wrap; - justify-content: space-evenly; + width: 100%; + margin-top: 32px; + margin-bottom: 48px; + width: 100%; + display: flex; + flex-wrap: wrap; + justify-content: space-evenly; } .landing .hero .buttons a { - flex: 1; - text-decoration: none; - color: inherit; - text-align: center; - background-color: $button-color; - border: 0; - border-radius: 4px; - font-size: 1rem; - padding: 12px 16px; - margin: 8px; - cursor: pointer; - box-shadow: 1px 1px 0px $button-shadow-color; - min-width: 160px; + flex: 1; + text-decoration: none; + color: inherit; + text-align: center; + background-color: $button-color; + border: 0; + border-radius: 4px; + font-size: 1rem; + padding: 12px 16px; + margin: 8px; + cursor: pointer; + box-shadow: 1px 1px 0px $button-shadow-color; + min-width: 160px; } .landing .hero .buttons a:hover { - text-decoration: none; - color: inherit; - background-color: $button-hover-color; + text-decoration: none; + color: inherit; + background-color: $button-hover-color; } .landing .hero .book { - display: flex; - flex-wrap: wrap; - justify-content: center; - width: 100%; - img { - max-width: 600px; - } + display: flex; + flex-wrap: wrap; + justify-content: center; + width: 100%; + img { + max-width: 600px; + } } .landing .user-comments { - padding: 48px 0; - background-color: $warm-grey-050; + padding: 48px 0; + background-color: $warm-grey-050; } .landing .user-comments h1 { - width: 100%; - text-align: center; + width: 100%; + text-align: center; } .landing .user-comments blockquote { - // background-color: $warm-grey-050; + // background-color: $warm-grey-050; } .landing .books { - background-color: $warm-grey-800; - padding: 48px 0; + background-color: $warm-grey-800; + padding: 48px 0; } .landing .format-wrapper { - width: 100%; - display: flex; - flex-wrap: wrap; - justify-content: center; + width: 100%; + display: flex; + flex-wrap: wrap; + justify-content: center; } .landing .format { + display: flex; + flex-wrap: wrap; + justify-content: center; + padding: 0; + border-radius: 8px; + + background-color: $yellow-050; + // border: solid 1px $yellow-100; + // border-radius: 8px; + margin-bottom: 48px; + + h1 { + margin-bottom: 16px; + } + ul { + list-style: none; + } + ol li, + ul li { + margin-bottom: 0.4em; + font-size: 95%; + line-height: 1.35; + } + nav.buttons { display: flex; flex-wrap: wrap; justify-content: center; - padding: 0; - border-radius: 8px; - - background-color: $yellow-050; - // border: solid 1px $yellow-100; - // border-radius: 8px; - margin-bottom: 48px; + } + nav.buttons a, + nav.buttons div.soon { + // flex: 1; + text-align: center; + width: 100%; + background-color: $button-color; + border: 0; + border-radius: 4px; + font-size: 1rem; + padding: 12px 16px; + // margin: 8px; + margin-bottom: 8px; + cursor: pointer; + box-shadow: 1px 1px 0px $button-shadow-color; - h1 { - margin-bottom: 16px; - } - ul { - list-style: none; - } - ol li, ul li { - margin-bottom: 0.4em; - font-size: 95%; - line-height: 1.35; - } - nav.buttons { - display: flex; - flex-wrap: wrap; - justify-content: center; - } - nav.buttons a, nav.buttons div.soon { - // flex: 1; - text-align: center; - width: 100%; - background-color: $button-color; - border: 0; - border-radius: 4px; - font-size: 1rem; - padding: 12px 16px; - // margin: 8px; - margin-bottom: 8px; - cursor: pointer; - box-shadow: 1px 1px 0px $button-shadow-color; - - display: flex; - flex-wrap: wrap; - justify-content: center; - - span { - // flex: 0; - width: 100%; - } - } - nav.buttons a:hover { - background-color: $button-hover-color; - cursor: pointer; - } - nav.buttons div.soon { - cursor: auto; - background-color: $invalid-button-color; - box-shadow: 1px 1px 0px $invalid-button-shadow-color; - } - nav.buttons span.spanner { - width: 100%; - display: flex; - flex-wrap: wrap; - justify-content: center; - } - nav.buttons span.spanner a { - flex: 1; - } - nav.buttons span.spanner a:not(:first-child) { - margin-left: 8px; - } - .small-emph { - // flex: 0; - // width: 100%; - font-size: 0.9rem; - font-style: italic; - } - .coming { - font-size: 0.9rem; - //font-style: italic; - } + display: flex; + flex-wrap: wrap; + justify-content: center; - ul.features { - margin-top: 24px; - } - ul.features li::before { - @extend %sans-serif; - content: "•"; - margin-left: -20px; - padding-right: 8px; - color: $yellow-500; - } - ul.features li { - margin-left: 32px; - } - ul.features a, ul.features a:link { - text-decoration: underline; - cursor: pointer; - } - ul.features a:hover { - color: $btc-orange; + span { + // flex: 0; + width: 100%; } + } + nav.buttons a:hover { + background-color: $button-hover-color; + cursor: pointer; + } + nav.buttons div.soon { + cursor: auto; + background-color: $invalid-button-color; + box-shadow: 1px 1px 0px $invalid-button-shadow-color; + } + nav.buttons span.spanner { + width: 100%; + display: flex; + flex-wrap: wrap; + justify-content: center; + } + nav.buttons span.spanner a { + flex: 1; + } + nav.buttons span.spanner a:not(:first-child) { + margin-left: 8px; + } + .small-emph { + // flex: 0; + // width: 100%; + font-size: 0.9rem; + font-style: italic; + } + .coming { + font-size: 0.9rem; + //font-style: italic; + } + + ul.features { + margin-top: 24px; + } + ul.features li::before { + @extend %sans-serif; + content: "•"; + margin-left: -20px; + padding-right: 8px; + color: $yellow-500; + } + ul.features li { + margin-left: 32px; + } + ul.features a, + ul.features a:link { + text-decoration: underline; + cursor: pointer; + } + ul.features a:hover { + color: $btc-orange; + } } .landing .background { - display: inline-block; - padding-left: 24px; + display: inline-block; + padding-left: 24px; } .landing .format .left { - width: 520px; - margin-right: 16px; - padding: 16px; + width: 520px; + margin-right: 16px; + padding: 16px; - a, a:link, a:hover { - color: inherit; - text-decoration: none; - cursor: auto; - } + a, + a:link, + a:hover { + color: inherit; + text-decoration: none; + cursor: auto; + } } .landing .format .img-wrapper { - width: 500px; - border-radius: 8px; - border-bottom-left-radius: 0; - border-top-left-radius: 0; - background-image: url("/images/cover/front.png"); - // padding: 8px; + width: 500px; + border-radius: 8px; + border-bottom-left-radius: 0; + border-top-left-radius: 0; + background-image: url("/images/cover/front.png"); + // padding: 8px; } .landing .print .img-wrapper { - background-image: url("/images/landing/print.png"); + background-image: url("/images/landing/print.png"); } .landing .ebook .img-wrapper { - background-image: url("/images/landing/ebook.png"); + background-image: url("/images/landing/ebook.png"); } .landing .pdf .img-wrapper { - background-image: url("/images/landing/pdf.png"); + background-image: url("/images/landing/pdf.png"); } .landing .web .img-wrapper { - background-image: url("/images/landing/unbanked.png"); + background-image: url("/images/landing/unbanked.png"); } .landing .praise { - max-width: $large-width; - display: grid; - grid-template-columns: repeat(auto-fill, minmax(500px, 1fr)); - grid-gap: 4px; + max-width: $large-width; + display: grid; + grid-template-columns: repeat(auto-fill, minmax(500px, 1fr)); + grid-gap: 4px; } .landing .what { - background-color: $cover-dark3; - padding-top: 32px; - padding-bottom: 32px; - color: $warm-grey-100; + background-color: $cover-dark3; + padding-top: 32px; + padding-bottom: 32px; + color: $warm-grey-100; } .landing .what .head { - width: 100%; - text-align: center; - margin-bottom: 32px; + width: 100%; + text-align: center; + margin-bottom: 32px; } .landing .what .examples { - max-width: $large-width; - display: grid; - grid-template-columns: repeat(auto-fill, minmax(500px, 1fr)); - grid-gap: 48px; + max-width: $large-width; + display: grid; + grid-template-columns: repeat(auto-fill, minmax(500px, 1fr)); + grid-gap: 48px; } .landing .what .ex { - display: flex; - flex-wrap: wrap; - justify-content: space-between; + display: flex; + flex-wrap: wrap; + justify-content: space-between; } .landing .what .ex h2 { - margin: 0; - margin-bottom: 0.3rem; + margin: 0; + margin-bottom: 0.3rem; } .landing .what .img-wrapper { - width: 130px; - height: 130px; - border-radius: 65px; - // border-radius: 8px; - // float: left; + width: 130px; + height: 130px; + border-radius: 65px; + // border-radius: 8px; + // float: left; } .landing .what .utility .img-wrapper { - background-image: url("/images/landing/casino.png"); + background-image: url("/images/landing/casino.png"); } .landing .what .easy .img-wrapper { - background-image: url("/images/landing/huh.png"); + background-image: url("/images/landing/huh.png"); } .landing .what .concepts .img-wrapper { - background-image: url("/images/landing/miners.png"); + background-image: url("/images/landing/miners.png"); } .landing .what .order .img-wrapper { - background-image: url("/images/landing/heli.png"); + background-image: url("/images/landing/heli.png"); } .landing .what .general .img-wrapper { - background-image: url("/images/landing/bank.png"); + background-image: url("/images/landing/bank.png"); } .landing .what .variety .img-wrapper { - background-image: url("/images/landing/snowden.png"); + background-image: url("/images/landing/snowden.png"); } .landing .what .right { - // float: left; - // width: 100px; - flex: 1; - margin-left: 16px; + // float: left; + // width: 100px; + flex: 1; + margin-left: 16px; } .landing .faq { - background-color: $warm-grey-900; - // background-color: $cover-dark3; - padding: 32px 8px; - // color: $warm-grey-100; - background-color: $warm-grey-200; + background-color: $warm-grey-900; + // background-color: $cover-dark3; + padding: 32px 8px; + // color: $warm-grey-100; + background-color: $warm-grey-200; } .landing .faq .questions { - width: 100%; + width: 100%; } .landing .faq h1 { - margin-bottom: 24px; + margin-bottom: 24px; } .landing .faq a { - color: inherit; - text-decoration: underline; + color: inherit; + text-decoration: underline; } .landing .faq a:hover { - color: $btc-orange; - text-decoration: none; + color: $btc-orange; + text-decoration: none; } .landing .faq .questions .question-answer { - width: 100%; - margin-bottom: 32px; + width: 100%; + margin-bottom: 32px; } .landing .faq .question { - width: 800px; - margin: 0 auto; - font-weight: bold; + width: 800px; + margin: 0 auto; + font-weight: bold; } .landing .faq .answer { - margin: 0 auto; - width: 800px; + margin: 0 auto; + width: 800px; } .landing .faq .answer ul { - list-style: none; - margin: 1rem 0 1rem 0em; - - > li::before { - @extend %sans-serif; - //content: "⭑"; - //content: "~"; - //content: "≈"; - //content: "→"; - //content: "»"; - //content: "*"; - content: "•"; - //content: "†"; - // color: $body-list-sym-color; - } + list-style: none; + margin: 1rem 0 1rem 0em; + + > li::before { + @extend %sans-serif; + //content: "⭑"; + //content: "~"; + //content: "≈"; + //content: "→"; + //content: "»"; + //content: "*"; + content: "•"; + //content: "†"; + // color: $body-list-sym-color; + } } .landing .ending { - padding-top: 8px; - padding-bottom: 8px; - background-color: $body-background-color; - // color: $warm-grey-050; + padding-top: 8px; + padding-bottom: 8px; + background-color: $body-background-color; + // color: $warm-grey-050; } .landing .ending { - a:link { - color: inherit; - text-decoration: underline; - } - a:hover { - color: $btc-orange; - text-decoration: none; - } + a:link { + color: inherit; + text-decoration: underline; + } + a:hover { + color: $btc-orange; + text-decoration: none; + } } @media only screen and (max-width: $small-screen) { - .landing .format { - width: 520px; - margin-left: 16px; - margin-right: 16px; - // padding: 16px; - border-radius: 8px; - padding: 0; - } - .landing .format .left { - order: 2; - width: 100%; - margin: 0; - padding: 16px; - } - .landing .format .img-wrapper { - order: 1; - width: 100%; - height: 300px; - border-radius: 8px; - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; - } - .landing .what .examples { - display: block; - } - .landing .what .ex { - margin-bottom: 48px; - } - .landing .faq { - padding: 32px; - } - .landing .faq .questions .question-answer { - width: 100%; - } - .landing .faq .question, - .landing .faq .answer { - width: 100%; - } - .landing .hero .buttons a { - flex: 0 1 auto; - width: 100%; - } + .landing .format { + width: 520px; + margin-left: 16px; + margin-right: 16px; + // padding: 16px; + border-radius: 8px; + padding: 0; + } + .landing .format .left { + order: 2; + width: 100%; + margin: 0; + padding: 16px; + } + .landing .format .img-wrapper { + order: 1; + width: 100%; + height: 300px; + border-radius: 8px; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } + .landing .what .examples { + display: block; + } + .landing .what .ex { + margin-bottom: 48px; + } + .landing .faq { + padding: 32px; + } + .landing .faq .questions .question-answer { + width: 100%; + } + .landing .faq .question, + .landing .faq .answer { + width: 100%; + } + .landing .hero .buttons a { + flex: 0 1 auto; + width: 100%; + } } @media only screen and (max-width: 520px) { - .landing .format { - width: 100%; - } - .landing .praise { - display: block; - } - .landing .praise blockquote { - margin-bottom: 48px; - } + .landing .format { + width: 100%; + } + .landing .praise { + display: block; + } + .landing .praise blockquote { + margin-bottom: 48px; + } } From 3fdd549ec253b7c0fd50cd5fed2dec905ded01e8 Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Mon, 20 Feb 2023 10:03:50 +0100 Subject: [PATCH 23/46] Restore toc formating --- rkt/index.rkt | 5 ++++- sass/homepage.scss | 24 ++++++++++++++---------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/rkt/index.rkt b/rkt/index.rkt index 824ed828..a7590693 100644 --- a/rkt/index.rkt +++ b/rkt/index.rkt @@ -55,7 +55,10 @@ ;; Make a table of content, used on the homepage or dedicated toc page. (define (make-toc content) `(nav ((class "toc") (epub:type "toc")) - (h1 "Contents") + (hgroup + (h1 "Why Cryptocurrencies?") + (h2 "What they are, what they do and why they matter") + ) (ol ,@(map (λ (x) `(li ,@(page-section-toc x))) diff --git a/sass/homepage.scss b/sass/homepage.scss index 53695754..686613aa 100644 --- a/sass/homepage.scss +++ b/sass/homepage.scss @@ -1,9 +1,9 @@ -.homepage { +.toc { max-width: 600px; margin: 0.5rem 1.2rem; } -.homepage > header { +.toc > hgroup { margin-bottom: 1em; padding-bottom: 0.3em; border-bottom: 0.2em solid; @@ -24,7 +24,7 @@ } } -.toc section:not(:first-child) { +.toc > ol > li:not(:first-child) { padding-top: 1.2rem; } @@ -40,18 +40,22 @@ } } -.toc h1 { +.toc ol { + list-style: none; +} + +.toc > ol > li > a { font-size: 1.1rem; + font-weight: bold; + @extend %sans-serif; + line-height: 1; } -.toc ul { + +.toc > ol > li > ol { margin-top: 0.5rem; - list-style: none; - li { + > li { margin-left: 0.6rem; margin-top: 0.3rem; } } -.toc .planned { - color: $planned-chapter-link; -} From 3347055bbc956a400fdf37bf8826d32198baadb0 Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Tue, 21 Feb 2023 16:34:18 +0100 Subject: [PATCH 24/46] Content metadata --- ebook-files/content.opf | 17 +++++++++++++---- ebook-files/toc.ncx | 2 +- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/ebook-files/content.opf b/ebook-files/content.opf index 2d5612a2..c1f85392 100644 --- a/ebook-files/content.opf +++ b/ebook-files/content.opf @@ -1,12 +1,21 @@ - + - Why cryptocurrencies? - Jonas Hietala + Why Cryptocurrencies? + main + What they are, what they do and why they matter + subtitle + Jonas Hietala + aut + Jonas Hietala en-US - ◊UUID + urn:isbn:978-91-986762-1-1 + urn:isbn:978-91-986762-0-4 + ◊DATE ◊DATE + reflowable + scrolled-doc diff --git a/ebook-files/toc.ncx b/ebook-files/toc.ncx index a749d94d..4554f460 100644 --- a/ebook-files/toc.ncx +++ b/ebook-files/toc.ncx @@ -1,7 +1,7 @@ - + From c352d4e482721f9ebddf272dfc933a3bf2bc2271 Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Tue, 21 Feb 2023 16:34:44 +0100 Subject: [PATCH 25/46] Restyle the opening page --- ebook-files/title_page.xhtml | 18 +++++++++++------- sass/homepage.scss | 4 ++++ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/ebook-files/title_page.xhtml b/ebook-files/title_page.xhtml index e45cec9d..2474a0a9 100644 --- a/ebook-files/title_page.xhtml +++ b/ebook-files/title_page.xhtml @@ -2,20 +2,24 @@ - + Why cryptocurrencies? + + -
-

Why cryptocurrencies?

-

What they are, what they do and why they matter

+
+
+

Why cryptocurrencies?

+

What they are, what they do and why they matter

+
-

v1.0.0

+

v1.0.0

The full text of this book is available online at: whycryptocurrencies.com

-

This is a self-published book, and if you’re curious about the creation process I wrote a few blog posts about it: jonashietala.se/blog/tags/why_cryptocurrencies/

+

This is a self-published book, and if you’re curious about the creation process I wrote a few blog posts about it.

Cover art by Brad Lark: blark@blark.com

@@ -24,6 +28,6 @@

All rights reserved.

ISBN: 978-91-986762-1-1

-
+
diff --git a/sass/homepage.scss b/sass/homepage.scss index 686613aa..3f09a8b1 100644 --- a/sass/homepage.scss +++ b/sass/homepage.scss @@ -59,3 +59,7 @@ margin-top: 0.3rem; } } + +.version { + font-style: italic; +} From bbe9e4872b673f168526e90befc5588f21444b5c Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Tue, 21 Feb 2023 16:35:05 +0100 Subject: [PATCH 26/46] Add pagespread info --- ebook-files/content.opf | 4 ++-- ebookify | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ebook-files/content.opf b/ebook-files/content.opf index c1f85392..e8049789 100644 --- a/ebook-files/content.opf +++ b/ebook-files/content.opf @@ -44,8 +44,8 @@ - - + + ◊SPINE_TOC diff --git a/ebookify b/ebookify index d7660f13..2bca9231 100755 --- a/ebookify +++ b/ebookify @@ -228,7 +228,7 @@ def manifest_post_tag(post): def spine_toc_post(post): id = post_id(post) - return f'' + return f'' def img_id(img): From c03e4545133c232b3415a6ddec1cf541ad412953 Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Tue, 21 Feb 2023 16:35:27 +0100 Subject: [PATCH 27/46] Override sidenote p fontsize, otherwise they might diverge when p is missing --- sass/chapter.scss | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sass/chapter.scss b/sass/chapter.scss index ad7f71f6..43bd5cbd 100644 --- a/sass/chapter.scss +++ b/sass/chapter.scss @@ -327,9 +327,10 @@ cite.book { visibility: hidden; } -.sidenote { +.sidenote, +.sidenote > p { @extend %sans-serif; - font-size: 0.8rem; + font-size: 0.8rem !important; } .sidenote img { max-width: 100%; From 7eb6c292e8516a97de83c28748cc794e2df1087e Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Tue, 21 Feb 2023 16:36:08 +0100 Subject: [PATCH 28/46] Reorder toc --- rkt/toc.rkt | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/rkt/toc.rkt b/rkt/toc.rkt index 28bce5a2..07149449 100644 --- a/rkt/toc.rkt +++ b/rkt/toc.rkt @@ -5,12 +5,9 @@ (define toc ;; This replaces the previously hand-made pagetree in index.ptree. ;; String entries gets removed and are treated as planned chapters. - `(eli5.html - (about_the_book.html - acknowledgements.html - ;how_to_use.html - ;free.html - about_me.html) + `(acknowledgements.html + about_the_book.html + eli5.html (what_is_a_cryptocurrency.html properties_of_a_cryptocurrency.html how_do_cryptocurrencies_work.html @@ -49,7 +46,8 @@ ;"Who is Satoshi Nakamoto?" ;"Is Facebook's Libra a cryptocurrency?" ;"Further research" - ))) + ) + about_me.html)) (define (in-toc? page) (in-tree? page toc)) From 08457867718da22a8f7a5a1cc4f2650cf70ef5e8 Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Tue, 21 Feb 2023 19:41:35 +0100 Subject: [PATCH 29/46] Remove sidenote top/bottom margin adjustments --- rkt/sidenotes.rkt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/rkt/sidenotes.rkt b/rkt/sidenotes.rkt index 1b2f56d3..ca134b5c 100644 --- a/rkt/sidenotes.rkt +++ b/rkt/sidenotes.rkt @@ -309,9 +309,12 @@ (string-join styles " "))) (define attrs `((class "sidenote"))) - (when (non-empty-string? styles) - (set! attrs (append attrs - `((style ,styles))))) + ; Remove bottom and top margins that are used for sidenote positioning. + ; If the reader overrides font or font size, then we will get overlap between + ; sidenotes. We really don't want that, so let's skip these. + ; (when (non-empty-string? styles) + ; (set! attrs (append attrs + ; `((style ,styles))))) `(aside ,attrs ,@(label note) From a2e47139f1010a7718fc45d1c4ca8af77d2962e9 Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Tue, 21 Feb 2023 19:42:03 +0100 Subject: [PATCH 30/46] Fix changed subnav styling --- sass/chapter.scss | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sass/chapter.scss b/sass/chapter.scss index 43bd5cbd..65b13411 100644 --- a/sass/chapter.scss +++ b/sass/chapter.scss @@ -177,16 +177,16 @@ $list-p-margin: 0.6em; font-weight: bold; } - ul { + ol { list-style: none; margin: 0; } - ul > li { + ol > li { font-size: 100%; margin-left: 0.6rem; margin-top: 0.3rem; } - ul > li::before { + ol > li::before { display: none; } From 43d7aa1f96ff78f57108053c46f26c9d549e17b5 Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Wed, 22 Feb 2023 07:00:25 +0100 Subject: [PATCH 31/46] Add short commit to version, for easy check during dev and release --- ebook-files/title_page.xhtml | 2 +- ebookify | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/ebook-files/title_page.xhtml b/ebook-files/title_page.xhtml index 2474a0a9..0cc0a97e 100644 --- a/ebook-files/title_page.xhtml +++ b/ebook-files/title_page.xhtml @@ -14,7 +14,7 @@

What they are, what they do and why they matter

-

v1.0.0

+

v1.0.0-◊SHORT_COMMIT

The full text of this book is available online at: whycryptocurrencies.com

diff --git a/ebookify b/ebookify index 2bca9231..5cf1faeb 100755 --- a/ebookify +++ b/ebookify @@ -11,8 +11,6 @@ import datetime # http://www.jedisaber.com/eBooks/Tutorial.shtml now = datetime.datetime.now() -uuid = "0dfc44f6-9c27-42ea-b6a8-45334b6aeeff" -# uuid = "0dfc44f6-9c27-42ea-b6a8-45334b6aeeff" + datetime.datetime.now().strftime("%y-%m-%d:%H%M") dirname = os.path.dirname(__file__) site_dir = os.path.join(dirname, "_site") @@ -24,6 +22,8 @@ oebps_dir = os.path.join(ebook_dir, "OEBPS") css_dir = oebps_dir image_dir = os.path.join(oebps_dir, "images") font_dir = os.path.join(oebps_dir, "fonts") +short_commit = subprocess.run(['git', 'rev-parse', '--short', 'HEAD'], + stdout=subprocess.PIPE).stdout.decode('utf-8') toc = [ "acknowledgements.html", @@ -275,7 +275,6 @@ def setup_content_opf(): with open(f"{ebook_files_dir}/content.opf", 'r') as f: data = f.read() - data = data.replace("◊UUID", uuid) data = data.replace("◊DATE", datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%SZ")) @@ -313,8 +312,6 @@ def setup_toc_ncx(): with open(f"{ebook_files_dir}/toc.ncx", 'r') as f: data = f.read() - data = data.replace("◊UUID", uuid) - with open(f"{oebps_dir}/toc.ncx", 'w') as f: f.write(data) @@ -337,7 +334,15 @@ def setup_toc(): def setup_static_pages(): - subprocess.run(f"cp {ebook_files_dir}/*.xhtml {oebps_dir}", shell=True) + for src in glob.glob(f"{ebook_files_dir}/*.xhtml"): + with open(src, 'r') as f: + data = f.read() + + data = replace_post_data(data) + + dst = os.path.join(oebps_dir, os.path.basename(src)) + with open(dst, 'w') as f: + f.write(data) def setup_post_replacements(): @@ -368,12 +373,12 @@ def replace_post_data(data): for link, new_link in link_replace.items(): data = data.replace(link, new_link) data = data.replace('Cheaper & faster', 'Cheaper & faster') - data = data.replace('UUID_COPY', uuid) # https://github.com/Scripler/scripler/issues/430 data = data.replace(' ', ' ') # Use relative links to internal things, not absolute links data = data.replace('href="/', 'href="') data = data.replace('src="/', 'src="') + data = data.replace("◊SHORT_COMMIT", short_commit) return data From f54ed36a14e284c8eb48f7340129589bd56f3981 Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Wed, 22 Feb 2023 11:29:11 +0100 Subject: [PATCH 32/46] Update alt text for images And specify group role on figure and presentation role for decorative images, according to http://diagramcenter.org/59-image-guidelines-for-epub-3.html --- a_defective_system.html.pm | 14 +++++++------- antifragile.html.pm | 4 ++-- are_cryptocurrencies_money.html.pm | 2 +- challenges.html.pm | 6 +++--- cryptography.html.pm | 2 +- for_the_unbanked.html.pm | 6 +++--- global_currency.html.pm | 2 +- how_do_cryptocurrencies_work.html.pm | 8 ++++---- properties_of_a_cryptocurrency.html.pm | 8 ++++---- rkt/tags.rkt | 24 ++++++++++++++++++++---- separation_of_money_and_state.html.pm | 2 +- timestamping_service.html.pm | 7 +++---- tokens.html.pm | 4 ++-- undesirable_businesses.html.pm | 4 ++-- voting.html.pm | 2 +- what_is_money.html.pm | 18 +++++++++--------- 16 files changed, 64 insertions(+), 49 deletions(-) diff --git a/a_defective_system.html.pm b/a_defective_system.html.pm index 30fd858b..a047baeb 100644 --- a/a_defective_system.html.pm +++ b/a_defective_system.html.pm @@ -31,17 +31,17 @@ If I did print money---a ◊strong{lot} of money---and spent it like this, what For starters, if I just kept the money without spending it, nothing would change: -◊img[#:src "/images/counterfeiting1.png" #:alt "The counterfeiter can print a large stash of cash."]{ +◊img[#:src "/images/counterfeiting1.png" #:alt "The counterfeiter can print a large stash of cash, but other people would not benefit."]{ The counterfeit money is colored yellow and the real money is green. } Then if I decided to buy a bunch of LEGO®, the store would get some of my money: -◊img[#:src "/images/counterfeiting2.png" #:alt "The counterfeiter buys LEGO."]{} +◊img[#:src "/images/counterfeiting2.png" #:alt "The counterfeiter buys LEGO, sharing the wealth with the store."]{} After a while the store would use the counterfeited money to pay their supplier: -◊img[#:src "/images/counterfeiting3.png" #:alt "Money further trickles down to the supplier, but not to everyone."]{} +◊img[#:src "/images/counterfeiting3.png" #:alt "Money further trickles down to the supplier, but not to everyone. The poor people did not get more money than they had before, and now they're even poorer relative to the others."]{} Who in turn will use it to buy other stuff, and in this way the counterfeited money slowly trickles out into the rest of the economy. This extra money has two important effects: @@ -356,7 +356,7 @@ While taking out debt to fuel investments was only supposed to be a temporary me ◊; Actual source ◊; https://fred.stlouisfed.org/graph/?id=GFDEBTN, -◊img[#:src "images/usa-debt.svg" #:link #t #:alt "The federal debt of the United States, measure in trillions of dollars, since 1966."]{ +◊img[#:src "images/usa-debt.svg" #:link #t #:alt "The federal debt of the United States figure"]{ The ◊link[usa-national-debt]{federal debt of the United States}, measure in trillions of dollars, since 1966. After the ◊link[financial_crisis]{2008 financial crisis} the amount of debt skyrocketed, signifying a shift in economic policy. During the COVID-19 pandemic the debt explosively increased at a pace unseen before. @@ -444,18 +444,18 @@ It seems like we're moving away from the original Keynesian ideas to something e There's a worrying trend in the world: ◊link[global-inequality]{global inequality is rising}. The rich get richer and the poor get... poorer. -◊img[#:src "images/income-inequality-world.svg" #:link #t #:alt "Top 10% income share between 1980 and 2015."]{ +◊img[#:src "images/income-inequality-world.svg" #:link #t #:alt "World income share figure"]{ Top 10% income share between 1980 and 2015. Source ◊link[inequality-data]{World Inequality Database}. } The inequality is on the rise in nearly every country. If we take a closer look at the United States, it paints a gloomy picture:◊mn{report} -◊img[#:src "images/income-inequality.svg" #:link #t #:alt "Income share in the United States between 1962 and 2014."]{ +◊img[#:src "images/income-inequality.svg" #:link #t #:alt "United States income share figure"]{ Income share in the United States between 1962 and 2014. Source ◊link[inequality-data]{World Inequality Database}. } -◊img[#:src "images/wealth-inequality.svg" #:link #t #:alt "Net personal wealth in the United States between 1962 and 2014."]{ +◊img[#:src "images/wealth-inequality.svg" #:link #t #:alt "Net personal wealth figure"]{ Net personal wealth in the United States between 1962 and 2014. Source ◊link[inequality-data]{World Inequality Database}. } diff --git a/antifragile.html.pm b/antifragile.html.pm index 2a929f06..9b28877e 100644 --- a/antifragile.html.pm +++ b/antifragile.html.pm @@ -142,11 +142,11 @@ Cryptocurrencies work the same way. When a weakness is discovered developers wil While you can argue that an individual cryptocurrency is antifragile, antifragility also applies to the cryptocurrency concept itself. People like to point at the thousands of cryptocurrencies as some sort of drawback, but it's actually the opposite. Cryptocurrencies being created and then dying off en mass is good as each time one fails we might learn something new and use that to improve the survivors. -◊img[#:src "/images/btc-hydra.png" #:alt "A hydra with one Bitcoin head"]{ +◊img[#:src "/images/btc-hydra.png" #:alt "A hydra with one head looking like the Bitcoin logo."]{ Cryptocurrencies are like a Hydra. } -◊img[#:src "/images/bch-xmr-hydra.png" #:alt "A hydra with two heads, one Bitcoin Cash and one Monero"]{ +◊img[#:src "/images/bch-xmr-hydra.png" #:alt "A hydra with three heads; one cut off, one like the Bitcoin Cash logo and one like the Monero logo."]{ Cut off one head, two more shall take its place. } diff --git a/are_cryptocurrencies_money.html.pm b/are_cryptocurrencies_money.html.pm index 2b8c2cb9..d3c0722c 100644 --- a/are_cryptocurrencies_money.html.pm +++ b/are_cryptocurrencies_money.html.pm @@ -212,7 +212,7 @@ We've looked at the properties---but how well do they function as money, today? The valuation is highly speculation driven and has been notoriously volatile.◊mn{sov} ◊note-pos{sov} - ◊img[#:src "images/btc-valuation.svg" #:link #t #:alt "Bitcoin closing price per month, between 2010 and 2019."]{ + ◊img[#:src "images/btc-valuation.svg" #:link #t #:alt "Bitcoin closing price per month, between 2010 and 2020."]{ ◊link[btc-valuation]{Bitcoin price per week up to the beginning of 2020}. The price peaked in December 2017 to $19,870, and some exchanges had it even higher. A year later the price had dropped to $3,177, a drop of over 84%. } diff --git a/challenges.html.pm b/challenges.html.pm index e2d924ae..38eac703 100644 --- a/challenges.html.pm +++ b/challenges.html.pm @@ -97,12 +97,12 @@ Bitcoin, like most cryptocurrencies, uses a public ledger where all transactions "https://www.chainalysis.com/" "Chainalysis: The Blockchain Analysis Company")) -◊img[#:src "/images/coin-tracing.png" #:alt "Paying someone with allows you to see their funds."]{ +◊img[#:src "/images/coin-tracing.png" #:alt "Image of John's address that has sent 1 BTC to the merchant and 13 BTC to another address."]{ After the merchant receives a payment from John, the merchant can see that John has sent 13 BTC to another address, out of an initial 40 BTC. John appears to be quite rich. } -◊img[#:src "/images/coin-tracing2.png" #:alt "You can trace coins back in history."]{ +◊img[#:src "/images/coin-tracing2.png" #:alt "Image of how John's 40 BTC originates from a hacked exchange."]{ It's possible to trace coins further back in history. Here we see that John's coins come from a hacked exchange, whose address is known. It might mean John is the hacker or, more probably, that John has received ◊em{tainted} coins (coins associated with illegal behavior). } @@ -119,7 +119,7 @@ You can explore the Bitcoin blockchain, and see all transactions and addresses, In an attempt to make Bitcoin more private "mixing" services such as ◊link[coinjoin]{CoinJoin} can be used. They work by mixing together your coins with the coins of others, in an attempt to obscure where the coins are coming from: -◊img[#:src "/images/coinjoin.png" #:alt "Obfuscation by mixing coins with other addresses."]{ +◊img[#:src "/images/coinjoin.png" #:alt "Image of mixing coins by sending them to and from various addresses."]{ A mixing service makes several addresses send to each other, in order to obfuscate the history. Although not shown here, because it would be too messy, all addresses and amounts are still visible. } diff --git a/cryptography.html.pm b/cryptography.html.pm index 1a9f23fd..635d936d 100644 --- a/cryptography.html.pm +++ b/cryptography.html.pm @@ -110,7 +110,7 @@ You ◊em{encrypt} a message by placing it in the mailbox, this way nobody but t This is where our mailbox metaphor breaks down a bit. It may seem that it's more inconvenient to sign a message than to encrypt one, but digitally they're both straightforward. } -◊img[#:src "/images/encrypted_mailbox.png" #:alt "Placing a letter in the mailbox."]{ +◊img[#:src "/images/encrypted_mailbox.png" #:alt "A letter is placed in the mailbox."]{ Placing a message inside the mailbox ensures that only the one with the key can read it. } diff --git a/for_the_unbanked.html.pm b/for_the_unbanked.html.pm index e92b1e44..8c7c5969 100644 --- a/for_the_unbanked.html.pm +++ b/for_the_unbanked.html.pm @@ -44,7 +44,7 @@ There are ◊strong{◊link[findex-report]{1.7 billion adults}} without a bank a ◊; #df65b0 36-60 ◊; #dd1c77 61-80 ◊; #980043 81-100 -◊img[#:src "images/unbanked-map.png" #:class "fullwidth" #:link #t #:alt "Adults without a bank account, 2017."]{ +◊img[#:src "images/unbanked-map.png" #:class "fullwidth" #:link #t #:alt "A world map showing the fraction of adults without a bank account in each country, 2017."]{ Adults without a bank account, 2017. Source ◊link[findex-report]{Global Findex database}. } @@ -63,7 +63,7 @@ Another way to look at the world is to visualize the raw number of unbanked in e ◊;#43a2ca 50 - 100 mil ◊; 100 - 150 mil (no country!) ◊;#0868ac > 150 mil -◊img[#:src "images/unbanked-count-map.png" #:class "fullwidth" #:link #t #:alt "The number of adults without a bank account, 2017."]{ +◊img[#:src "images/unbanked-count-map.png" #:class "fullwidth" #:link #t #:alt "A world map showing the number of adults without a bank account in each country, 2017."]{ The number of adults without a bank account, 2017. Source ◊link[findex-report]{Global Findex database} (◊link[findex-interactive]{interactive}). } @@ -81,7 +81,7 @@ The ◊link[findex-report]{Global Findex database} also tried to examine why peo If this is interesting to you I suggest you ◊link[findex-report]{give the report a read}. There are tons of different statistics and I only refer to a fraction of the data available. } -◊img[#:src "images/why-unbanked.svg" #:link #t #:alt "Reported reason for adults not having a bank account, 2017."]{ +◊img[#:src "images/why-unbanked.svg" #:link #t #:alt "Reported reasons table."]{ Reported reason for adults not having a bank account, 2017. More than one reason could be given. Source ◊link[findex-report]{Global Findex database}. } diff --git a/global_currency.html.pm b/global_currency.html.pm index 1b879e06..5bcddd7f 100644 --- a/global_currency.html.pm +++ b/global_currency.html.pm @@ -9,7 +9,7 @@ ◊(clear-sidenotes) -◊img[#:src "/images/global.png" #:alt "You can send coins all over the world."]{} +◊img[#:src "/images/global.png" #:alt "You can send coins all over the world." #:decorative #t]{} Cryptocurrencies don't have any borders. They allow you to send and receive money from anywhere in the world; to bypass sanctions and border control; opt-out of local monetary policies; and use a currency that's global to an extent we've never seen before. diff --git a/how_do_cryptocurrencies_work.html.pm b/how_do_cryptocurrencies_work.html.pm index 1c1f04b3..cfdc6ed5 100644 --- a/how_do_cryptocurrencies_work.html.pm +++ b/how_do_cryptocurrencies_work.html.pm @@ -83,7 +83,7 @@ For example, Sneaky Steve wants to buy a computer from Honest Harry and wants to What Sneaky Steve tries to do is send ◊sans-tnum{1 BTC} to the merchant, Honest Harry, and then send a copy of ◊sans-tnum{1 BTC} to his other address: ◊sans-tnum{Sneaky Steve 2}. (It's possible to have as many addresses as you want---a consequence of the permissionless nature of Bitcoin.) ◊img[#:src "/images/double-spend.png" - #:alt "Double spending by sending a coin to someone and back to himself."]{Sneaky Steve sends a digital coin both to Honest Harry and himself.} + #:alt "Double spending figure"]{Sneaky Steve sends a digital coin both to Honest Harry and himself.} If we didn't prevent this, the ledger might look like this: @@ -269,7 +269,7 @@ When a miner finds a solution, she can update the ledger by adding a block to th A blockchain is what it sounds like: a chain of blocks where a new block builds on previous blocks. When a miner searches for a solution, she must target a block on a specific height---the POW problem includes a reference to the previous block and it only fits at a specific position in the chain. When a new block is added, all miners need to work on a new problem targeting that block. -◊img[#:src "/images/add_block.png" #:alt "A new block is added by linking it with a POW solution."]{ +◊img[#:src "/images/add_block.png" #:alt "A new block is added by linking it to the previous block with a POW solution."]{ The blocks in the blockchain are linked with a key obtained by solving the POW problem. } @@ -344,7 +344,7 @@ The blockchain is duplicated, stored, and maintained by many different people; y What happens if two miners find a block at the same height? For example, one where Sneaky Steve sends money to Honest Harry and one where Sneaky Steve sends money to himself? ◊img[#:src "/images/double_spend_fork.png" - #:alt "Two blocks can be added at the same height."]{ + #:alt "Two blocks can be added at the same height, even if they contain different transactions."]{ Two blocks at the same height with different transactions. } @@ -388,7 +388,7 @@ It works like this: } } -◊img[#:src "/images/reversal1.png" #:alt "Sneaky Steve pays Honest Harry."]{ +◊img[#:src "/images/reversal1.png" #:alt "Sneaky Steve paying Honest Harry, and a block with two confirmations."]{ Sneaky Steve pays Honest Harry and they wait until the transaction has two confirmations. } ◊img[#:src "/images/reversal3.png" #:alt "Honest Harry gives Sneaky Steve jeans."]{ diff --git a/properties_of_a_cryptocurrency.html.pm b/properties_of_a_cryptocurrency.html.pm index 6f1a3b27..958265ee 100644 --- a/properties_of_a_cryptocurrency.html.pm +++ b/properties_of_a_cryptocurrency.html.pm @@ -41,13 +41,13 @@ The important difference between a cryptocurrency and the digital payments we ha Sending money to people via your bank isn't peer-to-peer as you rely on your bank to send it for you. VISA, PayPal, Swish, Apple Pay, and other digital payments have the same problem, all except cryptocurrencies. -◊img[#:src "images/give_cash.png" #:alt "Cash is given directly from hand to hand."]{ +◊img[#:src "images/give_cash.png" #:alt "Giving cash figure"]{ Cash is given directly from hand to hand. } -◊img[#:src "images/send_bank.png" #:alt "Regular digital payments are sent through a bank or different payment processors."]{ +◊img[#:src "images/send_bank.png" #:alt "Payments through a bank figure"]{ Regular digital payments are sent through a bank or different payment processors. } -◊img[#:src "images/send_crypto.png" #:alt "Cryptocurrencies are sent directly from device to device."]{ +◊img[#:src "images/send_crypto.png" #:alt "Sent between devices figure"]{ Cryptocurrencies are sent directly from device to device. } @@ -87,7 +87,7 @@ Problems with counterfeit coins and bills go far back. From biting coins to test With cryptocurrencies, anyone can independently verify the integrity of the coins you send and receive. Details on how is in the ◊link[next-chapter]{next chapter} but I assure you no biting is needed. You cannot counterfeit coins and you cannot send the same coin to multiple people ◊em{(double-spend)}. This is what allows cryptocurrencies to operate without a trusted third-party. -◊img[#:src "/images/double-spend.png" #:alt "Double spending by sending a coin to someone and back to himself."]{ +◊img[#:src "/images/double-spend.png" #:alt "Double spending figure"]{ A double spending occurs when someone sends the same coin both to a merchant and back to himself. } diff --git a/rkt/tags.rkt b/rkt/tags.rkt index 9c388934..b3495bd1 100644 --- a/rkt/tags.rkt +++ b/rkt/tags.rkt @@ -368,11 +368,12 @@ (define (img #:src src #:alt alt + #:decorative [decorative #f] #:title [title #f] #:class [c #f] #:margin [margin #f] #:link [link #f] . caption) - (define attrs `()) + (define attrs `((role "group"))) (when c (set! attrs (cons `(class ,c) attrs))) (when title @@ -389,12 +390,15 @@ `(figure ,attrs - ,(raw-img #:src src #:link link #:alt alt) + ,(raw-img #:src src #:link link #:alt alt #:decorative decorative) ,figcaption)) -(define (raw-img #:src src #:link [link #f] #:alt alt) +(define (raw-img #:src src #:link [link #f] #:alt alt #:decorative [decorative #f]) + (define attrs `((src ,(~a src)) (alt ,alt))) + (when decorative + (set! attrs (cons `(role "presentation") attrs))) (define img - `(img ((src ,(~a src)) (alt ,alt)))) + `(img ,attrs)) img) ; Image links not supported in ebooks? ; (if link @@ -402,6 +406,18 @@ ; ,img) ; img)) +(module+ test + (require rackunit) + (check-equal? (raw-img #:src "/src.png" #:alt "alt") + `(img ((src "/src.png") (alt "alt")))) + (check-equal? (raw-img #:src "/src.png" #:alt "alt" #:decorative #t) + `(img ((role "presentation") (src "/src.png") (alt "alt")))) + + (check-equal? (img #:src "/src.png" #:alt "alt" #:decorative #t) + `(figure ((role "group")) + (img ((role "presentation") (src "/src.png") (alt "alt"))) + (figcaption)))) + ;; FIXME rename to figcaption (define (decoded-figcaption . args) `(figcaption ,@(std-decode args))) diff --git a/separation_of_money_and_state.html.pm b/separation_of_money_and_state.html.pm index 6e3debd5..8eeebe18 100644 --- a/separation_of_money_and_state.html.pm +++ b/separation_of_money_and_state.html.pm @@ -9,7 +9,7 @@ ◊(clear-sidenotes) -◊img[#:src "/images/bitcoin-priest.png" #:class "slim" #:alt "A priest with a crown, holding a sword and a bag of Bitcoin."]{} +◊img[#:src "/images/bitcoin-priest.png" #:class "slim" #:alt "A priest with a crown, holding a sword and a bag of Bitcoin." #:decorative #t]{} When I first started thinking about cryptocurrencies, I thought they were just useful for some people who couldn't use regular transactions, like buying weed or things on a darknet market. Or that it was simply a better payment system as there was no middleman to skim off large fees from all transactions. That's useful, but it didn't strike me as revolutionary.◊mn{fees} diff --git a/timestamping_service.html.pm b/timestamping_service.html.pm index bac4c664..68ae4f76 100644 --- a/timestamping_service.html.pm +++ b/timestamping_service.html.pm @@ -56,9 +56,8 @@ Let's travel back in time and look at the site ◊link[hn]{Hacker News}, a tech } ◊img[#:src "images/hn-html.png" - #:alt "Hacker News on Mars 1st, 2011."]{ - The top three stories on ◊link[hn-wayback-ref]{Hacker News on Mars 1st, 2011} according to the Wayback Machine. - I tried to reproduce the site appearance, but it's not pixel perfect. + #:alt "Hacker News on Mars 1st, 2011. Any news of Bitcoin is absent."]{ + The top three stories on ◊link[hn-wayback-ref]{Hacker News on Mars 1st, 2011} according to the Wayback Machine. } As long as we can trust the Wayback Machine (and I do consider them generally trustworthy) we can be fairly sure this is correct. Letting a trusted party like the Wayback Machine handle timestamping, called ◊def[trusted-timestamping]{trusted timestamping}, is a solved problem with different kinds of standards but---as the name implies---there's always the caveat of requiring a trusted party to verify the timestamps. @@ -306,7 +305,7 @@ Let's now encode and timestamp it using the Bitcoin Cash blockchain: ◊img[#:src "images/electroncash-opreturn.png" #:title "Electron Cash custom OP_RETURN" - #:alt "Electron Cash custom OP_RETURN."]{ + #:alt "Electron Cash OP_RETURN figure"]{ Custom OP_RETURN using ◊link[electroncash]{Electron Cash}. } diff --git a/tokens.html.pm b/tokens.html.pm index 824d80b4..de43fc8f 100644 --- a/tokens.html.pm +++ b/tokens.html.pm @@ -207,12 +207,12 @@ I think visualizations can help us compare large amounts like these, so here's o `(div ((class "block")) (div ((class "title")) ,title) (div ((class "wrapper")) - (img ((src ,src)))))) + (img ((src ,src) (role "presentation") (alt ,title)))))) ◊(define (small-img title src) `(div ((class "block")) (div ((class "title")) ,title) (div ((class "wrapper small")) - (img ((src ,src)))))) + (img ((src ,src) (role "presentation") (alt ,title)))))) ◊; Extremely difficult to this with text, as fonts/sizes looks very different. diff --git a/undesirable_businesses.html.pm b/undesirable_businesses.html.pm index 32ad9c1a..bf6b6412 100644 --- a/undesirable_businesses.html.pm +++ b/undesirable_businesses.html.pm @@ -161,14 +161,14 @@ Therefore, most payment processors ◊link[stripe-restricted]{explicitly forbid} ◊img[#:src "/images/xxx-payments1.png" - #:alt "Payment processor doesn't want to do business with porn."]{ + #:alt "Payment processing denied figure"]{ Payment processors usually don't want anything to do with porn sites. } Instead, they have a third-party request the payment on their behalf and do some shady stuff. They can for example claim the payment is for another type of business, which isn't banned by the payment processor. ◊img[#:src "/images/xxx-payments2.png" - #:alt "An intermediary makes it possible for the porn business to use a payment processor."]{ + #:alt "Payment processing ok with an intermediary figure"]{ Another party acting as an intermediary might get accepted by the payment processor, especially if they disguise themselves. } diff --git a/voting.html.pm b/voting.html.pm index b251225b..46ffe745 100644 --- a/voting.html.pm +++ b/voting.html.pm @@ -280,7 +280,7 @@ With the tokens distributed, you could cast a vote by sending them to predetermi It's easy to give multiple options. For example if you want to be able to differentiate between those who don't care, and those who want to vote but not any candidate, just have an additional "blank" address voters can send to. } -◊img[#:src "/images/voting.png" #:alt "One vote is given out to each person, who then sends it to their voting address of choice."]{ +◊img[#:src "/images/voting.png" #:alt "One vote is given out to each person by the state, who then sends it to their voting address of choice (Hillary or Trump)."]{ Each arrow corresponds to a token transaction and the "Hillary" and "Trump" boxes are addresses. The state is responsible for issuing the voting tokens to the voters and the voters in turn send them to the address they want to vote for. In this example Hillary got 1 vote and Trump got 2, and everyone voted. } diff --git a/what_is_money.html.pm b/what_is_money.html.pm index 888d44f6..88ff2a28 100644 --- a/what_is_money.html.pm +++ b/what_is_money.html.pm @@ -40,13 +40,13 @@ First, let's look at some interesting historical examples of items that have bee ◊money["Shells" #:date "1200 B.C." #:img "/images/cowry.png" - #:alt "Sea shells."]{ + #:alt "Sea shells"]{ Sea shells ◊link[sea-shells]{have been used as money for centuries} and were commonly used in parts of Africa and Asia but also in other parts of the world. In West Africa, they saw ◊link[shell-usage]{significant use until the 20◊sup{th} century}. } ◊money["Coins in ancient Greece" #:date "500 B.C." #:img "images/greek_coin.png" - #:alt "A greek coin."]{ + #:alt "A greek coin"]{ The Greeks ◊link[ancient-greece-coinage]{used coins} made from precious metal like silver, bronze, and gold. They also stamped the coins with beautiful portraits for a truly modern look. } ◊money["Rai stones" @@ -58,7 +58,7 @@ First, let's look at some interesting historical examples of items that have bee ◊money["A 20kg copper coin" #:date "1644" #:img "images/20kg_copper.png" - #:alt "A 20kg copper coin in a wheelbarrow."]{ + #:alt "A 20kg copper coin in a wheelbarrow"]{ Another example of---let's say interesting---form of money is ◊link[largest-coin]{the world's largest coin.} It's a copper coin weighing 20kg, issued in Sweden. Since copper was worth much less than silver, very large coins had to be made to offset the difference. At that time, coins did contain raw materials according to their value, which isn't the case today. @@ -66,7 +66,7 @@ First, let's look at some interesting historical examples of items that have bee ◊money["A 100 billion mark note" #:date "1924" #:img "images/german_notes.png" - #:alt "A large pyramid of paper money."]{ + #:alt "A large pyramid of paper money"]{ Bank notes---paper money---are easy to use but they do have problems of their own. Unless kept in check, by for example ◊link[rel-gold-standard]{the gold standard}, they can be mass produced to cause ◊link[hyperinflation]{hyperinflation}. ◊link[germany-wallpaper]{This is what happened in Germany} after the first World War. They had massive debts after losing the war, so they tried to print enough money to pay off the debts.◊mn{germany-stories} @@ -78,13 +78,13 @@ First, let's look at some interesting historical examples of items that have bee ◊money["Cigarettes in prison" #:date `("20" (sup "th") " century") #:img "images/prison_money.png" - #:alt "A cigarette."]{ + #:alt "A cigarette"]{ Like depicted in the movie Shawshank Redemption cigarettes are used in some prisons ◊link[prison-cigarettes]{as a form of money}. Today, some prisons have started to ban smoking, so they instead use things like ◊link[prison-stamps]{stamps} or ◊link[prison-ramen]{ramen}. } ◊money["Euro bank notes" #:date `("21" (sup "th") " century") #:img "images/bank_notes.png" - #:alt "Euro bank notes."]{ + #:alt "Euro bank notes"]{ There are many kinds of ◊em{fiat currencies},◊mn{fiat-commodity} for example, the Euro. Modern coins aren't made of valuable metal and paper notes are used for large denominations. ◊note-pos[#:top -6 #:bottom -20]{fiat-commodity} @@ -92,13 +92,13 @@ First, let's look at some interesting historical examples of items that have bee ◊money["Dogecoin" #:date "2013" #:img "images/doge.png" - #:alt "Doge."]{ + #:alt "Doge"]{ Dogecoin is a cryptocurrency and while created as a "joke currency" it quickly gained popularity as a tipping tool online. You can still find merchants who accept it today for things like domain names, web hosting, VPNs, or games. } ◊money["Marbles on the school yard" #:date "2017" #:img "images/marbles.png" - #:alt "Two people playing with marbles."]{ + #:alt "Two people playing with marbles"]{ Kids on the school-yard often come up with interesting forms of money. For example, collectible card games or game components. Another example is marbles used in a Swedish game where you win your opponents marbles. (And those with many marbles had higher status in class.)◊mn{pokemon} ◊note-pos[#:bottom -20]{pokemon} @@ -131,7 +131,7 @@ First, let's look at some interesting historical examples of items that have bee [else ""])) `(div ((class "example")) - (img ((src ,img) (alt ,alt))) + (img ((src ,img) (alt ,alt) (role "presentation"))) (div ((class "txt")) (div ((class "header")) (h3 ,title) From 64dbdb46eff4c599ccc5219deaabfff143a39922 Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Wed, 22 Feb 2023 12:35:56 +0100 Subject: [PATCH 33/46] Use
and wrap content in
For hopefully better semantic HTML --- chapter.html.p | 16 +++++++++------- ebook-files/title_page.xhtml | 4 ++-- sass/chapter.scss | 6 +++--- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/chapter.html.p b/chapter.html.p index 22522646..9032b837 100644 --- a/chapter.html.p +++ b/chapter.html.p @@ -55,7 +55,7 @@ -
+
-
-

◊|title|

-

◊|subtitle|

-
+
+
+

◊|title|

+

◊|subtitle|

+
- ◊(->html doc #:splice? #t) + ◊(->html doc #:splice? #t) +
◊(->html (make-section-nav #:section-header? section-chapters-headers? here)) -
+
◊(when side-space? (->html `(div ((class "side-space"))))) diff --git a/ebook-files/title_page.xhtml b/ebook-files/title_page.xhtml index 0cc0a97e..4865ea05 100644 --- a/ebook-files/title_page.xhtml +++ b/ebook-files/title_page.xhtml @@ -8,7 +8,7 @@ -
+

Why cryptocurrencies?

What they are, what they do and why they matter

@@ -28,6 +28,6 @@

All rights reserved.

ISBN: 978-91-986762-1-1

-
+ diff --git a/sass/chapter.scss b/sass/chapter.scss index 65b13411..739035f2 100644 --- a/sass/chapter.scss +++ b/sass/chapter.scss @@ -21,7 +21,7 @@ $sidenote-float-width: 1280px; /* * Header */ -.chapter > header { +.chapter header { h2 { font-weight: normal; font-style: italic; @@ -32,7 +32,7 @@ $sidenote-float-width: 1280px; } } -.chapter > header > .date { +.chapter header > .date { text-align: right; font-size: 0.7rem; margin-top: -0.2rem; @@ -168,7 +168,7 @@ $list-p-margin: 0.6em; } } -.chapter > .subnav { +.chapter .subnav { margin-top: 1.5rem; @extend %sans-serif; From cff69c0e41b605db9129530b7dea16ae7c55601f Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Wed, 22 Feb 2023 12:37:43 +0100 Subject: [PATCH 34/46] Cover page meta --- ebook-files/cover_page.xhtml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ebook-files/cover_page.xhtml b/ebook-files/cover_page.xhtml index 11ce863a..128580c5 100644 --- a/ebook-files/cover_page.xhtml +++ b/ebook-files/cover_page.xhtml @@ -2,8 +2,12 @@ + Why cryptocurrencies? + + +
From 45be00d604f890b660defb836a945638e6fc846d Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Wed, 22 Feb 2023 12:51:24 +0100 Subject: [PATCH 35/46] Use section instead of div in stories and transcripts --- darknet_markets.html.pm | 2 +- freezing_of_merchant_accounts.html.pm | 2 +- uncensorable_donations.html.pm | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/darknet_markets.html.pm b/darknet_markets.html.pm index 68f60350..9ad8328c 100644 --- a/darknet_markets.html.pm +++ b/darknet_markets.html.pm @@ -149,7 +149,7 @@ So if none of those things are available, what can you buy on a darknet market? The following example, based on a real-life story I read a few years ago, illustrates why darknet markets aren't purely evil. -◊div[#:class "story"]{ +◊section[#:class "story"]{ Tom met the love of his life five years ago, when he went to get some of his teeth removed. Hardly the most romantic meeting, with her drilling into his aching teeth, but it was love at first sight. diff --git a/freezing_of_merchant_accounts.html.pm b/freezing_of_merchant_accounts.html.pm index 5c9d178b..c3c50ad9 100644 --- a/freezing_of_merchant_accounts.html.pm +++ b/freezing_of_merchant_accounts.html.pm @@ -30,7 +30,7 @@ This chapter continues on the same idea as the ◊link[prev]{previous one}, but Imagine coming in to work one day and having this conversion with your boss: -◊div[#:class "story"]{ +◊section[#:class "story"]{ ◊trow{I'm sorry John, but we'll pay you in 6 months.} ◊trow{What?} ◊trow{Don't worry, you'll still get your full salary, but we'll pay it in 6 months.} diff --git a/uncensorable_donations.html.pm b/uncensorable_donations.html.pm index d7b218f4..5c71e8c6 100644 --- a/uncensorable_donations.html.pm +++ b/uncensorable_donations.html.pm @@ -220,7 +220,7 @@ This is ◊strong{not} a glorification of WikiLeaks---they have ◊link[wikileak At 2019-08-28 the transcript timestamps are slightly off compared to the full video, I've tried to match them up better. } - ◊div[#:class "transcript-wrapper"]{ + ◊section[#:class "transcript-wrapper"]{ ◊transcript{ 02:34 He's got an RPG [Rocket Propelled Grenade]? From ae23d229358e869b787e5fb487c2e5f556f8963d Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Wed, 22 Feb 2023 12:52:11 +0100 Subject: [PATCH 36/46] Aria roles for fake table --- uncensorable_donations.html.pm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/uncensorable_donations.html.pm b/uncensorable_donations.html.pm index 5c71e8c6..96a6f7a8 100644 --- a/uncensorable_donations.html.pm +++ b/uncensorable_donations.html.pm @@ -589,10 +589,10 @@ This is ◊strong{not} a glorification of WikiLeaks---they have ◊link[wikileak (if (string=? row "\n") "" (let ((cols (string-split row " "))) - `(div ((class "row")) - (span ((class "time")) ,(car cols)) - (span ((class "txt")) ,@(cdr cols)))))) - `(div ((class "transcript")) + `(div ((class "row") (role "row")) + (span ((class "time") (role "cell")) ,(car cols)) + (span ((class "txt") (role "cell")) ,@(cdr cols)))))) + `(div ((class "transcript") (role "grid")) ,@(map make-row rows))) ◊(define execution-of-children From 478e9f53fb44552f38f1a566598ec824794a32b0 Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Wed, 22 Feb 2023 13:02:32 +0100 Subject: [PATCH 37/46] Add aria note role --- rkt/sidenotes.rkt | 2 +- uncensorable_donations.html.pm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rkt/sidenotes.rkt b/rkt/sidenotes.rkt index ca134b5c..87a9a39c 100644 --- a/rkt/sidenotes.rkt +++ b/rkt/sidenotes.rkt @@ -308,7 +308,7 @@ styles))) (string-join styles " "))) - (define attrs `((class "sidenote"))) + (define attrs `((class "sidenote") (role "note"))) ; Remove bottom and top margins that are used for sidenote positioning. ; If the reader overrides font or font size, then we will get overlap between ; sidenotes. We really don't want that, so let's skip these. diff --git a/uncensorable_donations.html.pm b/uncensorable_donations.html.pm index 96a6f7a8..129b1edb 100644 --- a/uncensorable_donations.html.pm +++ b/uncensorable_donations.html.pm @@ -195,7 +195,7 @@ This is ◊strong{not} a glorification of WikiLeaks---they have ◊link[wikileak ◊entry["The Chelsea Manning leaks" #:date "July 5, 2010"]{ - ◊div[#:class "caution"]{First I must caution you: it's very easy to become numb when you read about these leaks. The sheer amount of horror is enough to overwhelm you and might cause your brain to suppress your emotions, maybe out of self-defense. But try to remember that this happened to real people---it's not just a mass of text and numbers. Please don't relegate this as just another forgettable statistic.} + ◊div[#:class "caution" #:role "note"]{First I must caution you: it's very easy to become numb when you read about these leaks. The sheer amount of horror is enough to overwhelm you and might cause your brain to suppress your emotions, maybe out of self-defense. But try to remember that this happened to real people---it's not just a mass of text and numbers. Please don't relegate this as just another forgettable statistic.} Chelsea Manning (formerly Bradley Manning) is a former soldier of the United States who provided WikiLeaks with nearly 750,000 military and diplomatic documents. They were released in batches and spread out over a period of time. Some of the content was absolutely shocking and caused global outrage, I've tried to pick out some notable leaks◊mn{more-leaks}: From 0da196d8a01321ccd76d248e22fe1d3e0e5fe425 Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Wed, 22 Feb 2023 15:01:38 +0100 Subject: [PATCH 38/46] Fix sidenote tests --- rkt/sidenotes.rkt | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/rkt/sidenotes.rkt b/rkt/sidenotes.rkt index 87a9a39c..deae8c94 100644 --- a/rkt/sidenotes.rkt +++ b/rkt/sidenotes.rkt @@ -347,21 +347,30 @@ ;; Like including an "ignore" tag to match only against the most important things, ;; but that's too much work for me now. Meh. (define expected - `((p "One." - (span ((class "sidenote-label")) "1") - " Two." (span ((class "sidenote-label")) "2") - " Three." (span ((class "sidenote-label")) "3")) - (div ((class "sidenote")) (span ((class "sidenote-number")) "1") - "1st") - (div ((class "sidenote")) (span ((class "sidenote-number")) "2") - "2nd") - (ol - (li "a" (span ((class "sidenote-label")) "4")) - (li "b")) - (div ((class "sidenote")) (span ((class "sidenote-number")) "4") - "In list.") - (div ((class "sidenote")) (span ((class "sidenote-number")) "3") - "3rd"))) + '((p + "One." + (sup ((class "sidenote-number")) "1") + " Two." + (sup ((class "sidenote-number")) "2") + " Three." + (sup ((class "sidenote-number")) "3")) + (aside + ((class "sidenote") (role "note")) + (sup ((class "sidenote-number")) "1") + "1st") + (aside + ((class "sidenote") (role "note")) + (sup ((class "sidenote-number")) "2") + "2nd") + (ol (li "a" (sup ((class "sidenote-number")) "4")) (li "b")) + (aside + ((class "sidenote") (role "note")) + (sup ((class "sidenote-number")) "4") + "In list.") + (aside + ((class "sidenote") (role "note")) + (sup ((class "sidenote-number")) "3") + "3rd"))) (check-equal? (decode-sidenotes input) expected) ) From 6cee796b6487e04df150bc448891fff4ee5ccf68 Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Thu, 23 Feb 2023 10:50:36 +0100 Subject: [PATCH 39/46] Sidenotes with note refs --- rkt/sidenotes.rkt | 31 ++++++++++++++++++++++--------- sass/chapter.scss | 10 ++++++---- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/rkt/sidenotes.rkt b/rkt/sidenotes.rkt index deae8c94..bf24c018 100644 --- a/rkt/sidenotes.rkt +++ b/rkt/sidenotes.rkt @@ -4,6 +4,7 @@ (require racket/match racket/string racket/list) (require "string-process.rkt") (require "decode.rkt") +(require "refs.rkt") (require racket/pretty) (provide ndef sn mn note-pos decode-sidenotes clear-sidenotes) @@ -185,7 +186,7 @@ (begin (unless (manual-pos? note) (set! notes-after (cons note notes-after))) - (append (label note) + (append (ref-label note) acc))] ;; Explicit note def expansion. [note-pos-ref @@ -285,20 +286,32 @@ (define pos-ref (ref->pos-ref (note-ref note))) (hash-has-key? note-pos-refs pos-ref)) -(define (label note) - (define sign (note-sign note)) +(define (note-id note) + (to-name (format "~a" (note-ref note)))) + +(define (aside-label note) + (define sign (format "~a" (note-sign note))) (if (eq? sign 'marginnote) `() - `((sup ((class "sidenote-number")) ,(format "~a" sign))))) + `((sup ((class "sidenote-number")) ,sign)))) + +(define (ref-label note) + (define sign (format "~a" (note-sign note))) + (define href (format "#~a"(note-id note))) + (if (eq? sign 'marginnote) + `() + `((a ((epub:type "noteref") (class "sidenote-number") (href ,href)) ,sign)))) (define (expand-sidenote note) + (define ref (note-ref note)) + (define id (note-id note)) (define def (note-def note)) (define top (note-top note)) (define bottom (note-bottom note)) (when (and top (not (number? top))) - (error (format "Not a number: '~a' for sidenote '~a'~n" top (note-ref note)))) + (error (format "Not a number: '~a' for sidenote '~a'~n" top ref))) (when (and bottom (not (number? bottom))) - (error (format "Not a number: '~a' for sidenote '~a'~n" bottom (note-ref note)))) + (error (format "Not a number: '~a' for sidenote '~a'~n" bottom ref))) (define styles (let ((styles `())) @@ -308,7 +321,7 @@ styles))) (string-join styles " "))) - (define attrs `((class "sidenote") (role "note"))) + (define attrs `((epub:type "endnote") (class "sidenote") (role "note") (id ,id))) ; Remove bottom and top margins that are used for sidenote positioning. ; If the reader overrides font or font size, then we will get overlap between ; sidenotes. We really don't want that, so let's skip these. @@ -317,7 +330,7 @@ ; `((style ,styles))))) `(aside ,attrs - ,@(label note) + ,@(aside-label note) ,@def)) ;; A larger test to test the sidenote placement. @@ -327,7 +340,7 @@ ;; These tags are called when the chapter is parsed, and references are inserted in-place. (define 1st (sn "1st")) (define 2nd (sn "2nd")) - (define 3rd (sn "3rd")) + (define 3rd (mn "3rd")) ; Turn marginnotes into sidenotes (define 3rd-pos (note-pos "3rd")) (define list-note (sn "list-note")) diff --git a/sass/chapter.scss b/sass/chapter.scss index 739035f2..84300c0a 100644 --- a/sass/chapter.scss +++ b/sass/chapter.scss @@ -328,7 +328,8 @@ cite.book { } .sidenote, -.sidenote > p { +.sidenote > p, +.sidenote a { @extend %sans-serif; font-size: 0.8rem !important; } @@ -339,10 +340,11 @@ cite.book { padding-right: 0.2rem; } .sidenote-number, -.sidenote-label { +.sidenote-label, +a.sidenote-number { font-family: $sans-serif-font-family; - //vertical-align: super; - font-size: 0.7em; + vertical-align: super; + font-size: 0.7em !important; display: inline-block; //background-color: tomato; } From fc11babbed66331d919ab3ef5c28b2816988af00 Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Fri, 24 Feb 2023 08:59:26 +0100 Subject: [PATCH 40/46] Add dedication page --- ebook-files/content.opf | 2 ++ ebook-files/dedication.xhtml | 17 +++++++++++++++++ rkt/tags.rkt | 2 +- sass/chapter.scss | 5 +++++ 4 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 ebook-files/dedication.xhtml diff --git a/ebook-files/content.opf b/ebook-files/content.opf index e8049789..571f2675 100644 --- a/ebook-files/content.opf +++ b/ebook-files/content.opf @@ -22,6 +22,7 @@ + ◊MANIFEST_POSTS_TAG ◊MANIFEST_IMG_TAG @@ -45,6 +46,7 @@ + ◊SPINE_TOC diff --git a/ebook-files/dedication.xhtml b/ebook-files/dedication.xhtml new file mode 100644 index 00000000..afce17e2 --- /dev/null +++ b/ebook-files/dedication.xhtml @@ -0,0 +1,17 @@ + + + + + + Why cryptocurrencies? + + + + +
+
+

To Veronica, who lights my way in darkness.

+
+
+ + diff --git a/rkt/tags.rkt b/rkt/tags.rkt index b3495bd1..b87e7151 100644 --- a/rkt/tags.rkt +++ b/rkt/tags.rkt @@ -240,7 +240,7 @@ )) (define (epigraph . txt) - `(div ((class "epigraph")) + `(div ((class "epigraph") (epub:type "epigraph")) ,@txt)) (define (qt #:author [author #f] diff --git a/sass/chapter.scss b/sass/chapter.scss index 84300c0a..aa91110e 100644 --- a/sass/chapter.scss +++ b/sass/chapter.scss @@ -1138,3 +1138,8 @@ table.address-message { .flex-50 img { max-width: 50%; } + +.dedication { + text-align: center; + font-style: italic; +} From 085ce8913ef2a80861378df225360d74cf33343c Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Fri, 24 Feb 2023 09:10:20 +0100 Subject: [PATCH 41/46] Add epub:type to pages --- about_the_book.html.pm | 1 + acknowledgements.html.pm | 1 + antifragile.html.pm | 1 + appendix.html.pm | 1 + bitcoin_whitepaper.html.pm | 1 + challenges.html.pm | 1 + chapter.html.p | 26 ++++++++++---------------- cryptography.html.pm | 1 + ebook-files/cover_page.xhtml | 8 +++++--- ebook-files/title_page.xhtml | 26 ++++++++++++++------------ rkt/index.rkt | 6 +++--- 11 files changed, 39 insertions(+), 34 deletions(-) diff --git a/about_the_book.html.pm b/about_the_book.html.pm index d57a8803..3f6f0f2f 100644 --- a/about_the_book.html.pm +++ b/about_the_book.html.pm @@ -6,6 +6,7 @@ ◊(define-meta updated "2021-05-07T19:11:00+01:00") ◊(define-meta uuid "7ea80c78-aff2-46a1-8d05-1253d7033dc6") ◊(define-meta template "chapter.html") +◊(define-meta article-type "introduction") ◊(clear-sidenotes) diff --git a/acknowledgements.html.pm b/acknowledgements.html.pm index acd194e0..309ef215 100644 --- a/acknowledgements.html.pm +++ b/acknowledgements.html.pm @@ -2,6 +2,7 @@ ◊(define-meta title "Acknowledgments") ◊;(define-meta subtitle "A perspective beyond the hype") +◊(define-meta article-type "acknowledgments") ◊(define-meta published "2020-03-09T21:07:17+01:00") ◊(define-meta updated "2021-03-10T19:01:43+01:00") ◊(define-meta uuid "d33953be-5f6c-43b0-a700-eab1e1540447") diff --git a/antifragile.html.pm b/antifragile.html.pm index 9b28877e..c1dafa5a 100644 --- a/antifragile.html.pm +++ b/antifragile.html.pm @@ -6,6 +6,7 @@ ◊(define-meta updated "2021-05-07T19:11:00+01:00") ◊(define-meta uuid "9ce74583-fbbd-42d4-940e-3a9e44ed0658") ◊(define-meta template "chapter.html") +◊(define-meta article-type "appendix") ◊; https://unchained-capital.com/blog/bitcoin-is-antifragile/ ◊; https://cryptofundamental.com/in-pursuit-of-lindycoin-212bacafc395?gi=416e2a7a461c diff --git a/appendix.html.pm b/appendix.html.pm index 4e2247c9..d18eb8cb 100644 --- a/appendix.html.pm +++ b/appendix.html.pm @@ -5,6 +5,7 @@ ◊(define-meta no-side-space #t) ◊(define-meta no-section-chapters-header #t) ◊(define-meta extra-article-class "appendix") +◊(define-meta article-type "appendix") ◊(define-meta skip-feed #t) ◊(define-meta template "chapter.html") diff --git a/bitcoin_whitepaper.html.pm b/bitcoin_whitepaper.html.pm index 2b4e3990..ee21cdc0 100644 --- a/bitcoin_whitepaper.html.pm +++ b/bitcoin_whitepaper.html.pm @@ -6,6 +6,7 @@ ◊(define-meta updated "2021-05-07T19:11:00+01:00") ◊(define-meta uuid "581c4917-d862-49cb-9d01-495a9106081b") ◊(define-meta template "chapter.html") +◊(define-meta article-type "appendix") ◊(clear-sidenotes) diff --git a/challenges.html.pm b/challenges.html.pm index 38eac703..3a141dad 100644 --- a/challenges.html.pm +++ b/challenges.html.pm @@ -6,6 +6,7 @@ ◊(define-meta updated "2021-05-07T19:11:00+01:00") ◊(define-meta uuid "c13d8405-fb3e-411c-b035-aae08eedddf1") ◊(define-meta template "chapter.html") +◊(define-meta article-type "appendix") ◊(clear-sidenotes) diff --git a/chapter.html.p b/chapter.html.p index 9032b837..ae2d9ecd 100644 --- a/chapter.html.p +++ b/chapter.html.p @@ -19,10 +19,17 @@ ◊(define side-space? (not (select-from-metas 'no-side-space here))) ◊(define section-chapters-headers? (not (select-from-metas 'no-section-chapters-header here))) ◊(define article-class + ; This used to be on
but is now on main. Meh. (let ((extra (select-from-metas 'extra-article-class here))) (if extra (string-append "chapter " extra) "chapter"))) +◊(define article-type + (let ((type (select-from-metas 'article-type here))) + (if type + type + "chapter"))) + ◊(define prev-page (let ((p (previous here))) (if (equal? p 'index.html) @@ -63,10 +70,10 @@ ◊(ref parent-page parent-title parent-title) } -
+
-

◊|title|

-

◊|subtitle|

+

◊|title|

+

◊|subtitle|

◊(->html doc #:splice? #t) @@ -78,19 +85,6 @@ ◊(when side-space? (->html `(div ((class "side-space"))))) - -