diff --git a/.docker/Dockerfile b/.docker/Dockerfile index dd46fb4b5a..caab63bba5 100644 --- a/.docker/Dockerfile +++ b/.docker/Dockerfile @@ -16,10 +16,10 @@ RUN VERSION=$(grep -A 1 'BUNDLED WITH' Gemfile.lock | tail -n 1 | xargs); \ RUN apt update && apt install -y python3 python3-pip # install python packages -RUN python3 -m pip install --upgrade --requirement requirements.txt +RUN python3 -m pip install --no-cache-dir --upgrade --requirement requirements.txt # install python package for listening for file changes -RUN pip install "watchdog[watchmedo]" +RUN pip install "watchdog[watchmedo]==3.0.0" # ports used by jekyll EXPOSE 4000 diff --git a/.docker/entrypoint.sh b/.docker/entrypoint.sh index 2b734e3e3a..77c697aa85 100755 --- a/.docker/entrypoint.sh +++ b/.docker/entrypoint.sh @@ -6,19 +6,22 @@ echo "" ls echo "" -# run jekyll serve in hot-reload mode. -# rerun whenever _config.yaml changes (jekyll hot-reload doesn't work with this file). +# run cite process +python3 _cite/cite.py + +# run jekyll serve in hot-reload mode +# rerun whenever _config.yaml changes (jekyll hot-reload doesn't work with this file) watchmedo auto-restart \ --debug-force-polling \ --patterns="_config.yaml" \ --signal SIGTERM \ -- bundle exec jekyll serve --open-url --force_polling --livereload --trace --host=0.0.0.0 \ - | sed 's/0.0.0.0/localhost/g' & + | sed "s/LiveReload address.*//g;s/0.0.0.0/localhost/g" & -# run cite process. -# rerun whenever _data files change. +# rerun cite process whenever _data files change watchmedo shell-command \ --debug-force-polling \ --recursive \ + --wait \ --command="python3 _cite/cite.py" \ --patterns="_data/sources*;_data/orcid*;_data/pubmed*;_data/google-scholar*" \ diff --git a/.github/user_pull_request_template.md b/.github/user_pull_request_template.md new file mode 100644 index 0000000000..00a0e7117c --- /dev/null +++ b/.github/user_pull_request_template.md @@ -0,0 +1,4 @@ +This website is based on the Lab Website Template. +See its documentation for working with this site: + +https://greene-lab.gitbook.io/lab-website-template-docs diff --git a/.github/workflows/build-preview.yaml b/.github/workflows/build-preview.yaml index f363fe938e..52842860fe 100644 --- a/.github/workflows/build-preview.yaml +++ b/.github/workflows/build-preview.yaml @@ -21,6 +21,7 @@ jobs: runs-on: ubuntu-latest steps: + # for debugging - name: Print contexts uses: crazy-max/ghaction-dump-context@v1 diff --git a/.github/workflows/build-site.yaml b/.github/workflows/build-site.yaml index a7c36dd69d..9b71767f07 100644 --- a/.github/workflows/build-site.yaml +++ b/.github/workflows/build-site.yaml @@ -20,6 +20,7 @@ jobs: runs-on: ubuntu-latest steps: + # for debugging - name: Print contexts uses: crazy-max/ghaction-dump-context@v1 diff --git a/.github/workflows/first-time-setup.yaml b/.github/workflows/first-time-setup.yaml index 0b867cf5bf..0199ac9ef5 100644 --- a/.github/workflows/first-time-setup.yaml +++ b/.github/workflows/first-time-setup.yaml @@ -13,6 +13,7 @@ jobs: runs-on: ubuntu-latest steps: + # for debugging - name: Print contexts uses: crazy-max/ghaction-dump-context@v1 @@ -28,9 +29,11 @@ jobs: with: ref: gh-pages + # clean slate, as if starting from orphan branch - name: Clear Pages branch - run: rm -rf * .github .gitignore + run: rm -rf * .* + # prevent GitHub from running Jekyll a second time after build - name: Make .nojekyll file run: touch .nojekyll @@ -46,15 +49,18 @@ jobs: - name: Checkout main branch uses: actions/checkout@v3 - - name: Remove unneeded files + - name: Remove files user doesn't need run: | rm -rf \ - README.md \ CHANGELOG.md \ testbed.md \ .github/ISSUE_TEMPLATE \ .github/workflows/versioning.yaml \ .github/pull_request_template.md \ + + - name: Rename files + run: \ + mv .github/user_pull_request_template.md .github/pull_request_template.md - name: Set vars for personalization run: | @@ -73,25 +79,22 @@ jobs: _Built with [Lab Website Template](https://greene-lab.gitbook.io/lab-website-template-docs)_ " > README.md - - name: Install packages - run: yarn add yaml - - name: Personalize Jekyll config for user uses: actions/github-script@v6 with: script: | const { readFileSync, writeFileSync } = require("fs"); - const { parse, stringify } = require("yaml"); const file = "_config.yaml"; - const config = parse(readFileSync(file).toString()); - config.title = "${{ env.USER }}"; - config.description = "${{ env.DESCRIPTION }}"; - config.email = "contact@${{ env.USER }}.com"; - config.github = "${{ env.USER }}"; - config.twitter = "${{ env.USER }}"; - config.instagram = "${{ env.USER }}"; - config.youtube = "${{ env.USER }}"; - writeFileSync(file, stringify(config)); + const contents = readFileSync(file) + .toString() + .replace(/(^title: ).*$/m, "$1${{ env.USER }}") + .replace(/(^subtitle: ).*$/m, "$1") + .replace(/(^description: ).*$/m, "$1${{ env.DESCRIPTION }}") + .replace(/(^ email: ).*$/m, "$1contact@${{ env.USER }}.com") + .replace(/(^ github: ).*$/m, "$1${{ env.USER }}") + .replace(/(^ twitter: ).*$/m, "$1${{ env.USER }}") + .replace(/(^ youtube: ).*$/m, "$1${{ env.USER }}"); + writeFileSync(file, contents); - name: Personalize homepage for user uses: actions/github-script@v6 diff --git a/.github/workflows/update-citations.yaml b/.github/workflows/update-citations.yaml index 21775acfec..2bafb55257 100644 --- a/.github/workflows/update-citations.yaml +++ b/.github/workflows/update-citations.yaml @@ -28,6 +28,7 @@ jobs: timeout-minutes: 15 steps: + # for debugging - name: Print contexts uses: crazy-max/ghaction-dump-context@v1 diff --git a/.github/workflows/update-url.yaml b/.github/workflows/update-url.yaml index f1aba59193..9ccd9a3eb4 100644 --- a/.github/workflows/update-url.yaml +++ b/.github/workflows/update-url.yaml @@ -19,6 +19,7 @@ jobs: runs-on: ubuntu-latest steps: + # for debugging - name: Print contexts uses: crazy-max/ghaction-dump-context@v1 @@ -31,6 +32,7 @@ jobs: - name: Checkout branch contents uses: actions/checkout@v3 + # update link to site in readme - name: Update readme uses: actions/github-script@v6 with: diff --git a/.github/workflows/versioning.yaml b/.github/workflows/versioning.yaml index e76dc24534..386cc8dafc 100644 --- a/.github/workflows/versioning.yaml +++ b/.github/workflows/versioning.yaml @@ -20,6 +20,7 @@ jobs: github.event_name == 'pull_request' runs-on: ubuntu-latest steps: + # for debugging - name: Print contexts uses: crazy-max/ghaction-dump-context@v1 @@ -54,10 +55,10 @@ jobs: ); const changelog = readFileSync("pr/CHANGELOG.md") .toString() - .split(/^##?#?#?/m) + .split(/^## /m) .map((section) => { const [heading, ...body] = section.split("\n"); - return { heading, body: body.join("\n") }; + return [heading.trim(), body.join("\n").trim()]; }); // check version @@ -71,8 +72,8 @@ jobs: // check changelog const newSection = changelog.find( - ({ heading, body }) => - heading.includes(newVersion) && heading.includes(newDate) && body.trim() + ([heading, body]) => + heading.includes(newVersion) && heading.includes(newDate) && body ); if (!newSection) throw Error("Changelog not updated or not valid"); @@ -83,6 +84,7 @@ jobs: github.event_name == 'push' runs-on: ubuntu-latest steps: + # for debugging - name: Print contexts uses: crazy-max/ghaction-dump-context@v1 @@ -106,24 +108,30 @@ jobs: ); const changelog = readFileSync("CHANGELOG.md") .toString() - .split(/^##?#?#?/m) + .split(/^## /m) .map((section) => { const [heading, ...body] = section.split("\n"); - return { heading, body: body.join("\n") }; + return [heading.trim(), body.join("\n").trim()]; }); // find changelog body for version - const body = + const [, body = ""] = changelog.find( - ({ heading }) => heading.includes(version) && heading.includes(date) - )?.body || ""; + ([heading]) => heading.includes(version) && heading.includes(date) + ) || []; return { version, body }; - - name: Create tag and GitHub release + - name: Create tag + id: tag + uses: mathieudutour/github-tag-action@v6.1 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + custom_tag: ${{ fromJson(steps.version.outputs.result).version }} + + - name: Create GitHub release uses: ncipollo/release-action@v1 with: - commit: ${{ github.ref }} - tag: v${{ fromJson(steps.version.outputs.result).version }} - name: v${{ fromJson(steps.version.outputs.result).version }} + tag: ${{ fromJson(steps.version.outputs.result).version }} + name: ${{ fromJson(steps.version.outputs.result).version }} body: ${{ fromJson(steps.version.outputs.result).body }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c941fa8ae..cc6624a1f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,23 @@ Reference: common-changelog.org +## 1.1.1 - 2023-04-06 + +### Changed + +- Change member profile page from col layout to float. +- Fix first time setup. Preserve config formatting and comments. +- Improve Docker cite process behavior. +- Fix post excerpt component start/end markers and special search attr chars. +- Fix misc CSS. + +### Added + +- Add show-title and show-subtitle site config options. +- Include site subtitle in description meta tag. +- Add user pull request template. +- Add title and link fallbacks to citation component. + ## 1.1.0 - 2023-03-17 Add alert component, Docker support, accessibility fixes. diff --git a/CITATION.cff b/CITATION.cff index 1365e8e624..5266ebc85c 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -1,8 +1,8 @@ # citation metadata for the template itself title: "Lab Website Template" -version: 1.1.0 -date-released: 2023-03-17 +version: 1.1.1 +date-released: 2023-04-06 url: "https://github.com/greenelab/lab-website-template" authors: - family-names: "Rubinetti" diff --git a/_cite/cite.py b/_cite/cite.py index d6586c5cae..940054a0b4 100644 --- a/_cite/cite.py +++ b/_cite/cite.py @@ -1,3 +1,7 @@ +""" +cite process to convert sources and metasources into full citations +""" + from importlib import import_module from pathlib import Path from dotenv import load_dotenv @@ -85,11 +89,11 @@ # merge sources with matching (non-blank) ids for a in range(0, len(sources)): - id = sources[a].get("id") - if not id: + _id = sources[a].get("id") + if not _id: continue for b in range(a + 1, len(sources)): - if sources[b].get("id") == id: + if sources[b].get("id") == _id: sources[a].update(sources[b]) sources[b] = {} sources = [entry for entry in sources if entry] @@ -113,15 +117,15 @@ citation = {} # source id - id = source.get("id", "").strip() + _id = source.get("id", "").strip() # Manubot doesn't work without an id - if id: + if _id: log("Using Manubot to generate citation", 1) try: # run Manubot and set citation - citation = cite_with_manubot(source) + citation = cite_with_manubot(_id) except Exception as e: # if manually-entered source, throw error on cite failure diff --git a/_cite/plugins/google-scholar.py b/_cite/plugins/google-scholar.py index 7132e5af7a..0a05a00568 100644 --- a/_cite/plugins/google-scholar.py +++ b/_cite/plugins/google-scholar.py @@ -42,15 +42,14 @@ def query(): for work in response: # create source - source = {} - - # format source fields - source["id"] = work.get("citation_id", "") - source["title"] = work.get("title", "") - source["authors"] = list(map(str.strip, work.get("authors", "").split(","))) - source["publisher"] = work.get("publication", "") - source["date"] = work.get("year", "") + "-01-01" - source["link"] = work.get("link", "") + source = { + "id": work.get("citation_id", ""), + "title": work.get("title", ""), + "authors": list(map(str.strip, work.get("authors", "").split(","))), + "publisher": work.get("publication", ""), + "date": work.get("year", "") + "-01-01", + "link": work.get("link", ""), + } # copy fields from entry to source source.update(entry) diff --git a/_cite/util.py b/_cite/util.py index c46ea0c241..570426278c 100644 --- a/_cite/util.py +++ b/_cite/util.py @@ -1,3 +1,7 @@ +""" +utility functions for cite process and plugins +""" + import subprocess import json import yaml @@ -64,7 +68,7 @@ def list_of_dicts(data): check if data is list of dicts """ - return type(data) == list and all(type(entry) == dict for entry in data) + return isinstance(data, list) and all(isinstance(entry, dict) for entry in data) def format_date(date): @@ -144,17 +148,14 @@ def save_data(path, data): @log_cache @cache.memoize(name="manubot", expire=90 * (60 * 60 * 24)) -def cite_with_manubot(source): +def cite_with_manubot(_id): """ - generate citation data for source with Manubot + generate citation data for source id with Manubot """ - # source id - id = source.get("id") - # run Manubot try: - commands = ["manubot", "cite", id, "--log-level=WARNING"] + commands = ["manubot", "cite", _id, "--log-level=WARNING"] output = subprocess.Popen(commands, stdout=subprocess.PIPE).communicate() except Exception as e: log(e, 3) @@ -170,7 +171,7 @@ def cite_with_manubot(source): citation = {} # original id - citation["id"] = id + citation["id"] = _id # title citation["title"] = manubot.get("title", "") diff --git a/_includes/citation.html b/_includes/citation.html index 7387d3823a..ea62b17ed3 100644 --- a/_includes/citation.html +++ b/_includes/citation.html @@ -8,7 +8,9 @@
{% if include.style == "rich" %} @@ -25,8 +27,13 @@ {% assign type = site.data.types[citation.type] %} {% include icon.html icon=type.icon %} - - {{ citation.title }} + + {{ citation.title | default: "[no title info]" }}
+
{% for param in include %} {% assign key = param[0] %}
{{ include[key] | markdownify }}
diff --git a/_includes/header.html b/_includes/header.html index 3ea4dd80e9..967078cedf 100644 --- a/_includes/header.html +++ b/_includes/header.html @@ -26,12 +26,12 @@ {% endif %} {% endif %} - {% if site["logo-text"] != false %} + {% if site.logo-text != false %} - {% if site.title %} + {% if site.title and site.show-title != false %} {{ site.title }} {% endif %} - {% if site.subtitle %} + {% if site.subtitle and site.show-subtitle != false %} {{ site.subtitle }} {% endif %} diff --git a/_includes/meta.html b/_includes/meta.html index 087bb94106..dabae0723e 100644 --- a/_includes/meta.html +++ b/_includes/meta.html @@ -19,6 +19,11 @@ {% assign subtitle = site.subtitle %} {% assign description = page.description | default: site.description %} +{% if site.subtitle %} + {% capture description -%} + {{ site.subtitle }}. {{ description }} + {%- endcapture %} +{% endif %} {% assign url = site.location %} {% assign png = "images/icon.png" | file_exists %} diff --git a/_includes/post-excerpt.html b/_includes/post-excerpt.html index 3e380e6d53..5b7d811eeb 100644 --- a/_includes/post-excerpt.html +++ b/_includes/post-excerpt.html @@ -19,12 +19,17 @@ {% assign excerpt = post.content | default: "" - | regex_scan: "(.*)" + | regex_scan: "(.*)", true | default: post.excerpt | default: "" | strip_html %} -

+ {% assign search = post.content + | strip_html + | strip_newlines + | regex_strip + %} +

{{ excerpt }}

diff --git a/_includes/tags.html b/_includes/tags.html index 707ec31994..fb16266d50 100644 --- a/_includes/tags.html +++ b/_includes/tags.html @@ -1,5 +1,5 @@ {% assign tags = include.tags - | array_hash + | object_items | join: "," | split: "," | array_filter diff --git a/_layouts/member.html b/_layouts/member.html index 4a926b00c7..23b665646e 100644 --- a/_layouts/member.html +++ b/_layouts/member.html @@ -2,7 +2,7 @@ layout: default --- -{% capture col1 %} +{% capture floatcontent %} {% include portrait.html lookup=page.slug %} @@ -10,13 +10,13 @@ {% for link in page.links %} {% assign key = link[0] %} {% assign value = link[1] %} - {% include button.html type=key link=value style="bare" %} + {% include button.html type=key link=value style="bare" %}
{% endfor %}
{% endcapture %} -{% capture col2 %} +{% include float.html content=floatcontent %} {{ content }} @@ -33,7 +33,7 @@ {%- endcapture %} - See {{ page.name | default: page.title }}'s papers on the Research page + Search for {{ page.name | default: page.title }}'s papers on the Research page {% capture search -%} @@ -45,7 +45,3 @@ See {{ page.name | default: page.title }}'s posts on the Blog page --> - -{% endcapture %} - -{% include cols.html col1=col1 col2=col2 %} diff --git a/_plugins/array.rb b/_plugins/array.rb index 7404571a1d..e41006e126 100644 --- a/_plugins/array.rb +++ b/_plugins/array.rb @@ -2,16 +2,14 @@ module Jekyll module ArrayFilters - def array_hash(array) - return array.is_a?(Hash) ? array.keys : array - end - + # filter out empty entries from array def array_filter(array) return array .map{|x| x.is_a?(String) ? x.strip() : x} .select{|x| x and x != ""} end + # omit middle items of array with ellipsis, leave N items on either side def array_carve(array, length = 3) if array.length <= length * 2 return array diff --git a/_plugins/file.rb b/_plugins/file.rb index 37a3d1f06e..32a0af2466 100644 --- a/_plugins/file.rb +++ b/_plugins/file.rb @@ -2,11 +2,14 @@ module Jekyll module FileFilters + # check if file exists def file_exists(file) path = File.join(Dir.getwd, file) + # pass back filename if exists return File.file?(path) ? file : nil end + # read text contents of file def file_read(file) path = File.join(Dir.getwd, file) return File.file?(path) ? File.read(path) : nil diff --git a/_plugins/hash.rb b/_plugins/hash.rb index fc4bf47022..23445898ab 100644 --- a/_plugins/hash.rb +++ b/_plugins/hash.rb @@ -2,15 +2,18 @@ module Jekyll module HashFilters + # merge main hash with another hash of defaults def hash_default(hash, defaults) if not hash.is_a?(Hash) or not defaults.is_a?(Hash) return hash end defaults.each do |key, value| - if value.include?"$VALUE" + # substitute main string into default string and set main item + if value.is_a?(String) and value.include?"$VALUE" if hash[key].is_a?(String) hash[key] = value.sub"$VALUE", hash[key] end + # set main item to default item if not defined else if hash[key] == nil or !hash.key?(key) hash[key] = value @@ -19,10 +22,6 @@ def hash_default(hash, defaults) end return hash end - - def hash_keys(hash) - return hash.is_a?(Hash) ? hash.keys : [] - end end end diff --git a/_plugins/misc.rb b/_plugins/misc.rb index 5cd6ae79cc..6b4cb0fc8d 100644 --- a/_plugins/misc.rb +++ b/_plugins/misc.rb @@ -2,10 +2,22 @@ module Jekyll module MiscFilters + # fallback if value unspecified def is_nil(value, fallback) return value == nil ? fallback : value end + # get list of hash keys or array entries + def object_items(object) + if object.is_a?(Hash) + return object.keys + elsif object.is_a?(Array) + return object + end + return [] + end + + # filter a list of hashes by comma-sep'd field:value pairs def data_filter(data, filters) if not data.is_a?(Array) or not filters.is_a?(String) return data @@ -13,8 +25,10 @@ def data_filter(data, filters) data = data.clone for filter in array_filter(filters.split(",")) key, value = array_filter(filter.split(":")) + # find unspecified fields if value == nil data.select!{|d| d[key] == nil} + # find fields that match regex elsif value.is_a?(String) data.select!{|d| d[key].to_s =~ /#{value}/m} end @@ -22,21 +36,22 @@ def data_filter(data, filters) return data end + # from css text, find font family definitions and construct google font url def google_fonts(css) - names = regex_scan(css, '--\S*:\s*"(.*)",?.*;', true).sort.uniq - weights = regex_scan(css, '--\S*:\s(\d{3});', true).sort.uniq - string = "https://fonts.googleapis.com/css2?display=swap&" + names = regex_scan(css, '--\S*:\s*"(.*)",?.*;', false, true).sort.uniq + weights = regex_scan(css, '--\S*:\s(\d{3});', false, true).sort.uniq + url = "https://fonts.googleapis.com/css2?display=swap&" for name in names do name.sub!" ", "+" - string += "&family=#{name}:ital,wght@" + url += "&family=#{name}:ital,wght@" for ital in [0, 1] do for weight in weights do - string += "#{ital},#{weight};" + url += "#{ital},#{weight};" end end - string.delete_suffix!(";") + url.delete_suffix!(";") end - return string + return url end end end diff --git a/_plugins/regex.rb b/_plugins/regex.rb index f29dcf10d3..f7cd02e27a 100644 --- a/_plugins/regex.rb +++ b/_plugins/regex.rb @@ -2,8 +2,10 @@ module Jekyll module RegexFilters - def regex_scan(string, search, all = false) - matches = string.scan(/#{search}/).flatten + # search string for regex capture group, return first or all matches + def regex_scan(string, search, multi = false, all = false) + regex = multi ? /#{search}/m : /#{search}/ + matches = string.scan(regex).flatten if matches.length return all ? matches : matches[0] else @@ -11,9 +13,15 @@ def regex_scan(string, search, all = false) end end + # find regex capture group in string and replace def regex_replace(string, search, replace) return string.gsub(/#{search}/m, replace) end + + # strip all non-letter and non-number characters from string + def regex_strip(string) + return string.gsub(/[^\p{L}\p{N}]/u, " ") + end end end diff --git a/_styles/card.scss b/_styles/card.scss index 2686ea19eb..57fe20df78 100644 --- a/_styles/card.scss +++ b/_styles/card.scss @@ -23,6 +23,7 @@ .card-image img { aspect-ratio: 3 / 2; object-fit: cover; + width: 100%; // box-shadow: var(--shadow); } @@ -32,6 +33,7 @@ align-items: center; flex-direction: column; gap: 20px; + max-width: 100%; padding: 20px; } diff --git a/_styles/code.scss b/_styles/code.scss index 9b9ba272de..79ada5e085 100644 --- a/_styles/code.scss +++ b/_styles/code.scss @@ -20,8 +20,6 @@ code.highlighter-rouge { div.highlighter-rouge { width: 100%; margin: 40px 0; - background: #202020; - color: white; border-radius: var(--rounded); overflow-x: auto; overflow-y: auto; @@ -33,6 +31,7 @@ div.highlighter-rouge { pre.highlight { width: fit-content; + min-width: 100%; margin: 0; padding: 20px; color: var(--white); diff --git a/_styles/header.scss b/_styles/header.scss index 09506b4254..4d2519927d 100644 --- a/_styles/header.scss +++ b/_styles/header.scss @@ -5,7 +5,6 @@ $logo-big: 80px; $logo: 40px; $big-padding: 100px; $collapse: 700px; -$limit-title: 400px; $sticky: true; header { @@ -65,7 +64,7 @@ header a { // subtitle .title > *:last-child { - color: var(--gray); + opacity: 0.65; font-weight: var(--thin); } @@ -168,13 +167,3 @@ header[data-big] { font-size: var(--large); } } - -@media (max-width: $limit-title) { - .title > *:first-child { - font-size: var(--medium); - } - - .title > *:not(:first-child) { - display: none; - } -} diff --git a/_styles/portrait.scss b/_styles/portrait.scss index cff819e9af..322e516ca4 100644 --- a/_styles/portrait.scss +++ b/_styles/portrait.scss @@ -30,6 +30,7 @@ } .portrait-image { + width: 100%; aspect-ratio: 1 / 1; border-radius: 999px; object-fit: cover; diff --git a/_styles/post-excerpt.scss b/_styles/post-excerpt.scss index 853d45e881..6e57a105ce 100644 --- a/_styles/post-excerpt.scss +++ b/_styles/post-excerpt.scss @@ -17,11 +17,15 @@ margin: 0 !important; } -.post-excerpt > *:first-child { - font-weight: var(--semi-bold); +.post-excerpt > a:first-child { width: 100%; + font-weight: var(--semi-bold); } .post-excerpt > div { justify-content: flex-start; } + +.post-excerpt > p { + width: 100%; +} diff --git a/index.md b/index.md index c31802641a..bea698059b 100644 --- a/index.md +++ b/index.md @@ -51,7 +51,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor i {% include button.html - link="tools" + link="projects" text="Browse our projects" icon="fa-solid fa-arrow-right" flip=true diff --git a/testbed.md b/testbed.md index 46210dd33b..3c95e91bb7 100644 --- a/testbed.md +++ b/testbed.md @@ -315,11 +315,11 @@ With Markdown images ![image](https://iiif.elifesciences.org/lax:32822%2Felife-32822-fig8-v3.tif/full/863,/0/default.webp) -![image](/images/icon.png) +![image]({{ "/images/icon.png" | relative_url }}) -![image](/images/icon.png) +![image]({{ "/images/icon.png" | relative_url }}) -![image](/images/icon.png) +![image]({{ "/images/icon.png" | relative_url }}) {% endcapture %} {% include grid.html content=content %}