diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 91d4bdc..0000000 Binary files a/.DS_Store and /dev/null differ diff --git a/.github/workflows/jekyll.yml b/.github/workflows/jekyll.yml index 68520b5..94c923c 100644 --- a/.github/workflows/jekyll.yml +++ b/.github/workflows/jekyll.yml @@ -33,6 +33,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + with: + submodules: recursive - name: Setup Ruby uses: ruby/setup-ruby@8575951200e472d5f2d95c625da0c7bec8217c42 # v1.161.0 with: @@ -41,7 +43,7 @@ jobs: cache-version: 0 # Increment this number if you need to re-download cached gems - name: Setup Pages id: pages - uses: actions/configure-pages@v5 + uses: actions/configure-pages@v4 - name: Build with Jekyll # Outputs to the './_site' directory by default run: bundle exec jekyll build --baseurl "${{ steps.pages.outputs.base_path }}" diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..2248b3d --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "dogwood"] + path = dogwood + url = git@github.com:osmus/dogwood.git diff --git a/.ruby-version b/.ruby-version deleted file mode 100644 index 711ee4f..0000000 --- a/.ruby-version +++ /dev/null @@ -1 +0,0 @@ -3.1.3 \ No newline at end of file diff --git a/Gemfile b/Gemfile index e8bef19..f61e706 100644 --- a/Gemfile +++ b/Gemfile @@ -1,10 +1,17 @@ -# frozen_string_literal: true - source "https://rubygems.org" -# these gems aren't published so we need to tell ruby where they're located -gem "absolute-urls", path: "_plugins/absolute-urls" -gem "post-aliases", path: "_plugins/post-aliases" -gem "unwrap-img", path: "_plugins/unwrap-img" +gem "rake" + +gem "jekyll", "~> 4.3.3" + +group :jekyll_plugins do + gem "jekyll-feed", "~> 0.12" +end + +# theme +gem "osmus-dogwood", path: "dogwood" -gemspec \ No newline at end of file +# theme plugins +gem "absolute-urls", path: "./dogwood/_plugins/absolute-urls" +gem "post-aliases", path: "./dogwood/_plugins/post-aliases" +gem "unwrap-img", path: "./dogwood/_plugins/unwrap-img" diff --git a/_config.yml b/_config.yml index e2a765c..5902ab7 100644 --- a/_config.yml +++ b/_config.yml @@ -4,11 +4,10 @@ permalink: /:title/ # Include "future" posts so that upcoming events will display. Posts cannot be scheduled to automatically # publish at a certain time with Jekyll alone. logo: /img/MM_white_typography.svg -# logo_mono: /img/logo-mono.svg +logo_mono: /img/MM_white_typography.svg future: true # timezone: America/New_York -# github: osmus/dogwood -# mastodon: https://en.osm.town/@OpenStreetMapUS +mastodon: false twitter: TheMissingMaps youtube_page: c/themissingmaps facebook: TheMissingMaps @@ -25,23 +24,12 @@ links: - link: /events label: Missing Maps Events a_class: button bordered + +# Build settings +theme: osmus-dogwood plugins: - - jekyll-archives - - jekyll-include-cache -jekyll-archives: - enabled: - - tags - - month - - year - layouts: - tag: archives/posts-tag - year: archives/posts-year - month: archives/month - permalinks: - tag: '/tags/:name/' - month: '/:year/:month/' - year: '/:year/' -date_format: "%b %e, %Y" + - jekyll-feed + collections: feeds: output: true @@ -81,4 +69,4 @@ defaults: values: permalink: /blog/:year/:month/:title/ category: "Blog" - layout: "post" \ No newline at end of file + layout: "post" diff --git a/_config_production.yml b/_config_production.yml deleted file mode 100644 index 6c5347e..0000000 --- a/_config_production.yml +++ /dev/null @@ -1,2 +0,0 @@ -url: https://osmus.github.io -baseurl: /dogwood \ No newline at end of file diff --git a/_includes/analytics.html b/_includes/analytics.html deleted file mode 100644 index c2ca5a8..0000000 --- a/_includes/analytics.html +++ /dev/null @@ -1,3 +0,0 @@ - \ No newline at end of file diff --git a/_includes/body_classes.html b/_includes/body_classes.html deleted file mode 100644 index 83196a4..0000000 --- a/_includes/body_classes.html +++ /dev/null @@ -1,19 +0,0 @@ -{%- if page.layout -%} - layout-{{page.layout}} -{%- endif %} -{% if page.image -%} - has-image -{%- endif %} -{% if page.cover -%} - has-cover -{%- endif %} -{% assign path_parts = page.url | remove_first: '/' | remove_last: '/' | split: '/' -%} -{%- assign componenturl = '/' -%} -{%- for part in path_parts -%} - {%- assign componenturl = componenturl | append: part | append: '/' -%} - {%- assign componentpage = site.documents | find: 'url', componenturl -%} - {%- if componentpage and componentpage.title %} - page-{{ componentpage.title | slugify }} - {% endif -%} -{%- endfor %} -ispage-{{ page.title | slugify }} \ No newline at end of file diff --git a/_includes/breadcrumbs.html b/_includes/breadcrumbs.html deleted file mode 100644 index 19310d8..0000000 --- a/_includes/breadcrumbs.html +++ /dev/null @@ -1,36 +0,0 @@ - \ No newline at end of file diff --git a/_includes/cover.html b/_includes/cover.html deleted file mode 100644 index 0f4b20c..0000000 --- a/_includes/cover.html +++ /dev/null @@ -1,21 +0,0 @@ -{%- assign cover_image=page.cover | default: page.image -%} -{%- if cover_image or page.youtube or page.podbean or page.video_src -%} -
-
- {%- if page.video_src -%} - - {%- elsif page.youtube -%} - - {%- elsif page.podbean -%} - - {%- elsif cover_image -%} -
- - {%- if page.caption -%} -
{{page.caption | markdownify}}
- {%- endif -%} -
- {%- endif -%} -
-
-{%- endif -%} \ No newline at end of file diff --git a/_includes/custom-scripts.html b/_includes/custom-scripts.html deleted file mode 100644 index 914ac2f..0000000 --- a/_includes/custom-scripts.html +++ /dev/null @@ -1,3 +0,0 @@ - \ No newline at end of file diff --git a/_includes/footer.html b/_includes/footer.html deleted file mode 100644 index 39c1420..0000000 --- a/_includes/footer.html +++ /dev/null @@ -1,81 +0,0 @@ - diff --git a/_includes/head.html b/_includes/head.html deleted file mode 100644 index 88a592b..0000000 --- a/_includes/head.html +++ /dev/null @@ -1,4 +0,0 @@ - - {% include page_meta.html %} - {% include_cached site_meta.html %} - \ No newline at end of file diff --git a/_includes/inline_avatar.html b/_includes/inline_avatar.html deleted file mode 100644 index 7288da5..0000000 --- a/_includes/inline_avatar.html +++ /dev/null @@ -1,9 +0,0 @@ -{%- assign img = include.item.image -%} -{%- if img -%} - {%- assign first = img | slice: 0, 12 -%} - {%- if first == '/img/people/' -%} - {%- assign body = img | slice: 12, 1000 -%} - {%- assign img = "/img-thumbnails/people/" | append: body | append: ".webp" -%} - {%- endif -%} -{%- endif -%} - diff --git a/_includes/item_list.html b/_includes/item_list.html deleted file mode 100644 index eee952b..0000000 --- a/_includes/item_list.html +++ /dev/null @@ -1,109 +0,0 @@ -{% assign _items = include.items %} -{% assign collection = include.collection | default: _items.first.collection %} -{% assign category = _items.first.categories.first | slugify %} - -{%- assign show_image=true -%} -{%- assign image_length = _items | map: "image" | join: "" | strip_html | strip | size -%} -{%- assign logo_length = _items | map: "logo" | join: "" | strip_html | strip | size -%} -{%- assign sign_length = _items | map: "sign" | join: "" | strip_html | strip | size -%} -{%- assign youtube_length = _items | map: "youtube" | join: "" | strip_html | strip | size -%} -{%- if image_length == 0 and logo_length == 0 and youtube_length == 0 and sign_length == 0 -%} - {%- assign show_image=false -%} -{%- endif -%} - -
- {%- for item in _items -%} - {%- assign names=item.author | default: item.speaker -%} - {%- assign title=item.title -%} - {%- if include.titles -%} - {%- assign title=include.titles | slice: forloop.index0 -%} - {%- endif -%} - {%- if include.type=="simple" -%} - {% if include.ignore_name %} - {% if names==include.ignore_name %} - {% assign names = nil %} - {% else %} - {% assign exp = "item != '" | append: include.ignore_name | append: "'" %} - {% assign names = names | where_exp: "item", exp %} - {% endif %} - {% endif %} -
-

- {{title}} {% if item.youtube or item.podbean or item.video_src %}{% endif %} - {{item.date | date: site.date_format }} - {%-if names and names.size > 0 %} - ·| - {% if include.ignore_name %} - w/ - {% endif %} - {%- include names_list.html names=names avatar=false -%} - {%- endif -%} -

-

{{item.date | date: site.date_format }}

-
- {% else %} -
- {%- if show_image -%} -
- {%- assign imageurl = nil -%} - {%- assign image_style_class = 'rect-image' -%} - {%- if item.sign -%} - {%- assign imageurl = item.sign -%} - {%- assign image_style_class = 'app-sign' -%} - {%- elsif item.logo -%} - {%- assign imageurl = item.logo -%} - {%- assign image_style_class = 'contained-image' -%} - {%- elsif item.image -%} - {%- assign imageurl = item.image -%} - {%- assign first = imageurl | slice: 0, 11 -%} - {%- if first == '/img/posts/' -%} - {%- assign body = imageurl | slice: 11, 1000 -%} - {%- assign imageurl = "/img-thumbnails/posts/" | append: body | append: ".webp" -%} - {%- endif -%} - {%- elsif item.youtube -%} - {%- assign imageurl = 'https://i3.ytimg.com/vi/' | append: item.youtube | append: '/hqdefault.jpg' -%} - {%- endif -%} - {%- if imageurl -%} - - {%- endif -%} -
- {%- endif -%} -
- {%- if title and title.size > 0 -%} -

{{title}}

- {%- endif -%} - {%- if include.subtitles -%} -

{{include.subtitles | slice: forloop.index0 }}

- {%- elsif item.collection=='posts' -%} - {%- unless include.gallery -%} -

- {{item.date | date: site.date_format }} - {% if names %} - · - {% include names_list.html names=names %} - {% endif %} -

- {%- endunless -%} - {%- endif -%} - {%- unless include.gallery -%} -
- {% if item.blurb %} - {{ item.blurb | markdownify }} - {% else %} - {{ item.content | strip_html | markdownify | strip_html | truncatewords: 32 }} - {% endif %} -
- {%- include register_button.html item=item -%} - {%- endunless -%} -
-
- {%- endif -%} - {%- endfor -%} -
diff --git a/_includes/item_time.html b/_includes/item_time.html deleted file mode 100644 index 3e98e9e..0000000 --- a/_includes/item_time.html +++ /dev/null @@ -1,2 +0,0 @@ -{%- assign eventPage = site.pages | find: "title", include.item.event -%} -{{ include.item.date | date: "%l:%M %p" }} EST \ No newline at end of file diff --git a/_includes/load_event b/_includes/load_event deleted file mode 100644 index 5e4975d..0000000 --- a/_includes/load_event +++ /dev/null @@ -1,8 +0,0 @@ -{%- assign curDate = site.time | date: '%s' | minus: 86400 -%} -{%- assign page_date = include.item.date | date: '%s' | minus: 0 -%} -{%- assign event_is_past = true -%} -{%- assign event_is_future = false -%} -{%- if page_date > curDate -%} - {%- assign event_is_past = false -%} - {%- assign event_is_future = true -%} -{%- endif -%} \ No newline at end of file diff --git a/_includes/load_people b/_includes/load_people deleted file mode 100644 index dc2c639..0000000 --- a/_includes/load_people +++ /dev/null @@ -1,19 +0,0 @@ -{%- assign people="" | split: ',' -%} -{%- assign roles="" | split: ',' -%} -{%- if include.at -%} - {%- for person in site.people -%} - {%- for role in person.roles -%} - {%- if role.at == include.at and role.to == nil -%} - {%- assign roles=roles | push: role -%} - {%- assign people=people | push: person -%} - {%- endif -%} - {%- endfor -%} - {%- endfor -%} -{%- elsif include.names -%} - {%- for name in include.names -%} - {%- assign person_with_name = site.people | find: "title", name -%} - {%- if person_with_name -%} - {%- assign people=people | push: person_with_name -%} - {%- endif -%} - {%- endfor -%} -{%- endif -%} \ No newline at end of file diff --git a/_includes/names_list.html b/_includes/names_list.html deleted file mode 100644 index c3a8d83..0000000 --- a/_includes/names_list.html +++ /dev/null @@ -1,24 +0,0 @@ -{% for name in include.names %} - - {%- if include.names.size > 1 and name == include.names.last %} - and - {% endif -%} - {% assign _item=site.people | find: "title", name %} - {%- unless _item -%} - {%- assign _item=site.pages | find: "title", name -%} - {%- endunless -%} - {%- if _item.url -%} - - {%- if _item.collection=="people" and include.avatar!=false -%} - {%- include inline_avatar.html item=_item -%} - {%- endif -%} - {{- name -}} - - {%- else -%} - {{name}} - {%- endif -%} - {%- if include.names.last and include.names.size > 2 and name != include.names.last -%} - , - {% endif -%} - -{% endfor %} \ No newline at end of file diff --git a/_includes/page_meta.html b/_includes/page_meta.html deleted file mode 100644 index 14024d6..0000000 --- a/_includes/page_meta.html +++ /dev/null @@ -1,42 +0,0 @@ -{% if page.title or page.temp_title %} {{page.temp_title | default: page.title}} | {% endif %} {{site.title}} - - -{% assign description= page.content | strip_html | markdownify | strip_html | strip_newlines | truncate: 210 -%} -{%- if page.temp_blurb or page.blurb -%} - {%- assign description=page.temp_blurb | default: page.blurb | strip_html | markdownify | strip_html -%} -{% endif %} - -{% assign image=page.sign -%} -{%- unless image -%} - {% assign image=page.image -%} -{%- endunless -%} -{%- unless image %} - {%- assign image=page.cover -%} -{%- endunless -%} -{%- unless image -%} - {%- assign image=page.logo -%} -{%- endunless -%} -{%- unless image -%} - {%- if page.youtube %} - {%- assign image = "https://i3.ytimg.com/vi/" | append: page.youtube | append: "/hqdefault.jpg" -%} - {% endif %} -{%- endunless -%} -{%- if image %} - - -{% endif %} - - - - -{%- if page.image %} - -{% endif -%} diff --git a/_includes/page_people_list.html b/_includes/page_people_list.html deleted file mode 100644 index d4b335a..0000000 --- a/_includes/page_people_list.html +++ /dev/null @@ -1,12 +0,0 @@ -{%- assign max_people=include.max_people | default: 15 -%} -{%- include load_people at=page.title -%} -{%- assign people=people | slice: 0, max_people -%} -{%- assign roles=roles | slice: 0, max_people -%} -{%- if max_people > 0 and roles.size > 0 -%} -
-
-

Meet the {{page.team_name | default: "team"}}

-
- {%- include people_list.html people=people roles=roles gallery=true -%} -
-{%- endif -%} \ No newline at end of file diff --git a/_includes/pagenav.html b/_includes/pagenav.html deleted file mode 100644 index eac09a7..0000000 --- a/_includes/pagenav.html +++ /dev/null @@ -1,47 +0,0 @@ -{%- if page.title or pate.temp_title -%} - -{%- endif -%} \ No newline at end of file diff --git a/_includes/people_list.html b/_includes/people_list.html deleted file mode 100644 index 7d68e46..0000000 --- a/_includes/people_list.html +++ /dev/null @@ -1,41 +0,0 @@ -{% if include.at %} - {% include load_people at=include.at %} - {% assign _items = people %} - {% assign _roles = roles %} -{% else %} - {% assign _items = include.people %} - {% assign _roles = include.roles %} -{% endif %} -{%- assign gallery=include.gallery -%} -{%- assign content_length = _items | map: "content" | join: "" | strip_html | strip | size -%} -{%- if content_length == 0 -%} - {%- assign gallery=true -%} -{%- endif -%} -{% assign ranks_string = "President;Vice President;Secretary;Treasurer;Member At-Large;Executive Director;Program Director;Program Manager;Maintainer;Organizer;Advisor;Developer;default;Trails Stewardship Initiative Program Manager" %} -{% assign _ranks = ranks_string | split:";" %} - \ No newline at end of file diff --git a/_includes/person_footer.html b/_includes/person_footer.html deleted file mode 100644 index e69de29..0000000 diff --git a/_includes/posts_section.html b/_includes/posts_section.html deleted file mode 100644 index 61ffd03..0000000 --- a/_includes/posts_section.html +++ /dev/null @@ -1,24 +0,0 @@ -{%- assign max_posts=include.max_posts | default: 5 -%} -{%- assign tagged_posts = site.posts | where: "tags", include.tag -%} -{%- if tagged_posts.size > 0 and max_posts > 0 -%} -
-
- {%- assign label=include.label -%} - {%- if label==nil -%} - {%- assign label="News and talks" -%} - {%- assign news_count=tagged_posts | where: "category", "News" | size -%} - {%- if news_count==tagged_posts.size -%} - {%- assign label="News" -%} - {%- elsif news_count==0 -%} - {%- assign label="Talks" -%} - {%- endif -%} - {%- endif -%} -

{{label}}

- {%- if tagged_posts.size > max_posts -%} - See all posts - {%- endif -%} -
- {%- assign filtered_tagged_posts=tagged_posts | slice: 0, max_posts -%} - {%- include item_list.html items=filtered_tagged_posts -%} -
-{%- endif -%} \ No newline at end of file diff --git a/_includes/register_button.html b/_includes/register_button.html deleted file mode 100644 index 2cfe80c..0000000 --- a/_includes/register_button.html +++ /dev/null @@ -1,4 +0,0 @@ -{% include load_event item=include.item %} -{%- if include.item.register and event_is_future -%} -

Register

-{% endif %} \ No newline at end of file diff --git a/_includes/schedule_table.html b/_includes/schedule_table.html deleted file mode 100644 index b0b938d..0000000 --- a/_includes/schedule_table.html +++ /dev/null @@ -1,40 +0,0 @@ -{% assign sessions = include.items | sort: 'date' -%} - - - - - - - - - {%- for item in sessions -%} - - {%- assign names=item.author | default: item.speaker -%} - {%- assign title=item.title -%} - - - - {%- endfor -%} -
{{sessions[0].date | date: '%A, %B %e'}}
TimeSession
{%- include item_time.html item=item -%} - {%- if title and title.size > 0 -%} -

- {%- if item.url -%} - {{title}} {% if item.youtube or item.podbean or item.video_src %}{% endif %} - {%- else -%} - {{title}} - {%- endif -%} -

- {%- endif -%} -

- {% if names %} - {% include names_list.html names=names %} - {% endif %} -

-

- {% if item.blurb %} - {{ item.blurb | markdownify }} - {% else %} - {{ item.content | strip_html | markdownify | strip_html | truncatewords: 64 }} - {% endif %} -

-
\ No newline at end of file diff --git a/_includes/scripts.html b/_includes/scripts.html deleted file mode 100644 index 1c5198d..0000000 --- a/_includes/scripts.html +++ /dev/null @@ -1,6 +0,0 @@ - \ No newline at end of file diff --git a/_includes/scripts/icon_loader.js b/_includes/scripts/icon_loader.js deleted file mode 100644 index 30502d1..0000000 --- a/_includes/scripts/icon_loader.js +++ /dev/null @@ -1,19 +0,0 @@ -fetch("{{site.url}}{{site.baseurl}}/assets/icons/fa-solid.svg") - .then(function(response) { - return response.text(); - }) - .then(function(text) { - var div = document.createElement('div'); - div.innerHTML = text; - document.body.insertBefore(div, document.body.childNodes[0]); - }); - -fetch("{{site.url}}{{site.baseurl}}/assets/icons/fa-brands.svg") - .then(function(response) { - return response.text(); - }) - .then(function(text) { - var div = document.createElement('div'); - div.innerHTML = text; - document.body.insertBefore(div, document.body.childNodes[0]); - }); \ No newline at end of file diff --git a/_includes/scripts/realtime_updater.js b/_includes/scripts/realtime_updater.js deleted file mode 100644 index d139929..0000000 --- a/_includes/scripts/realtime_updater.js +++ /dev/null @@ -1,90 +0,0 @@ -document.addEventListener("DOMContentLoaded", function() { - - var scheduleRowsToCheck = document.querySelectorAll('table.schedule tr[start][end]'); - - if (scheduleRowsToCheck.length > 0) { - setInterval(checkScheduleRows, 1000); - checkScheduleRows(); - } - - function checkScheduleRows() { - var now = new Date(); - scheduleRowsToCheck.forEach(function(el) { - var start = new Date(parseInt(el.getAttribute('start') + '000')); - var end = new Date(parseInt(el.getAttribute('end') + '000')); - if (now >= start && now < end) { - if (!el.classList.contains('ongoing')) { - el.classList.add('ongoing'); - } - } else if (el.classList.contains('ongoing')) { - el.classList.remove('ongoing'); - } - }); - } - - var homepageUrl = document.querySelector('meta[name="homepage"]').getAttribute('content'); - var nextEventEl = document.querySelector('meta[name="dogwood-next-event"]'); - if (nextEventEl) createRealtimeMessage(); - - function createRealtimeMessage() { - - var title = nextEventEl.getAttribute('content'); - - var noticeInfo = JSON.parse(localStorage.getItem('notice-info')) || null; - if (noticeInfo && noticeInfo.title !== title) { - localStorage.removeItem('notice-info'); - noticeInfo = null; - } - - var end = new Date(parseInt(nextEventEl.getAttribute('end') + '000')); - var now = new Date(); - - // don't show something that's over - if (now > end) return; - - var link = nextEventEl.getAttribute('href'); - - // don't show if we're already on the promoted part of the site - if (window.location.href.startsWith(link) || - // or if we're on the homepage since content is already promoted there - window.location.href === homepageUrl + '/') return; - - var start = new Date(parseInt(nextEventEl.getAttribute('start') + '000')); - - if (now < start && - noticeInfo && - now.getTime() < noticeInfo.clicked + 172800000 - ) { - // don't notify again if event hasn't started yet and it's been under two days since last notified - return; - } - - var tagline = nextEventEl.getAttribute('tagline'); - var logo = nextEventEl.getAttribute('logo'); - - var notice = document.createElement('a'); - notice.setAttribute('href', link); - notice.setAttribute('id', 'notice-overlay'); - notice.classList.add(nextEventEl.getAttribute('noticeclass')); - var html = ''; - - if (logo) { - html += ''; - } - html += '
'; - var status = start > now ? 'Upcoming' : 'Happening Now'; - html += '
' + status + '
'; - html += '

' + title + '
' + tagline + '

' - html += ''; - - notice.innerHTML = html; - document.body.appendChild(notice); - - notice.addEventListener('click', function() { - localStorage.setItem('notice-info', JSON.stringify({ - title: title, - clicked: now.getTime() - })); - }); - } -}); \ No newline at end of file diff --git a/_includes/scripts/smooth_anchor_scroller.js b/_includes/scripts/smooth_anchor_scroller.js deleted file mode 100644 index 91f344a..0000000 --- a/_includes/scripts/smooth_anchor_scroller.js +++ /dev/null @@ -1,15 +0,0 @@ -// do smooth scroll when clicking an #anchor link instead of jumping -document.addEventListener('click', function(e) { - const origin = e.target.closest(`a`); - if (!origin || !origin.href) return; - - var parts = origin.href.match(/^([^#]*)#(.+)/); - if (parts && parts.length >=3 && parts[1] === (window.location.origin + location.pathname) && parts[2]) { - - // cancel jump - e.preventDefault(); - - var elmntToView = document.getElementById(parts[2]); - elmntToView.scrollIntoView({behavior: "smooth"}); - } -}); diff --git a/_includes/scripts/time_localizer.js b/_includes/scripts/time_localizer.js deleted file mode 100644 index e63fa59..0000000 --- a/_includes/scripts/time_localizer.js +++ /dev/null @@ -1,64 +0,0 @@ -document.addEventListener("DOMContentLoaded", function() { - document.querySelectorAll('.time').forEach(function(el) { - var targetTimeZone = el.getAttribute('totimezone') || undefined; - var sourceTime = el.getAttribute('time') && parseInt(el.getAttribute('time') + '000'); - var date = (sourceTime && new Date(sourceTime)) || parseTime(el.textContent); - var timeZoneLabel = date.toLocaleDateString(undefined, { - day: '2-digit', - timeZoneName: 'long', - timeZone: targetTimeZone, - }).substring(4); - var localizedTimeString = date.toLocaleString(undefined, { - hour: 'numeric', - minute: 'numeric', - timeZoneName: 'short', - timeZone: targetTimeZone, - }); - el.innerHTML = '' + localizedTimeString + ''; - }); - - document.querySelectorAll('.day-long').forEach(function(el) { - var targetTimeZone = el.getAttribute('totimezone') || undefined; - var sourceTime = el.getAttribute('time') && parseInt(el.getAttribute('time') + '000'); - var date = (sourceTime && new Date(sourceTime)) || new Date(); - var localizedTimeString = date.toLocaleDateString(undefined, { - weekday: 'long', - month: 'long', - day: 'numeric', - timeZone: targetTimeZone, - }); - el.innerHTML = localizedTimeString; - }); - - document.querySelectorAll('.timezone').forEach(function(el) { - var targetTimeZone = el.getAttribute('totimezone') || undefined; - var sourceTime = el.getAttribute('time') && parseInt(el.getAttribute('time') + '000'); - var date = (sourceTime && new Date(sourceTime)) || new Date(); - el.textContent = date.toLocaleDateString(undefined, { - day:'2-digit', - timeZoneName: 'long', - timeZone: targetTimeZone, - }).substring(4); - }); - - function parseTime(t) { - var time = t.match( /(\d+)(?::(\d\d))?\s*([pP]|[aA]?)/ ); - var h = parseInt(time[1]); - - // if am or pm - if (time[3]) { - h = h % 12; // normalize between 0 and 11 - - if (time[3].toLowerCase()[0] === 'p') { - h += 12; // add 12 hours if pm - } - } - - // hardcode UTC offset - h += 5; - // normalize between 0 and 23 - h = h % 24; - var m = parseInt( time[2]) || 0; - return new Date(Date.UTC(2024, 1, 19, h, m)); - } -}); \ No newline at end of file diff --git a/_includes/site_meta.html b/_includes/site_meta.html deleted file mode 100644 index 0a308be..0000000 --- a/_includes/site_meta.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - -{% assign sessions = site.posts | where_exp: "item", "item.url contains '/events/'" %} -{% assign future_sessions="" | split: ',' -%} -{% assign curDate = site.time | date: '%s' | minus: 86400 %} -{% for session in sessions %} - {% assign page_date = session.date | date: '%s' | minus: 0 %} - {% if page_date >= curDate %} - {% assign future_sessions = future_sessions | push: session %} - {% endif %} -{% endfor %} -{% assign next_session = future_sessions | reverse | first %} -{% if next_session %} - {% assign starttime = next_session.date | date: '%s' %} - {% assign endtime = starttime | plus: 3600 %} - {% if next_session.event %} - {% assign all_in_series = site.posts | where: 'event', next_session.event | sort: 'date' %} - {% assign first_in_series = all_in_series | first %} - {% assign last_in_series = all_in_series | last %} - {% assign starttime = first_in_series.date | date: '%s' %} - {% assign endtime = last_in_series.date | date: '%s' | plus: 3600 %} - {% assign next_session = site.pages | find_exp: "item", "item.title==next_session.event or item.temp_title==next_session.event" %} - {% endif %} - -{% endif %} - - -{% for feed in site.feeds %} - -{% endfor %} \ No newline at end of file diff --git a/_includes/sitemap.html b/_includes/sitemap.html deleted file mode 100644 index cab27d9..0000000 --- a/_includes/sitemap.html +++ /dev/null @@ -1,38 +0,0 @@ -
- {%- assign site_links=site.footer_links | default: site.links -%} - {%- for site_link in site_links -%} - {%- assign linked_page=site.pages | find: "url", site_link.link -%} - - {%- endfor -%} -
\ No newline at end of file diff --git a/_includes/tagged_pages_list.html b/_includes/tagged_pages_list.html deleted file mode 100644 index 7dfd150..0000000 --- a/_includes/tagged_pages_list.html +++ /dev/null @@ -1,15 +0,0 @@ -{%- assign linked_pages="" | split: ',' -%} -{%- for tag in page.tags -%} - {%- assign linked_page=site.pages | find: "title", tag -%} - {%- if linked_page -%} - {%- assign linked_pages=linked_pages | push: linked_page -%} - {%- endif -%} -{%- endfor -%} -{%- if linked_pages.size > 0 -%} -
-
-

More info

-
- {% include item_list.html items=linked_pages %} -
-{%- endif -%} \ No newline at end of file diff --git a/_includes/topbar.html b/_includes/topbar.html deleted file mode 100644 index 0b859e6..0000000 --- a/_includes/topbar.html +++ /dev/null @@ -1,47 +0,0 @@ -
-
- - - {{ site.title }} - - -
-
\ No newline at end of file diff --git a/_includes/upcoming_events.html b/_includes/upcoming_events.html deleted file mode 100644 index f34493e..0000000 --- a/_includes/upcoming_events.html +++ /dev/null @@ -1,27 +0,0 @@ - -{% assign sessions = site.posts | where_exp: "item", "item.url contains '/events/'" %} -{% assign past_sessions="" | split: ',' -%} -{% assign future_sessions="" | split: ',' -%} -{% if include.category %} - {% assign sessions = sessions | where: "category", include.category %} -{% endif %} -{% assign curDate = site.time | date: '%s' | minus: 86400 %} -{% for session in sessions %} - {% assign page_date = session.date | date: '%s' | minus: 0 %} - {% if page_date < curDate %} - {% unless session.image==nil and session.youtube==nil %} - {% assign past_sessions = past_sessions | push: session %} - {% endunless %} - {% else %} - {% assign future_sessions = future_sessions | push: session %} - {% endif %} -{% endfor %} -{% assign future_sessions = future_sessions | reverse %} -{% if future_sessions.size > 0 %} -
-
-

Upcoming event{% if future_sessions.size!=1 %}s{% endif %}

-
- {% include item_list.html items=future_sessions %} -
-{% endif %} \ No newline at end of file diff --git a/_layouts/archives/month.html b/_layouts/archives/month.html deleted file mode 100644 index 5d7e500..0000000 --- a/_layouts/archives/month.html +++ /dev/null @@ -1,11 +0,0 @@ ---- ---- - - - - -{%- assign redirect_base_len=page.url.size | minus: 3 -%} -{%- assign redirect_base=page.url|slice: 0, redirect_base_len -%} - - - diff --git a/_layouts/archives/posts-tag.html b/_layouts/archives/posts-tag.html deleted file mode 100644 index a02aa4b..0000000 --- a/_layouts/archives/posts-tag.html +++ /dev/null @@ -1,11 +0,0 @@ ---- -layout: default ---- -
-
-
-

Posts tagged "{{ page.title }}"

-
- {% include item_list.html items=page.posts %} -
-
diff --git a/_layouts/archives/posts-year.html b/_layouts/archives/posts-year.html deleted file mode 100644 index 518fb80..0000000 --- a/_layouts/archives/posts-year.html +++ /dev/null @@ -1,32 +0,0 @@ ---- -layout: default ---- -
-

Posts published in {{ page.date | date: "%Y" }}

- {% assign posts=page.posts | reverse %} - {% assign lowerindex=0 %} - {% assign upperindex=0 %} - {% for i in (1..12) %} - {% for post in posts %} - {% assign post_month = post.date | date: "%m" | minus: 0 %} - {% if post_month > i %} - {% assign upperindex=forloop.index0 %} - {% break %} - {% elsif post==posts.last %} - {% assign upperindex=forloop.index0 | plus: 1 %} - {% break %} - {% endif %} - {% endfor %} - {% if lowerindex < upperindex %} - {% assign post_count=upperindex | minus: lowerindex %} - {% assign month_posts=posts | slice: lowerindex, post_count %} -
- - {% include item_list.html items=month_posts %} -
- {% endif %} - {% assign lowerindex=upperindex %} - {% endfor %} -
diff --git a/_layouts/default.html b/_layouts/default.html deleted file mode 100644 index 384516d..0000000 --- a/_layouts/default.html +++ /dev/null @@ -1,16 +0,0 @@ ---- ---- - - -{% include head.html %} - - {% include_cached analytics.html %} - {% include_cached topbar.html %} -
- {{content}} -
- {% include_cached footer.html %} - {% include_cached scripts.html %} - {% include_cached custom-scripts.html %} - - \ No newline at end of file diff --git a/_layouts/embedded-page.html b/_layouts/embedded-page.html deleted file mode 100644 index 4852fb4..0000000 --- a/_layouts/embedded-page.html +++ /dev/null @@ -1,23 +0,0 @@ ---- -layout: default ---- - -
-
- {%- include breadcrumbs.html -%} - {%- include pagenav.html -%} -
-
- {%- assign embedsrc = page.embedded | default: page.embedded_remote -%} - -
-
-
- {{ content }} -
-
-
diff --git a/_layouts/page.html b/_layouts/page.html deleted file mode 100644 index a68c6cb..0000000 --- a/_layouts/page.html +++ /dev/null @@ -1,21 +0,0 @@ ---- -layout: default ---- -
-
-
- {%- include breadcrumbs.html -%} - {%- include pagenav.html -%} -
-
- {%- include cover.html -%} -
-
-
- {{content}} -
- {%- include posts_section.html tag=page.title max_posts=page.max_posts -%} -
-
- -
diff --git a/_layouts/person.html b/_layouts/person.html deleted file mode 100644 index 426416f..0000000 --- a/_layouts/person.html +++ /dev/null @@ -1,118 +0,0 @@ ---- -layout: default ---- -{% assign content = page.content | strip_newlines %} -{% assign talks = site.posts | where: "speaker", page.title %} -{% assign authored_posts = site.posts | where: "author", page.title %} -{% assign tagged_posts = site.posts | where: "tags", page.title %} -{% if page.cover %} - {% include cover.html %} -{% else %} -
-{% endif %} -
-
-
- -
-
-
-

{{page.title}}

- {%- if page.osm -%} - @{{page.osm}} - {%- endif -%} -
- {%- if content != '' -%} -
- {{content}} -
- {%- endif -%} - {%- if page.roles -%} -
-
    - {%- for role in page.roles -%} - {%- if role.at -%} -
  • - {%- if role.title -%} - {{role.title}}, - {% endif -%} - {% assign at_page=site.pages | find: "title", role.at -%} - {%- assign at = role.at -%} - {%- if at == "OpenStreetMap US Staff" -%} - {%- assign at = "OpenStreetMap US" -%} - {%- endif -%} - - {%- if at_page -%} - {{at}} - {%- else -%} - {{at}} - {%- endif -%} - - {%- if role.from %} ({{role.from | date: "%Y" }}–{%- if role.to -%}{{role.to | date: "%Y" }}{%- else -%}present{%- endif -%}){%- endif -%} -
  • - {%- endif -%} - {%- endfor -%} -
-
- {%- endif -%} - {%- if page.website or page.wikipedia or page.mastodon or page.twitter or page.github or page.linkedin or page.medium -%} - - {%- endif -%} -
-
- {%- if talks.size > 0 -%} -
-

Talks

-
- {%- include item_list.html items=talks type="simple" ignore_name=page.title -%} -
-
- {%- endif -%} - {%- if authored_posts.size > 0 -%} -
-

Authored posts

-
- {%- include item_list.html items=authored_posts type="simple" ignore_name=page.title -%} -
-
- {%- endif -%} - {%- if tagged_posts.size > 0 -%} -
-

Mentions

-
- {%- include item_list.html items=tagged_posts type="simple" -%} -
-
- {%- endif -%} -
-

-
- {%- include person_footer.html -%} - {%- if page.updated -%} -

Last updated {{page.updated | date: "%B %Y" }}.

- {% endif %} -
-
-
\ No newline at end of file diff --git a/_layouts/post.html b/_layouts/post.html deleted file mode 100644 index 595945f..0000000 --- a/_layouts/post.html +++ /dev/null @@ -1,17 +0,0 @@ ---- -layout: default ---- -
- {% include cover.html %} -
-
- - {% include pagenav.html %} -
-
-
- {{content}} -
- {%- include tagged_pages_list.html -%} -
-
diff --git a/_layouts/project.html b/_layouts/project.html deleted file mode 100644 index 7b9d477..0000000 --- a/_layouts/project.html +++ /dev/null @@ -1,98 +0,0 @@ ---- -layout: default ---- -
-
-
-
-
- {% include breadcrumbs.html %} -
- {% if page.logo %} -
- -
- {% endif %} -
- {% include pagenav.html %} - {% if page.tagline or page.temp_tagline %} -

{{ page.temp_tagline | default: page.tagline }}

- {% endif %} - {% if page.temp_blurb or page.blurb %} -
- {{ page.temp_blurb | default: page.blurb | markdownify }} -
- {% endif %} - {%- if page.buttons or page.website -%} -
-
- {%- for button in page.buttons -%} - {{button.label}} - {%- endfor -%} - {%- unless page.buttons -%} - Visit Website - {%- endunless -%} -
-
    - {%- if page.website and page.buttons -%} -
  • - {%- endif -%} - {%- if page.github -%} -
  • - {%- endif -%} - {%- if page.instagram -%} -
  • - {%- endif -%} - {%- if page.mastodon -%} -
  • - {%- endif -%} - {%- if page.twitter -%} -
  • - {%- endif -%} - {%- if page.facebook -%} -
  • - {%- endif -%} - {%- if page.reddit -%} -
  • - {%- endif -%} - {%- if page.meetup -%} -
  • - {%- endif -%} - {%- if page.youtube_page -%} -
  • - {%- endif -%} - {%- if page.slack_channel -%} -
  • - {%- endif -%} - {%- if page.email_list -%} -
  • - {%- endif -%} - {%- if page.donate -%} -
  • - {%- endif -%} -
-
- {%- endif -%} -
-
-
-
- {%- if page.image -%} -
- -
- {%- endif -%} -
-
- {%- assign content = page.content | strip_newlines -%} - {%- if content != '' -%} -
-
- {{- content -}} -
-
- {%- endif -%} - {%- include posts_section.html tag=page.title max_posts=page.max_posts -%} -
-
-
diff --git a/_layouts/redirect.html b/_layouts/redirect.html deleted file mode 100644 index 93a484c..0000000 --- a/_layouts/redirect.html +++ /dev/null @@ -1,9 +0,0 @@ ---- ---- - - - - - - - diff --git a/_layouts/session.html b/_layouts/session.html deleted file mode 100644 index 638d6c6..0000000 --- a/_layouts/session.html +++ /dev/null @@ -1,69 +0,0 @@ ---- -layout: default ---- -
- {% include cover.html %} -
-
- {% include breadcrumbs.html %} - {% include pagenav.html %} -
-
-
- {{content}} - {%- include register_button.html item=page -%} - {%- include load_event item=page -%} - {%- if event_is_past and page.youtube == nil and page.podbean==nil and page.video_src==nil -%} -

No recording is available from this session.

- {%- endif -%} - {%- if page.slides -%} -

View Slides

- {% endif %} -
- {% include load_people names=page.speaker %} - {%- if people.size > 0 -%} -
-
-

Speaker{%- if people.size != 1 -%}s{%- endif -%}

-
- {% include people_list.html people=people %} -
- {%- endif -%} - - {%- include tagged_pages_list.html -%} - - {%- assign talks=site.categories[page.categories.first] | where_exp: "item", "item != page" -%} - {%- if page.youtube or page.video_src or page.podbean -%} - {%- assign talks=talks | where_exp: "item", "item.youtube or item.video_src or item.podbean" -%} - {%- endif -%} - {%- assign newer_item=talks | reverse | find_exp: "item", "item.date > page.date" -%} - {%- assign older_item=talks | find_exp: "item", "item.date < page.date" -%} - - {%- unless older_item -%} - {%- assign older_item=talks | first -%} - {%- endunless -%} - - {%- unless newer_item -%} - {%- assign newer_item=talks | last -%} - {%- endunless -%} - - {%- if page.categories.first == "State of the Map US" or page.categories.first == "Mapping USA" -%} - {%- assign up_next_item=newer_item -%} - {%- assign prior_item=older_item -%} - {%- else -%} - {%- assign up_next_item=older_item -%} - {%- assign prior_item=newer_item -%} - {%- endif -%} -
-
-

Next up in {{page.categories.first}}

- Previous talk -
- {% assign as_array="" | split: "," | push: up_next_item %} - {% include item_list.html items=as_array %} -
- -
-
- -
diff --git a/_plugins/absolute-urls/Gemfile b/_plugins/absolute-urls/Gemfile deleted file mode 100644 index bb94df8..0000000 --- a/_plugins/absolute-urls/Gemfile +++ /dev/null @@ -1,4 +0,0 @@ -# frozen_string_literal: true - -source "https://rubygems.org" -gemspec diff --git a/_plugins/absolute-urls/absolute-urls.gemspec b/_plugins/absolute-urls/absolute-urls.gemspec deleted file mode 100644 index 87226e4..0000000 --- a/_plugins/absolute-urls/absolute-urls.gemspec +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -Gem::Specification.new do |spec| - spec.name = "absolute-urls" - spec.version = "0.1.0" - spec.authors = ["Quincy Morgan"] - spec.email = ["2046746+quincylvania@users.noreply.github.com"] - - spec.summary = "Force absolute URLs in Jekyll Kramdown `href` and `src` properties." - spec.homepage = "https://github.com/osmus/dogwood" - spec.license = "MIT" - - spec.files = Dir["lib/**/*"] - - spec.add_runtime_dependency "jekyll", "~> 4.3" -end diff --git a/_plugins/absolute-urls/lib/absolute-urls.rb b/_plugins/absolute-urls/lib/absolute-urls.rb deleted file mode 100644 index 9585dd5..0000000 --- a/_plugins/absolute-urls/lib/absolute-urls.rb +++ /dev/null @@ -1,25 +0,0 @@ -# This plugin ensures all `src` and `href` properties created by markdown parsing -# are absolute links. This solves issues that occur when the baseurl is a subdirectory. - -require 'kramdown/utils/html' - -SITE_BASEURL = (Jekyll.sites()[0].config['url'] || '') + (Jekyll.sites()[0].config['baseurl'] || ''); - -module AbsoluteUrls - def html_attributes(attr) - - return super unless attr['src'] || attr['href'] - - if attr['src'] && attr['src'].start_with?("/") - attr['src'] = SITE_BASEURL + attr['src'] - end - - if attr['href'] && attr['href'].start_with?("/") - attr['href'] = SITE_BASEURL + attr['href'] - end - - super(attr) - end -end - -Kramdown::Utils::Html.prepend AbsoluteUrls \ No newline at end of file diff --git a/_plugins/post-aliases/Gemfile b/_plugins/post-aliases/Gemfile deleted file mode 100644 index bb94df8..0000000 --- a/_plugins/post-aliases/Gemfile +++ /dev/null @@ -1,4 +0,0 @@ -# frozen_string_literal: true - -source "https://rubygems.org" -gemspec diff --git a/_plugins/post-aliases/lib/post-aliases.rb b/_plugins/post-aliases/lib/post-aliases.rb deleted file mode 100644 index e6b992a..0000000 --- a/_plugins/post-aliases/lib/post-aliases.rb +++ /dev/null @@ -1,38 +0,0 @@ -# This plugin generates redirect pages for all posts, pointing from the /:year/:month/:title -# format to the actual URL, whatever it may be. This makes the site backwards-compatible -# for links to pre-2023-redesign blog posts. It could have other uses as well, like URL-shortening. -# -# Example: -# /2023/02/tasking-manager-redesign -# --> automatically redirects to --> -# /news/2023/02/tasking-manager-redesign - -module RedirectPosts - class RedirectPostsGenerator < Jekyll::Generator - safe true - - def generate(site) - site.posts.docs.each do |post| - site.pages << PostRedirectPage.new(site, post) - end - end - end -end - -class PostRedirectPage < Jekyll::Page - def initialize(site, post) - @site = site # the current site instance. - @base = site.source # path to the source directory. - - @basename = post.basename # filename without the extension. - @ext = post.data["ext"] # the extension. - @name = post.basename + post.data["ext"] # basically @basename + @ext. - - @data = {} - - data["layout"] = "redirect" - data["redirect"] = post.url - data["permalink"] = post.date.strftime('/%Y/%m/') + post.data["slug"] + "/" - - end -end \ No newline at end of file diff --git a/_plugins/post-aliases/post-aliases.gemspec b/_plugins/post-aliases/post-aliases.gemspec deleted file mode 100644 index c791e50..0000000 --- a/_plugins/post-aliases/post-aliases.gemspec +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -Gem::Specification.new do |spec| - spec.name = "post-aliases" - spec.version = "0.1.0" - spec.authors = ["Quincy Morgan"] - spec.email = ["2046746+quincylvania@users.noreply.github.com"] - - spec.summary = "Create redirect pages for /:year/:month/:title to canonical posts." - spec.homepage = "https://github.com/osmus/dogwood" - spec.license = "MIT" - - spec.files = Dir["lib/**/*"] - - spec.add_runtime_dependency "jekyll", "~> 4.3" -end diff --git a/_plugins/unwrap-img/Gemfile b/_plugins/unwrap-img/Gemfile deleted file mode 100644 index bb94df8..0000000 --- a/_plugins/unwrap-img/Gemfile +++ /dev/null @@ -1,4 +0,0 @@ -# frozen_string_literal: true - -source "https://rubygems.org" -gemspec diff --git a/_plugins/unwrap-img/lib/unwrap-img.rb b/_plugins/unwrap-img/lib/unwrap-img.rb deleted file mode 100644 index 09b8644..0000000 --- a/_plugins/unwrap-img/lib/unwrap-img.rb +++ /dev/null @@ -1,31 +0,0 @@ -# This plugin unwrap elements wrapped in

elements, and adds an 'img-container' -# class to elements that wrap elements. This allows us to properly style images -# separately from

, e.g. to give them different widths. - -require 'kramdown/converter/html' - -BLANK_RE = /\A[[:space:]]*\z/ - -module StandaloneImages - def isImageElement(ele) - return ele.type == :img || (ele.type == :html_element && ele.value == "img") - end - def convert_p(el, indent) - return super unless el.children.any? {|child| isImageElement(child) } || el.children.all? { |child| child.type == :a } - # remove empty text elements that might be sandwiched between images - els = el.children.select { |child| child.type != :text || !BLANK_RE.match?(child.value) } - els = els.map { |child| - if child.children.size == 1 && isImageElement(child.children.first) - if child.attr['class'].nil? - child.attr['class'] = 'img-container' - else - child.attr['class'] = child.attr['class'] + ' img-container' - end - end - convert(child, indent) - } - return els.join('') - end -end - -Kramdown::Converter::Html.prepend StandaloneImages \ No newline at end of file diff --git a/_plugins/unwrap-img/unwrap-img.gemspec b/_plugins/unwrap-img/unwrap-img.gemspec deleted file mode 100644 index dcece94..0000000 --- a/_plugins/unwrap-img/unwrap-img.gemspec +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -Gem::Specification.new do |spec| - spec.name = "unwrap-img" - spec.version = "0.1.0" - spec.authors = ["Quincy Morgan"] - spec.email = ["2046746+quincylvania@users.noreply.github.com"] - - spec.summary = "Unwrap Kramdown elements from

elements." - spec.homepage = "https://github.com/osmus/dogwood" - spec.license = "MIT" - - spec.files = Dir["lib/**/*"] - - spec.add_runtime_dependency "jekyll", "~> 4.3" -end diff --git a/_redirects/trees.md b/_redirects/trees.md deleted file mode 100644 index c25548b..0000000 --- a/_redirects/trees.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -redirect: /plants/ ---- \ No newline at end of file diff --git a/_sass/dogwood/_base.scss b/_sass/dogwood/_base.scss deleted file mode 100644 index b39101b..0000000 --- a/_sass/dogwood/_base.scss +++ /dev/null @@ -1,45 +0,0 @@ -/* Reset ♥ - http://meyerweb.com/eric/tools/css/reset/ - v2.0 | 20110126 - License: none (public domain) -------------------------------------------------------- */ -html, body, div, span, applet, object, iframe, -h1, h2, h3, h4, h5, h6, p, blockquote, pre, -a, abbr, acronym, address, big, cite, code, -del, dfn, em, img, ins, kbd, q, s, samp, -small, strike, strong, sub, sup, tt, var, -b, u, i, center, -dl, dt, dd, ol, ul, li, -fieldset, form, label, legend, -table, caption, tbody, tfoot, thead, tr, th, td, -article, aside, canvas, details, embed, -figure, figcaption, footer, header, hgroup, -menu, nav, output, ruby, section, summary, -time, mark, audio, video { - margin:0; - padding:0; - border:0; - font-size:100%; - font:inherit; - vertical-align:baseline; - } -/* HTML5 display-role reset for older browsers */ -article, aside, details, figcaption, figure, -footer, header, hgroup, menu, nav, section { - display:block; -} -body { line-height:1; } -ol, ul { list-style:none; } -blockquote, q { quotes:none; } -blockquote:before, blockquote:after, -q:before, q:after { content:''; content:none; } -/* tables still need 'cellspacing="0"' in the markup */ -table { border-collapse: collapse; border-spacing:0; } -/* remember to define focus styles. Hee Haw */ -:focus { outline:0; } - -*, *:after, *:before { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} \ No newline at end of file diff --git a/_sass/dogwood/_layout.scss b/_sass/dogwood/_layout.scss deleted file mode 100644 index cb3eee2..0000000 --- a/_sass/dogwood/_layout.scss +++ /dev/null @@ -1,1599 +0,0 @@ -@use 'sass:color'; - -/* Inline Elements & Typography -------------------------------------------------------- */ -body { - background-color: $background-color; -} - -body, -input, -textarea { - color: $text-color; - font-size: $body-text-size; - line-height: 1.6667; - font-family: $sans-serif-font; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - font-variant-numeric: lining-nums; -} - -h1, h2, h3, h4, h5, h6 { - font-family: $serif-font; - margin: 0; - margin-bottom: $sp*0.5; - font-weight: 600; - line-height: 1.3; -} - -h1 { - font-weight: 700; - font-size: 32px; -} - -h2 { - font-size: 26px; -} - -h3 { - font-size: 22px; -} - -h4, h5 { - font-size: 18px; -} - -/* Links */ -a { - color: $primary-color; - text-decoration:none; -} -a:visited { - color: $primary-color; -} -a:hover, a:active { - color: lighten($primary-color, 10%); - - &:not(.button) { - text-decoration: underline; - } -} - -.dark { - background-color: $dark-background-color; - color: white; - a { - color: $primary-color-alt; - - &:hover, &:active { - color: lighten($primary-color-alt, 20%); - } - } - hr { - background: $dark-grid-color; - } -} - -abbr { - border-bottom:1px dotted #000; - cursor:help; -} - -address { font-style:italic;} -small { font-size:12px; line-height: 1.5;} -strong, b { font-weight:700;} -em, i { font-style:italic;} - -hr { - margin: 0 0 20px; - border: 0; - height: 1px; - background: $alpha-grid-color; -} - -/* Block Quotes */ -blockquote, q { - quotes:none; - font-style:italic; - padding-left:20px; - border-left: 10px solid #e8e8e8; - - &.pullquote > *:not(cite) { - font-size: 22px; - } -} - -blockquote:before, -blockquote:after, -q:before, -q:after { - content:''; -} - -/* Code Blocks & Pre */ -code, -pre { - padding: 5px 4px; - font-family: Menlo, Bitstream Vera Sans Mono, Monaco, Consolas, monospace; - font-size: 12px; - border-radius: 3px; -} -code { - padding:5px; - background: rgba(128,128,128,0.07); - border: 1px solid $grid-color; -} -pre { - display:block; - padding:10px; - word-break:break-all; - word-wrap:break-word; - white-space:pre; - white-space:pre-wrap; - background:#f8f8f8; - border:1px solid #ddd; - border-radius:3px; -} -pre code { - padding:0; - color:inherit; - background-color:transparent; - border:0; -} -.pre-scrollable { - max-height:300px; - overflow-y:scroll; -} - -/* sub/superscripts */ -sup, -sub { - height:0; - line-height:1; - vertical-align:baseline; - _vertical-align:bottom; - position:relative; - font-size:75%; -} -sup { - bottom:1em; -} - -label { - display: block; - font-weight: 600; - font-size: 0.9em; - cursor: pointer; -} -select, -textarea, -input[type=text], -input[type=email] { - display: inline-block; - width: 500px; - max-width: 100%; - vertical-align: middle; - padding: 4px 8px; - border-radius: 3px; - background-color:#fff; - border:1px solid $grid-color; -} -textarea:focus, -input[type=text]:focus, -input[type=email]:focus { - border-color: #70a177; -} - -textarea { - height:200px; - max-width:none; -} - -table { - width:100%; - background-color:transparent; - border-collapse:collapse; - border-spacing:0; - table-layout:fixed; -} -th, td { - padding: 4px 4px; - text-align: left; - vertical-align: top; - border-bottom: 1px solid $grid-color; -} -tr:first-child { - > th, > td { - border-top: 1px solid $grid-color; - } -} -th { - font-weight:bold; -} -thead th { - vertical-align:bottom; - color:#57594D; -} - -.iconsvg { - fill: currentColor; - display: inline-block; - vertical-align: middle; - width: 0.8em; - height: 0.8em; -} - -.iconsvg.pre-text { - margin-right: 0.2em; -} - -/* Layout -------------------------------------------------------- */ -.container { - position: relative; - width: 100%; - max-width: $container-width; - margin: 0 auto; - padding-right: $container-padding; - padding-left: $container-padding; - - .inner-container { - width: 100%; - max-width: 900px; - margin: 0 auto; - } - - &.stretch { - @media only screen and (max-width: $container-width) { - padding: 0; - .cover-image { - border-left: 0; - border-right: 0; - } - } - } -} -.layout-post:not(.has-image) article.content{ - padding-top: 0; -} -.layout-post.has-image article.content { - @media only screen and (max-width: $container-width) { - padding-top: 0; - .cover-image { - border-top: 0; - } - } -} - -form { - padding: $sp; - border: 1px solid #cfead3; - background: #f3fff5; - border-radius: 0 0 8px 8px; - border-top-width: 4px; - display: flex; - flex-direction: column; - align-items: baseline; - - > *:not(label):not(input[type='submit']) { - margin-bottom: $sp*0.5; - } - - input[type=submit] { - padding: 10px 30px; - margin-top: $sp*0.5; - } -} - -.bordered { - border: 1px solid $grid-color; -} - -/* Buttons -------------------------------------------------------- */ -button, a.button, input[type=submit] { - cursor: pointer; - display: inline-block; - font-weight: 600; - text-align: center; - -webkit-backdrop-filter: blur(10px); - backdrop-filter: blur(10px); - border: 0; - padding: 2px 8px; - border-radius: 6px; - - &:hover { - filter: brightness(1.1); - } - - &.bordered { - border: 1px solid $primary-color; - font-size: 0.95em; - - &:hover { - background: rgba(0, 0, 0, 0.05); - } - } - &.large { - padding: 10px 20px; - } - &.wide { - padding: 4px 24px; - } - &.white { - border-color: white; - color: white; - &:hover { - background: rgba(255, 255, 255, 0.1); - } - } - - &.prominent { - background-color: $primary-color; - color: white; - &:hover { - border-color: $primary-color-alt; - background: $primary-color-alt; - } - } - - &.external:after { - content: " "; - background-image: url('data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20512%20512%22%20fill%3D%22%23fff%22%3E%3C!--!%20Font%20Awesome%20Free%206.4.2%20by%20%40fontawesome%20-%20https%3A%2F%2Ffontawesome.com%20License%20-%20https%3A%2F%2Ffontawesome.com%2Flicense%20(Commercial%20License)%20Copyright%202023%20Fonticons%2C%20Inc.%20--%3E%3Cpath%20d%3D%22M320%200c-17.7%200-32%2014.3-32%2032s14.3%2032%2032%2032h82.7L201.4%20265.4c-12.5%2012.5-12.5%2032.8%200%2045.3s32.8%2012.5%2045.3%200L448%20109.3V192c0%2017.7%2014.3%2032%2032%2032s32-14.3%2032-32V32c0-17.7-14.3-32-32-32H320zM80%2032C35.8%2032%200%2067.8%200%20112V432c0%2044.2%2035.8%2080%2080%2080H400c44.2%200%2080-35.8%2080-80V320c0-17.7-14.3-32-32-32s-32%2014.3-32%2032V432c0%208.8-7.2%2016-16%2016H80c-8.8%200-16-7.2-16-16V112c0-8.8%207.2-16%2016-16H192c17.7%200%2032-14.3%2032-32s-14.3-32-32-32H80z%22%2F%3E%3C%2Fsvg%3E'); - background-repeat: no-repeat; - display: inline-block; - height: 0.8em; - width: 0.8em; - margin-left: 0.3em; - } -} - -.site-wordmark { - display: flex; - align-items: center; - font-family: $serif-font; - font-weight: bold; - font-size: 21px; - white-space: nowrap; - - .logo { - height: 30px; - margin-right: $sp*0.25; - position: relative; - top: 2px; - } - - .text { - color: inherit; - } -} - - -/* Header -------------------------------------------------------- */ -.topbar { - position: fixed; - top: 0; - border-top: 5px solid $primary-color; - z-index: 10000; - background: $background-color; - width: 100%; - height: $topbar-height; - border-bottom: 1px solid $grid-color; - - .site-wordmark { - color: inherit; - } - - .container { - display: flex; - justify-content: space-between; - height: 100%; - } - - @media only screen and (max-width: $sections-width) { - position: relative; - height: $topbar-height*1.8; - .container { - flex-direction: column; - align-items: center; - padding-top: $sp*0.33333; - } - } -} - -.layout-body { - background: $background-color; - position: relative; - margin-top: $topbar-height; - - min-height: calc(100vh - $topbar-height - $footer-min-height); - - @media only screen and (max-width: $sections-width) { - margin-top: 0; - } -} - -ul.headernav { - display: flex; - flex-flow: row nowrap; - align-items: center; - height: 100%; - - > li { - flex: 0 1 100%; - font-size: 16px; - font-weight: 600; - white-space: nowrap; - height: 100%; - - display: flex; - align-items: center; - position: relative; - - &:last-child { - margin-left: $sp*0.5; - } - - a { - display: flex; - align-items: center; - } - - > a:not(.bordered) { - padding: 0 min($sp, 1.5vw); - color: $text-color; - height: 100%; - } - - ul.submenu { - display: none; - position: absolute; - top: 100%; - left: calc(min($sp, 1.5vw) - $sp*0.5); - background: white; - border: 1px solid $grid-color; - border-radius: 5px; - border-top-left-radius: 0; - box-shadow: 1px 1px 2px rgba(0,0,0,0.1); - - &::before { - content: " "; - background: white; - position: absolute; - left: 0; - top: -1px; - height: 1px; - width: 80px; - } - - a { - height: 100%; - width: 100%; - padding: $sp*0.25 $sp*0.5 $sp*0.5 $sp*0.5; - color: inherit; - font-weight: 400; - line-height: 1em; - } - } - /* don't show hover menu on touch taps */ - @media (hover: hover) { - &:hover { - ul.submenu { - display: block; - } - } - } - } -} - -body:not(.layout-post):not(.layout-session) { - .pagenav a { - color: inherit; - } -} - -.breadcrumbs, .pagenav { - width: 100%; - z-index: 1000; -} -.breadcrumbs, .pagenav ul { - font-size: 16px; - font-weight: 600; -} - -.breadcrumbs { - margin-bottom: $sp; - &:empty { - display: none; - } - .iconsvg { - margin-top: -2px; - } - a { - color: inherit; - } -} - -.pagenav { - display: flex; - align-items: baseline; - justify-content: space-between; - border-bottom: 1px solid $alpha-grid-color; - margin-bottom: $sp; - - .meta { - margin-bottom: $sp*0.5; - } - - > *:last-child { - margin-bottom: $sp*0.5; - } - - li { - display: inline; - white-space: nowrap; - &:not(:last-child) { - margin-right: 2vw; - } - } - - @media only screen and (max-width: $sections-width) { - flex-direction: column; - } -} -.layout-page.has-image { - .pagenav { - border-bottom: none; - margin-bottom: 0; - } -} -#hero-map { - width: 100%; - height: 50vw; - max-height: 70vh; - min-height: 30vh; - border-bottom: 1px solid $grid-color; - - .custom-marker { - background-color: var(--color); - border-radius: 50%; - width: 20px; - height: 20px; - cursor: pointer; - } - - .custom-marker::after { - position: absolute; - content: ''; - background-image: var(--icon-image); - background-position: center; - background-size: 70%; - background-repeat: no-repeat; - filter: invert(1); - width: 100%; - height: 100%; - border-radius: 50%; - } - - .custom-marker::before { - position: absolute; - content: ''; - width: 0px; - height: 0px; - bottom: -100%; - border: 10px solid transparent; - border-top: 17px solid var(--color); - } -} - -figcaption { - background-color: rgba(0,0,0,0.5); - -webkit-backdrop-filter: blur(10px); - backdrop-filter: blur(10px); - position: absolute; - right: 0; - bottom: 0; - max-width: min($text-width*0.8, 100%); - padding: calc($sp/6) calc($sp/4); - font-style: italic; - line-height: 1.3; - font-size: 0.9em; - color: white; - - a, a:visited { - color: #00e723; - } - a:hover, a:focus, a:active { - color: #00ff27; - } - - &.left { - right: initial; - left: 0; - } -} - -.cover { - color: white; - width: 100%; - position: relative; - background-position: center; - background-size: cover; - overflow-x: hidden; - - .pagenav { - border-bottom-color: rgba(255, 255, 255, 0.25); - } - - &.video { - background: black; - line-height: 0; - } - - .cover-image-container { - position: relative; - } - - .cover-image { - border: 1px solid $grid-color; - } - - .cover-image, .cover-video { - width: 100%; - max-height: min(70vh, 50vw); - height: $cover-image-height; - background-size: cover; - background-position: center; - background-repeat: no-repeat; - position: relative; - } - - figcaption { - right: 1px; - bottom: 1px; - max-width: min($text-width*0.8, calc(100%) - 2px); - } -} -.layout-project .cover, .layout-person .cover { - background: linear-gradient(-135deg, #002042, #022D48); -} - -iframe.embedded-page-viewer { - width: 100%; - height: calc(80vh - $topbar-height); - border: 1px solid $grid-color; - border-radius: 4px; - overflow: hidden; -} - -/* Project page --------------------------------------------- -*/ -$hero-overlap: 150px; - -.layout-project { - - .cover { - .logo-area { - display: flex; - - > * { - width: 100%; - } - - .logo-wrap { - flex: 0 0 auto; - width: $avatar-width; - max-height: $avatar-width*1.25; - margin-right: $sp*1.5; - text-align: center; - - img { - max-width: 100%; - max-height: 100%; - } - } - @media only screen and (max-width: $sections-width) { - flex-direction: column; - - .logo-wrap { - margin-right: 0; - margin-bottom: $sp; - } - - img.wordmark { - margin-top: 0; - } - } - } - a { - display: inline-block; - color: inherit; - } - > .container { - margin-top: $sp; - margin-bottom: $sp; - } - &.with-hero-image { - padding-bottom: $hero-overlap; - } - - .blurb a { - text-decoration: underline; - } - } - - img.wordmark { - max-width: 100%; - max-height: 86px; - } - - .blurb, .tagline { - max-width: $text-width; - } - - .cover .container .logo-area .right > *:not(:last-child) { - margin-bottom: $sp*0.5; - } - .tagline { - font-style: italic; - font-weight: bold; - font-size: 20px; - } - img.hero-image { - width: 100%; - border-radius: 5px; - border: 1px solid $alpha-grid-color; - margin-top: -$hero-overlap; - } - -} - -.buttons { - display: flex; - align-items: center; - justify-content: space-between; - margin-top: $sp; - - margin-bottom: -$sp; - - a { - margin-bottom: $sp; - } - .button { - flex: 0 0 auto; - } - .text-buttons > .button:not(:last-child) { - margin-right: $sp*0.75; - } - - @media only screen and (max-width: $sections-width) { - flex-direction: column; - align-items: baseline; - } -} -.banner-footer { - width: 100%; - padding-top: $sp; - position: relative; - color: #fff; -} -table.schedule { - table-layout: auto; - th, td { - padding: 10px 14px; - border-right: 1px solid $grid-color; - &:first-child { - border-left: 1px solid $grid-color; - } - } - td { - &:first-child { - width: 100px; - } - .title { - font-weight: 600; - } - } - - tr { - transition: 200ms ease-in-out; - } - - tr.interstitial { - background: hsl(0, 0%, 97%); - .title { - font-weight: normal; - font-style: italic; - } - } - - tr.ongoing { - border-top: 2px solid $status-color; - background: #E5F7FC; - td:first-child { - padding-top: 18px; - font-weight: 600; - position: relative; - - &:before { - content: "Happening Now"; - display: block; - position: absolute; - top: -14px; - border-radius: 13px; - background-color: $status-color; - color: white; - font-size: 14px; - font-weight: bold; - width: 124px; - height: 26px; - text-align: center; - left: -13px; - } - } - .title { - font-weight: bold; - } - } -} - -.icon-buttons { - display: flex; - flex-direction: row; - flex-wrap: wrap; - > li { - &:not(:last-child) { - margin-right: $sp*0.25; - } - } - .iconsvg { - vertical-align: middle; - height: 30px; - width: 30px; - } -} - -.section { - width: 100%; - .section-header { - border-bottom: 1px solid $alpha-grid-color; - margin-bottom: $sp; - display: flex; - align-items: baseline; - justify-content: space-between; - - h2, h3 { - white-space: nowrap; - } - } - a.section-button { - font-weight: 600; - } - margin-bottom: $sp; - - & > *:not(.prose) { - h1, h2, h3, h4, h5, h6 { - font-family: $serif-font !important; - } - } - &:empty { - display: none; - } -} - -/* Person page --------------------------------------------- -*/ -.layout-person { - $avatar-border-width: 5px; - - h1 { - margin: 0; - } - - .cover { - min-height: 200px; - } - - &.has-cover { - .cover { - background: none; - } - } - - .hero-avatar { - width: 100%; - padding-bottom: calc(100% - $avatar-border-width*2); - position: relative; - margin-top: -84px; - border: $avatar-border-width solid $background-color; - } - - .sections { - display: flex; - flex-direction: column; - } - .section { - width: auto; - display: flex; - justify-content: right; - margin: 0 auto; - - .section-body { - padding: $sp*0.75; - padding-left: 0; - border-bottom: 1px solid $grid-color; - - &.prose { - padding-bottom: 0; - } - } - - > h3 { - padding-top: $sp*0.75; - } - - > *:first-child { - width: 210px; - text-align: right; - padding-right: $sp*0.75; - } - > *:last-child { - width: $text-width; - max-width: 100%; - flex: 0 0 auto; - border-right: 1px solid $grid-color; - } - &:last-child > *:last-child { - border-bottom: 0; - } - - .name-header { - padding-top: 0; - } - } - .connect-links a:not(:last-child) { - margin-right: $sp; - } - - @media only screen and (max-width:$sections-width) { - .hero-avatar { - margin-left: auto; - margin-right: auto; - width: 210px; - height: 210px; - padding: 0; - } - .cover figcaption { - top: 1px; - bottom: initial; - } - .name-header { - text-align: center; - } - .sections { - padding-left: $sp*0.75; - } - .section { - flex-direction: column; - width: 100%; - - - > *:first-child { - width: 100%; - margin: 0 auto; - max-width: $text-width; - text-align: center; - } - > h3 { - border-right: 1px solid $grid-color; - } - > h3:empty { - display: none; - } - > *:last-child { - margin: 0 auto; - } - } - } -} - -.item-list { - position: relative; - - .item-listing { - display: flex; - justify-content: left; - max-width: 100%; - &:not(:last-child) { - margin-bottom: $sp; - } - - .listing-front { - max-width: 100%; - width: 360px; - position: relative; - flex: 0 0 auto; - - &:empty { - height: 0; - } - - .thumbnail-image { - position: relative; - width: 100%; - background-size: cover; - background-position: center; - background-repeat: no-repeat; - display: block; - border: 1px solid $alpha-grid-color; - - transition: transform 100ms ease-in-out; - - &:hover { - transform: scale(1.04); - z-index: 9999; - - .iconsvg { - opacity: 0.9; - } - } - - .iconsvg { - color: white; - opacity: 0.75; - width: 20px; - height: 20px; - position: absolute; - right: 10px; - bottom: 10px; - } - } - .rect-image { - border-radius: 2px; - height: $list-item-image-height; - } - } - - .listing-body { - padding-left: $sp; - max-width: $text-width; - - &:empty { - display: none; - } - &:first-child { - padding-left: 0; - } - - & > * { - margin-bottom: $sp*0.25; - } - .button { - margin-top: $sp*0.25; - } - .subtitle { - line-height: 1.2; - font-style: italic; - } - } - - &.contained-image { - .listing-front { - width: $avatar-width; - } - } - &.contained-image .thumbnail-image, - .thumbnail-image.contained-image { - height: $list-item-image-height; - background-size: contain; - border: 0; - } - - @media only screen and (max-width: $sections-width) { - flex-wrap: wrap; - .listing-front { - width: 100%; - } - .listing-body { - padding-left: 0; - padding-top: $sp*0.5; - } - } - } - - &.gallery { - display: flex; - flex-wrap: wrap; - .item-listing { - flex-direction: column; - align-items: center; - text-align: center; - width: $avatar-width; - flex: 0 0 auto; - - .listing-front { - width: 100%; - } - .thumbnail-image { - width: 80%; - padding-bottom: 80%; - margin: 0 auto; - } - - .listing-body { - padding: 0; - margin-top: $sp*0.5; - } - } - - @media only screen and (max-width: calc($avatar-width*2 + $container-padding*2)) { - &:not(.scroll) { - justify-content: center; - } - } - &:not(.pages-list):not(.people-list):not(.swag-list) { - - .item-listing { - width: calc($content-width * 0.333); - - align-items: baseline; - .listing-front .thumbnail-image { - width: 92%; - padding: 0; - } - - .listing-body { - width: 92%; - margin-left: auto; - margin-right: auto; - } - - h3 { - text-align: left; - } - } - - &.no-titles { - - .item-listing { - margin: 0; - .listing-front .thumbnail-image { - height: 196px; - width: 100%; - border-radius: 0; - border-width: 0.5px; - } - - } - } - - &.scroll { - .item-listing { - width: calc($content-width * 0.27); - .listing-front .thumbnail-image { - height: 148px; - } - } - .thumbnail-image, .listing-body { - margin-left: 0; - } - } - } - } - - &.people-list { - - .listing-front { - width: $avatar-width; - height: auto; - - .thumbnail-image { - width: 80%; - padding-bottom: 80%; - margin: 0 auto; - } - } - .listing-body { - padding-left: $sp*0.5; - } - } - - &.scroll { - flex-wrap: nowrap; - overflow-x: auto; - } - - &.swag-list { - h3 { - font-family: $sans-serif-font !important; - font-size: 1em; - } - } -} - -.simple-item-listing { - display: flex; - justify-content: space-between; - line-height: 1.25; - .date { - white-space: nowrap; - } - &:not(:last-child) { - margin-bottom: $sp*0.75; - } -} - -.title { - .iconsvg { - width: 0.6em; - height: 0.6em; - } -} - -.content { - padding-top: $sp; - padding-bottom: $sp*2; - width: 100%; -} - -article { - position: relative; - margin: auto; - display: flex; - flex-direction: column; - align-items: center; - - .post-header { - padding-top: $sp; - width: 100%; - margin: 0 auto; - position: relative; - } - .post-body { - margin-bottom: $sp*2; - } -} - -.prose { - display: flex; - flex-direction: column; - align-items: baseline; - position: relative; - z-index: 0; - - h2, h3, h4, h5, h6 { - font-family: $sans-serif-font; - } - - li { - list-style: disc; - margin-left: 20px; - } - ol { - li { - list-style: decimal; - } - } - - >, blockquote { - - .neatline { - position: absolute; - height: calc(100% + $sp); - width: calc(100% + $container-padding); - max-width: calc($text-width + $sp*2); - left: 0; - right: 0; - top: -$sp; - border-right: 1px solid $grid-color; - z-index: -1; - - @media only screen and (max-width: calc($text-width + $container-padding*2)) { - display: none; - } - } - - iframe, table, form, a, em, b, strong, i, p, ol, ul, - code, blockquote, q, h1, h2, h3, h4, h5, h6, hr, pre, center { - width: 100%; - max-width: $text-width; - margin-bottom: $sp; - } - img, figure, .img-container, div { - margin-bottom: $sp; - } - hr { - padding: 0; - width: 100%; - max-width: calc($text-width + $sp*2); - position: relative; - } - img, figure, .img-container, iframe, table { - max-width: $img-width; - border: 1px solid $grid-color; - background-color: $background-color; - padding: 0; - - &.wide { - max-width: 100%; - } - - @media only screen and (max-width: calc($img-width + $container-padding*2)) { - max-width: 100%; - } - } - figure, .img-container { - line-height: 0; - position: relative; - - img { - width: 100%; - } - } - blockquote, q { - position: relative; - left: 0.75em; - padding-left: $sp; - border-left: 6px solid $grid-color; - width: calc(100% - 1em); - max-width: calc($text-width - 1em); - } - } -} - -/* About -------------------------------------------------------- */ -.board-members img { - max-width: 50%; - margin: 0px auto 10px auto; - display: block; -} - -.board-members p { - margin-bottom: 40px; -} - - -/* Blog Post -------------------------------------------------------- */ - -.avatar { - background-image: url($baseurl + "/assets/avatar.jpg"); - background-color: white; - border-radius: 50%; - background-size: cover; - background-position: center; - flex: 0 0 auto; -} - -.inline-avatar { - display: inline-block; - vertical-align: text-top; - width: 24px; - height: 24px; - margin-right: 4px; -} - -/* 404 -------------------------------------------------------- */ -.notfound { - padding: 100px 100px; - text-align: center; - color: #999; - text-shadow: 1px 1px 2px #eee; - font-size: 25px; -} -.notfound h1 { - font-size: 50px; -} - -/* Footer -------------------------------------------------------- */ -.footer { - min-height: $footer-min-height; - font-size: 17px; - border-top: 1px solid rgb(60, 60, 60); - position: relative; - margin-top: 0px; - display: flex; - flex-flow: row nowrap; - padding: $sp 0; - - .top { - display: flex; - justify-content: space-between; - - @media only screen and (max-width: $sections-width) { - flex-direction: column; - - .site-wordmark { - margin-bottom: $sp; - } - } - } - - .sitemap { - display: flex; - flex-direction: row; - flex-wrap: wrap; - ul { - width: $avatar-width; - margin-bottom: $sp; - li { - white-space: nowrap; - - &:first-child { - font-weight: 600; - } - &:not(:last-child) { - margin-right: $sp*0.5; - } - } - } - a { - color: inherit; - } - } - - .smallprint { - display: flex; - justify-content: space-between; - } -} - -.status-bubble { - color: white; - background: $status-color; - border-radius: 20px; - position: absolute; - top: -10px; - font-weight: bold; - font-size: 0.75em; - padding: 0 $sp*0.5; -} - -.app-sign { - background-position: center; - background-size: cover; - border-radius: 16px; - border: 1px solid $grid-color; - height: 140px; - - .status-bubble { - top: -10px; - right: -10px; - } -} -.status-symbol { - color: $status-color; -} - -.hoverscale { - transition: transform 100ms ease-in-out; - - &:hover { - transform: scale(1.04); - z-index: 9999; - } -} - -.mono-logos { - img { - filter: brightness(0) invert(1); - } -} - -ul.org-members { - - padding-left: $sp*1.5; - - display: flex; - flex-wrap: wrap; - - li { - max-width: 100%; - list-style: none; - margin-left: 0; - margin-bottom: $sp; - &:not(:last-child) { - margin-right: $sp*2; - } - - img { - width: auto; - height: 100%; - max-width: 100%; - object-fit: contain; - } - } -} - -ul.org-members.level-5 li { - height: 70px; -} - -ul.org-members.level-4 li { - height: 80px; -} - -ul.org-members.level-3 li { - height: 90px; -} - -ul.org-members.level-2 li { - height: 100px; -} - -ul.org-members.level-1 li { - height: 108px; -} - -.directory { - display: flex; - flex-wrap: wrap; - .list-wrap { - flex-basis: 25%; - min-width: 200px; - padding-bottom: $sp; - padding-right: $sp*0.5; - white-space: nowrap; - } -} - -#notice-overlay { - position: fixed; - bottom: $sp*0.5; - right: $sp*0.5; - background: white; - border: 1px solid $grid-color; - border-radius: 4px; - padding: $sp*0.75 $sp*0.5; - box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.12); - - display: flex; - flex-direction: row; - - .logo { - width: 60px; - margin-right: $sp*0.5; - } - .status-bubble { - left: -10px; - } -} - -.cond-only { - display: none; -} -.condensed { - .no-cond { - display: none; - } -} -.condensed { - .cond-only { - display: initial; - } -} -.condensed { - .simple-item-listing > *:first-child { - display: flex; - flex-direction: column; - } -} -@media only screen and (max-width: $sections-width) { - .no-cond { - display: none !important; - } - .cond-only { - display: initial; - } - - .simple-item-listing > *:first-child { - display: flex; - flex-direction: column; - } -} \ No newline at end of file diff --git a/_sass/dogwood/custom-variables.scss b/_sass/dogwood/custom-variables.scss index 2a2d0fa..59ea803 100644 --- a/_sass/dogwood/custom-variables.scss +++ b/_sass/dogwood/custom-variables.scss @@ -1 +1,5 @@ -// Placeholder to allow overriding predefined variables smoothly. +$background-color: white; +$primary-color: #22b663; +$primary-color-alt: #22b663; +$status-color: #930041; + diff --git a/_sass/dogwood/initialize.scss b/_sass/dogwood/initialize.scss deleted file mode 100644 index ff620bd..0000000 --- a/_sass/dogwood/initialize.scss +++ /dev/null @@ -1,44 +0,0 @@ -@charset "UTF-8"; - -$sans-serif-font: Helvetica, Arial, sans-serif; -$serif-font: Georgia, serif; - -$background-color: white; -$primary-color: #22b663; -$primary-color-alt: #22b663; -$status-color: #930041; - -$grid-color: #dedede; -/* the below should look the same as the above when on a white bg */ -/* $alpha-grid-color: rgba(0, 0, 0, 0.13); */ -$alpha-grid-color: rgba(128, 128, 128, 0.26); -$text-color: #333; -$dark-background-color: #333; -$dark-grid-color: rgba(255, 255, 255, 0.13); - -$body-text-size: 18px; -$sp: 24px; -$container-width: 1100px; -$container-padding: $sp*0.75; -$content-width: calc($container-width - $container-padding * 2); -$cover-image-height: $container-width * 0.5; -$text-width: 700px; -$img-width: 880px; - -$footer-min-height: 490px; - -$topbar-height: 54px; - -$avatar-width: calc($content-width * 0.2); - -$sections-width: 720px; - -$list-item-image-height: 180px; - -// Import pre-styling-overrides hook and style-partials. -@import - "dogwood/custom-variables", // Hook to override predefined variables. - "dogwood/base", // Defines element resets. - "dogwood/layout", // Defines structure and style based on CSS selectors. - "dogwood/custom-styles" // Hook to override existing styles. -; diff --git a/_tools/embedded-page-cacher/index.js b/_tools/embedded-page-cacher/index.js deleted file mode 100644 index e6b9cdc..0000000 --- a/_tools/embedded-page-cacher/index.js +++ /dev/null @@ -1,139 +0,0 @@ -// embedded-page-cacher for dogwood -// -// This script saves local versions of remote pages linked -// in the `embedded_remote` property of `_posts`. Pages -// and their images are saved to `/embeds/cached/` with the -// full local URL saved to the `embedded` property. You can -// then use the `embedded-page` layout to display these pages -// in an iframe. -// -// This script is used on openstreetmap.us to cache our newsletters. -// Cacheing ensures the content will always be available, but also -// fixes cross-origin issues with iframes. For instance, we want -// clicked links to open in the browser window and not within the iframe. - -import fs from 'fs'; -import followRedirects from 'follow-redirects'; -const https = followRedirects.https; -import graymatter from 'gray-matter'; -import filenamifyUrl from 'filenamify-url'; - -import process from 'process'; -import minimist from 'minimist'; -const argv = minimist(process.argv.slice(2)); -let sourcePath = process.env.npm_config_srcdir || argv.srcdir || '.'; -if (sourcePath.endsWith('/')) sourcePath.slice(0, -1); - -const inDir = sourcePath + '/_posts'; -const outRelativeDir = '/embeds/cached' -const outDir = sourcePath + outRelativeDir; - -if (!fs.existsSync(outDir)) fs.mkdirSync(outDir); - -cacheRemoteLinks(inDir); - -function cacheRemoteLinks(path) { - - const dir = fs.opendirSync(path); - let dirent; - while ((dirent = dir.readSync()) !== null) { - const subpath = path + '/' + dirent.name; - if (dirent.isFile()) { - - const filedata = fs.readFileSync(subpath); - const frontmatter = graymatter(filedata); - - // ignore files not in Jekyll format - if (Object.keys(frontmatter.data).length > 0) { - let remoteUrl = frontmatter.data.embedded_remote; - if (remoteUrl) { - let slug = filenamifyUrl(remoteUrl); - let outPath = outDir + '/' + slug + '/'; - if (!fs.existsSync(outPath)) { - fs.mkdirSync(outPath); - cacheRemoteWebpage(remoteUrl, outPath); - - frontmatter.data.embedded = outRelativeDir + '/' + slug; - - let newFileContent = graymatter.stringify(frontmatter, frontmatter.data); - fs.writeFileSync(subpath, newFileContent); - console.log(`updated ${subpath}`); - } - } - } - } else if (dirent.isDirectory()) { - cacheRemoteLinks(subpath); - } - } - dir.closeSync(); -} - - -function cacheRemoteWebpage(url, toPath) { - console.log(url); - - var content = ""; - - var req = https.request(url, function(res) { - res.setEncoding("utf8"); - res.on("data", function (chunk) { - content += chunk; - }); - - res.on("end", function () { - content = content.trim() - // we want all links to open in new tabs instead of in the iframe - .replace('', ''); - - content = cacheRemoteImages(content, toPath); - - fs.writeFileSync(toPath + "index.html", content); - console.log(`cached ${url} to ${toPath}`); - }); - }); - - req.on('error', (e) => { - console.error(`problem with request: ${e.message}`); - }); - - req.end(); -} - -function cacheRemoteImage(url, toPath) { - - var content = ""; - - var req = https.request(url, function(res) { - res.setEncoding('binary'); - res.on("data", function (chunk) { - content += chunk; - }); - - res.on("end", function () { - fs.writeFileSync(toPath, content, "binary"); - console.log(`cached ${url} to ${toPath}`); - }); - }); - - req.on('error', (e) => { - console.error(`problem with request: ${e.message}`); - }); - - req.end(); -} - -function cacheRemoteImages(html, toPath) { - if (!fs.existsSync(toPath + "img/")){ - fs.mkdirSync(toPath + "img/"); - } - - let imgRegex = /src="(\S+?\.(?:png|jpg|jpeg|gif|svg|tif|tiff|pdf))\S*?"/gi; - const matches = html.matchAll(imgRegex); - for (const match of matches) { - let imgUrl = match[1]; - let slug = filenamifyUrl(imgUrl); - html = html.replaceAll(imgUrl, "img/" + slug); - cacheRemoteImage(imgUrl, toPath + "img/" + slug); - } - return html; -} diff --git a/_tools/frontmatter-validator/index.js b/_tools/frontmatter-validator/index.js deleted file mode 100644 index b687df2..0000000 --- a/_tools/frontmatter-validator/index.js +++ /dev/null @@ -1,97 +0,0 @@ -// frontmatter-validator for dogwood -// -// This script checks that the frontmatter in all your -// Jekyll documents matches a known format. This is important -// since the theme relies on many custom variables. -// -// By default, the script will throw an error if you have -// additional properties to those expected. This catches -// typos like `authors` instead of `author`. Use the -// `--strict=false` option to turn off this behavior. - -import fs from 'fs'; -import graymatter from 'gray-matter'; -import path from 'path'; -import {fileURLToPath} from 'url'; - -import process from 'process'; -import minimist from 'minimist'; -const argv = minimist(process.argv.slice(2)); -let sourcePath = process.env.npm_config_srcdir || argv.srcdir || '.'; -if (sourcePath.endsWith('/')) sourcePath.slice(0, -1); - -import ZSchema from 'z-schema'; - -let zSchemaOptions = {}; - -let isStrict = true; -if (("npm_config_strict" in process.env && !process.env.npm_config_strict) || - process.argv.includes("--strict=false")) { - isStrict = false; -} - -if (isStrict) { - let strictOptions = { - assumeAdditional: true, - forceItems: true, - forceMinItems: true, - forceMinLength: true, - forceProperties: true, - noEmptyArrays: true, - noEmptyStrings: true, - noExtraKeywords: true, - noTypeless: true, - }; - Object.assign(zSchemaOptions, strictOptions); -} - -const jsonValidator = new ZSchema(zSchemaOptions); - -let hasInvalid = false; - -function validateJson(json, schema) { - const valid = jsonValidator.validate(json, schema); - const errors = jsonValidator.getLastErrors(); - if (!valid) { - errors.forEach(function(error) { - console.log(error); - }); - hasInvalid = true; - } -} - -function validateFrontmatter(path, schemaPath) { - const schema = JSON.parse(fs.readFileSync(schemaPath)); - const dir = fs.opendirSync(path); - let dirent; - while ((dirent = dir.readSync()) !== null) { - const subpath = path + '/' + dirent.name; - if (dirent.isFile()) { - const filedata = fs.readFileSync(subpath); - const info = graymatter(filedata); - - // ignore files not in Jekyll format - if (Object.keys(info.data).length > 0) { - // parse to string and back again to make sure dates are in string format - let data = JSON.parse(JSON.stringify(info.data)); - validateJson(data, schema); - } - } else if (dirent.isDirectory()) { - validateFrontmatter(subpath, schemaPath); - } - } - dir.closeSync(); -} - -const directory = path.dirname(fileURLToPath(import.meta.url)); -var schemasDir = path.join(directory, '/schemas'); - -validateFrontmatter(sourcePath + '/_posts', schemasDir + '/post.json'); -validateFrontmatter(sourcePath + '/_people', schemasDir + '/person.json'); -validateFrontmatter(sourcePath + '/_pages', schemasDir + '/page.json'); -validateFrontmatter(sourcePath + '/_redirects', schemasDir + '/redirect.json'); - -if (hasInvalid) { - // nonzero exit for GitHub Actions - process.exit(1); -} \ No newline at end of file diff --git a/_tools/frontmatter-validator/schemas/page.json b/_tools/frontmatter-validator/schemas/page.json deleted file mode 100644 index 84cef98..0000000 --- a/_tools/frontmatter-validator/schemas/page.json +++ /dev/null @@ -1,281 +0,0 @@ -{ - "title": "Page", - "type": "object", - "properties": { - "title": { - "type": "string" - }, - "temp_title": { - "type": "string" - }, - "short_title": { - "type": "string" - }, - "tagline": { - "type": "string" - }, - "temp_tagline": { - "type": "string" - }, - "blurb": { - "type": "string" - }, - "temp_blurb": { - "type": "string" - }, - "layout": { - "type": "string" - }, - "event": { - "type": "string" - }, - "event_series": { - "type": "string" - }, - "caption": { - "type": "string" - }, - "status": { - "type": "string" - }, - "location": { - "type": "string" - }, - "image": { - "type": "string" - }, - "sign": { - "type": "string" - }, - "logo": { - "type": "string" - }, - "wordmark": { - "type": "string" - }, - "icon": { - "type": "string" - }, - "website": { - "type": "string" - }, - "twitter": { - "type": "string" - }, - "youtube_page": { - "type": "string", - "description": "Path to a page on youtube.com. Different from `youtube` since that parameter is a video ID which is used differently." - }, - "facebook": { - "type": "string" - }, - "slack_channel": { - "type": "string" - }, - "instagram": { - "type": "string" - }, - "email_list": { - "type": "string" - }, - "meetup": { - "type": "string" - }, - "reddit": { - "type": "string" - }, - "mastodon": { - "type": "string" - }, - "donate": { - "type": "string" - }, - "links": { - "type": "array", - "items": { - "type": "object", - "properties": { - "label": { - "type": "string" - }, - "link": { - "type": "string" - } - } - } - }, - "swag_items": { - "type": "array", - "items": { - "type": "object", - "properties": { - "title": { - "type": "string" - }, - "url": { - "type": "string" - }, - "image": { - "type": "string" - } - } - } - }, - "swag_sections": { - "type": "array", - "items": { - "type": "object", - "properties": { - "title": { - "type": "string" - }, - "items": { - "type": "array", - "items": { - "type": "object", - "properties": { - "title": { - "type": "string" - }, - "url": { - "type": "string" - }, - "image": { - "type": "string" - } - } - } - } - } - } - }, - "dropdown_links": { - "type": "array", - "items": { - "type": "object", - "properties": { - "label": { - "type": "string" - }, - "link": { - "type": "string" - } - } - } - }, - "app_links": { - "type": "array", - "items": { - "type": "object", - "properties": { - "label": { - "type": "string" - }, - "link": { - "type": "string" - } - } - } - }, - "footer_links": { - "type": "array", - "items": { - "type": "object", - "properties": { - "label": { - "type": "string" - }, - "link": { - "type": "string" - } - } - } - }, - "buttons": { - "type": "array", - "items": { - "type": "object", - "properties": { - "label": { - "type": "string" - }, - "link": { - "type": "string" - } - } - } - }, - "sessions": { - "type": "array", - "items": { - "type": "object", - "properties": { - "title": { - "type": "string" - }, - "blurb": { - "type": "string" - }, - "date": { - "oneOf": [ - { - "type": "string", - "format": "date-time" - }, - { - "type": "string", - "pattern": "\\d{4}-[01]\\d-[0-3]\\d [0-2]\\d:[0-5]\\d(:[0-5]\\d)? ([+-][0-2]\\d[0-5]\\d)" - } - ] - } - } - } - }, - "section_tags": { - "type": "array", - "items": { - "type": "string" - } - }, - "team_name": { - "type": "string" - }, - "max_posts": { - "type": "integer" - }, - "updated": { - "type": "string", - "format": "date-time" - }, - "timezone": { - "type": "string" - }, - "filter_start": { - "type": "string", - "format": "date-time" - }, - "filter_end": { - "type": "string", - "format": "date-time" - }, - "start": { - "type": "string", - "format": "date-time" - }, - "end": { - "type": "string", - "format": "date-time" - }, - "map": { - "type": "object", - "properties": { - "points": { - "type": "string" - } - } - } - }, - "required": [ - "title" - ] - } \ No newline at end of file diff --git a/_tools/frontmatter-validator/schemas/person.json b/_tools/frontmatter-validator/schemas/person.json deleted file mode 100644 index f2d0cda..0000000 --- a/_tools/frontmatter-validator/schemas/person.json +++ /dev/null @@ -1,77 +0,0 @@ -{ - "title": "Person", - "type": "object", - "properties": { - "title": { - "type": "string" - }, - "updated": { - "type": "string", - "format": "date-time" - }, - "roles": { - "type": "array", - "items": { - "type": "object", - "properties": { - "title": { - "type": "string" - }, - "at": { - "type": "string" - }, - "from": { - "type": "string", - "format": "date-time" - }, - "to": { - "type": "string", - "format": "date-time" - } - }, - "required": [ - "at" - ] - } - }, - "image": { - "type": "string" - }, - "image_remote": { - "type": "string" - }, - "cover": { - "type": "string" - }, - "caption": { - "type": "string" - }, - "linkedin": { - "type": "string" - }, - "twitter": { - "type": "string" - }, - "github": { - "type": "string" - }, - "osm": { - "type": "string" - }, - "website": { - "type": "string" - }, - "wikipedia": { - "type": "string" - }, - "mastodon": { - "type": "string" - }, - "medium": { - "type": "string" - } - }, - "required": [ - "title" - ] - } \ No newline at end of file diff --git a/_tools/frontmatter-validator/schemas/post.json b/_tools/frontmatter-validator/schemas/post.json deleted file mode 100644 index 7dbdbfe..0000000 --- a/_tools/frontmatter-validator/schemas/post.json +++ /dev/null @@ -1,113 +0,0 @@ -{ - "title": "session", - "type": "object", - "properties": { - "title": { - "type": "string" - }, - "embedded": { - "type": "string" - }, - "embedded_remote": { - "type": "string" - }, - "permalink": { - "type": "string" - }, - "event": { - "type": "string" - }, - "blurb": { - "type": "string" - }, - "date": { - "oneOf": [ - { - "type": "string", - "format": "date-time" - }, - { - "type": "string", - "pattern": "\\d{4}-[01]\\d-[0-3]\\d [0-2]\\d:[0-5]\\d(:[0-5]\\d)? ([+-][0-2]\\d[0-5]\\d)" - } - ] - }, - "image": { - "type": "string" - }, - "image_remote": { - "type": "string" - }, - "caption": { - "type": "string" - }, - "youtube": { - "type": ["string", "null"] - }, - "video_src": { - "type": "string" - }, - "podbean": { - "type": "string" - }, - "register": { - "type": "string" - }, - "slides": { - "type": "string" - }, - "author": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "speaker": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "tags": { - "type": "array", - "items": { - "type": "string" - } - }, - "block": { - "type": "string" - }, - "time": { - "type": "string" - }, - "day": { - "type": "string" - }, - "room": { - "type": "string" - }, - "length": { - "type": "string" - }, - "type": { - "type": "string" - } - }, - "required": [ - "title" - ] - } \ No newline at end of file diff --git a/_tools/frontmatter-validator/schemas/redirect.json b/_tools/frontmatter-validator/schemas/redirect.json deleted file mode 100644 index 56113a8..0000000 --- a/_tools/frontmatter-validator/schemas/redirect.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "title": "Redirect", - "type": "object", - "properties": { - "permalink": { - "type": "string" - }, - "redirect": { - "type": "string" - }, - "title": { - "type": "string" - } - }, - "required": [ - "redirect" - ] - } \ No newline at end of file diff --git a/_tools/image-cacher/index.js b/_tools/image-cacher/index.js deleted file mode 100644 index ea0f598..0000000 --- a/_tools/image-cacher/index.js +++ /dev/null @@ -1,112 +0,0 @@ -// image-cacher for dogwood -// -// This script fetches remote images referenced in the `image` -// property of `_posts` and `_people` and saves them locally. -// Remote images are sometimes a convenience but they are liable -// to turn into 404s or 403s in time. -// -// Cached images are saved to `/img/posts/cached/` and /img/people/cached/`, -// the `image` property is changed to the local file, and the original `image` -// value is moved to `image_remote` for future reference. -// -// Remember to re-run the thumbnail-generator tool after cacheing images. - -import fs from 'fs'; -import followRedirects from 'follow-redirects'; -const https = followRedirects.https; -import graymatter from 'gray-matter'; - -import process from 'process'; -import minimist from 'minimist'; -const argv = minimist(process.argv.slice(2)); -let sourcePath = process.env.npm_config_srcdir || argv.srcdir || '.'; -if (sourcePath.endsWith('/')) sourcePath.slice(0, -1); - -const imgDir = 'img'; - -const imgKeys = ['image', 'cover']; - -processFiles('_people', 'people'); -processFiles('_posts', 'posts'); - -async function processFiles(jekyllSubdir, imageSubdir) { - let jekyllDirPath = sourcePath + "/" + jekyllSubdir; - const dir = fs.opendirSync(jekyllDirPath); - let dirent; - while ((dirent = dir.readSync()) !== null) { - const subpath = jekyllDirPath + '/' + dirent.name; - if (dirent.isFile()) { - const filedata = fs.readFileSync(subpath); - const info = graymatter(filedata); - - // ignore files not in Jekyll format - if (Object.keys(info.data).length > 0) { - let newFrontmatter = await cacheRemoteImages(info.data, imageSubdir); - if (newFrontmatter) { - let newFileContent = graymatter.stringify(info, newFrontmatter); - fs.writeFileSync(subpath, newFileContent); - console.log(`updated ${subpath}`); - } - } - } else if (dirent.isDirectory()) { - await processFiles(jekyllSubdir + '/' + dirent.name, imageSubdir); - } - } - dir.closeSync(); -} - -async function cacheRemoteImage(url, toPath) { - - return new Promise((resolve) => { - - var content = ""; - - var req = https.request(url, function(res) { - if (res.statusCode !== 200) { - console.error(`status ${res.statusCode} for ${url}`); - resolve(false); - return; - } - res.setEncoding('binary'); - res.on("data", function (chunk) { - content += chunk; - }); - - res.on("end", function () { - fs.writeFileSync(toPath, content, "binary"); - console.log(`cached ${url}`); - resolve(true); - }); - }); - - req.on('error', (e) => { - console.error(`problem with request: ${e.message}`); - resolve(false); - }); - - req.end(); - }); -} - -async function cacheRemoteImages(frontmatter, imageSubdir) { - - - var didCacheAny = false; - for (var i in imgKeys) { - var key = imgKeys[i]; - let imgUrl = frontmatter[key]; - if (imgUrl && imgUrl.startsWith('http')) { - let slug = encodeURIComponent(imgUrl); - frontmatter[key + "_remote"] = frontmatter[key]; - - var cachedDirPath = imgDir + '/' + imageSubdir + '/cached/'; - if (!fs.existsSync(sourcePath + "/" + cachedDirPath)) fs.mkdirSync(sourcePath + "/" + cachedDirPath); - - let relativeOutPath = '/' + cachedDirPath + slug; - frontmatter[key] = relativeOutPath; - var didCache = await cacheRemoteImage(imgUrl, sourcePath + relativeOutPath); - didCacheAny = didCacheAny || didCache; - } - } - if (didCache) return frontmatter; -} diff --git a/_tools/people-validator/index.js b/_tools/people-validator/index.js deleted file mode 100644 index 7a11cdd..0000000 --- a/_tools/people-validator/index.js +++ /dev/null @@ -1,106 +0,0 @@ -// people-validator for dogwood -// -// This script checks to make sure there is a document in the `_people` -// directory for every `author` and `speaker` referenced in your `_posts`. -// This isn't strictly necessary but it enables linking people with the -// various content they're associated with. -// -// Use the `--fix=true` option to automatically create missing files. -// Use the `--strict=false` option to output warnings instead of errors. -// -// Note that the name is the only unique identifier for a person. This -// means you can only reference one person for each unique name, -// and that different version of the name (Jim vs. Jimmy) will be -// treated as different people. - -import fs from 'fs'; -import graymatter from 'gray-matter'; - -import process from 'process'; -import minimist from 'minimist'; -const argv = minimist(process.argv.slice(2)); -let shouldFix = process.env.npm_config_fix || argv.fix; -let hasUnfixedIssue = false; - -let sourcePath = process.env.npm_config_srcdir || argv.srcdir || '.'; -if (sourcePath.endsWith('/')) sourcePath.slice(0, -1); - -let isStrict = true; -if (("npm_config_strict" in process.env && !process.env.npm_config_strict) || - process.argv.includes("--strict=false")) { - isStrict = false; -} - -let expectedPeople = {}; - -function recordPostData(data) { - let peopleKeys = ["author", "speaker"]; - peopleKeys.forEach(function(key) { - let value = data[key]; - if (typeof value === 'string') { - expectedPeople[value] = true; - } else if (Array.isArray(value)) { - value.forEach(function(item) { - if (typeof item === 'string') { - expectedPeople[item] = true; - } - }); - } - }); -} - -function processFiles(path) { - const dir = fs.opendirSync(path); - let dirent; - while ((dirent = dir.readSync()) !== null) { - const subpath = path + '/' + dirent.name; - if (dirent.isFile()) { - const filedata = fs.readFileSync(subpath); - const info = graymatter(filedata); - - // ignore files not in Jekyll format - if (Object.keys(info.data).length > 0) { - recordPostData(info.data); - } - } else if (dirent.isDirectory()) { - processFiles(subpath); - } - } - dir.closeSync(); -} - -function validatePeopleBasedOnPosts() { - let peopleList = Object.keys(expectedPeople).sort(); - peopleList.forEach(function(name) { - let slug = name.replaceAll(" ", "-").replaceAll(".", "").toLowerCase().normalize("NFD").replace(/\p{Diacritic}/gu, ""); - let path = sourcePath + '/_people/' + slug + '.md'; - if (!fs.existsSync(path)) { - // ignore groups - if (!name.match(/(Team|Committee|Organization|Staff|Board|Community|OpenStreetMap)/gi)) { - if (shouldFix) { - let newFileString = `---\ntitle: "${name}"\n---`; - fs.writeFileSync(path, newFileString); - console.log(`Created file for ${name} at ${path}`); - } else { - console.error(`Missing file for ${name} at ${path}`); - hasUnfixedIssue = true; - } - } - } else { - let personData = graymatter(fs.readFileSync(path)).data; - // the document title needs to match the name listed in the post meta or else Jekyll can't link them - if (personData.title !== name) { - console.error(`Unexpected name "${personData.title}" for ${name} at ${path}`); - hasUnfixedIssue = true; - } - } - }); -} - -processFiles(sourcePath + '/_posts'); -validatePeopleBasedOnPosts(); - -if (hasUnfixedIssue && isStrict) { - // nonzero exit for GitHub Actions - process.exit(1); -} \ No newline at end of file diff --git a/_tools/thumbnail-generator/index.js b/_tools/thumbnail-generator/index.js deleted file mode 100644 index c5b5c31..0000000 --- a/_tools/thumbnail-generator/index.js +++ /dev/null @@ -1,68 +0,0 @@ -// thumbnail-generator for dogwood -// -// This script creates thumbnail versions of images that are displayed -// at small sizes on some pages in order to reduce load times. -// It is hardcoded for special directories (it works recursively): -// /img/people/ – avatar images for people -// /img/posts/ – header images for posts -// And it saves the output to: -// /img-thumbnails/people/ -// /img-thumbnails/posts/ -// In your Jekyll documents you should specify images like -// "image: /img/posts/john.jpg" And the theme will automatically -// output "/img-thumbnails/posts/john.jpg" in places where smaller -// images are appropriate. -// -// Note that if you specify images in the special directories -// but do not run this script before building your site then -// your images will 404. - -import fs from 'fs'; -import sharp from 'sharp'; - -import process from 'process'; -import minimist from 'minimist'; -const argv = minimist(process.argv.slice(2)); -let sourcePath = process.env.npm_config_srcdir || argv.srcdir || '.'; -if (sourcePath.endsWith('/')) sourcePath.slice(0, -1); - -var imgDir = sourcePath + '/img/'; -var imgThumbDir = sourcePath + '/img-thumbnails/'; - -if (!fs.existsSync(imgThumbDir)) fs.mkdirSync(imgThumbDir); - -processFiles('posts', 720, null); -processFiles('people', 48, 48); - -function processFiles(subdir, width, height) { - let inDir = imgDir + subdir; - let outDir = imgThumbDir + subdir; - - if (!fs.existsSync(outDir)) fs.mkdirSync(outDir); - - const dir = fs.opendirSync(inDir); - let dirent; - while ((dirent = dir.readSync()) !== null) { - - //ignore hidden files - if (dirent.name[0] === '.') continue; - - if (dirent.isFile()) { - const subpath = inDir + '/' + dirent.name; - let outPath = outDir + '/' + dirent.name + '.webp'; - const buffer = fs.readFileSync(subpath); - - sharp(buffer, { animated: true, limitInputPixels: false }) - .resize(width, height, { withoutEnlargement: true }) - .toFile(outPath) - .catch(err => { - console.log("cannot create thumbnail for: " + subpath); - console.error(err); - }); - - } else if (dirent.isDirectory()) { - processFiles(subdir + '/' + dirent.name, width, height); - } - } - dir.closeSync(); -} diff --git a/assets/avatar.jpg b/assets/avatar.jpg deleted file mode 100644 index e7b4fe4..0000000 Binary files a/assets/avatar.jpg and /dev/null differ diff --git a/assets/style.scss b/assets/style.scss deleted file mode 100644 index d3fd0ef..0000000 --- a/assets/style.scss +++ /dev/null @@ -1,5 +0,0 @@ ---- ---- -$baseurl: "{{site.url}}{{site.baseurl}}"; - -@import "dogwood/initialize"; \ No newline at end of file diff --git a/dogwood b/dogwood new file mode 160000 index 0000000..6b90193 --- /dev/null +++ b/dogwood @@ -0,0 +1 @@ +Subproject commit 6b90193942f448bf92a9dd83c60ece0cb4f4c205 diff --git a/dogwood.gemspec b/dogwood.gemspec deleted file mode 100644 index 7814252..0000000 --- a/dogwood.gemspec +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true - -Gem::Specification.new do |spec| - spec.name = "osmus-dogwood" - spec.version = "0.1.0" - spec.authors = ["Quincy Morgan"] - spec.email = ["2046746+quincylvania@users.noreply.github.com"] - - spec.summary = "The Jekyll theme powering openstreetmap.us" - spec.homepage = "https://github.com/osmus/dogwood" - spec.license = "MIT" - - spec.files = `git ls-files -z`.split("\x0").select do|f| - f.match(%r!^((assets|_includes|_plugins|_layouts|_sass)/|_config.yml|index.html|(LICENSE|README)((\.(txt|md|markdown)|$)))!i) - end - - spec.add_runtime_dependency "jekyll", "~> 4.3" - - spec.add_runtime_dependency "jekyll-archives", "~> 2.2.1" - spec.add_runtime_dependency 'jekyll-include-cache', "~> 0.2.1" - - spec.add_runtime_dependency "absolute-urls" - spec.add_runtime_dependency "post-aliases" - spec.add_runtime_dependency "unwrap-img" -end