~cadence/bibliogram

7461f25ca97bcb894e3fa5f54a010905ebb44f26 — Cadence Ember 18 days ago d211470
Use boring font for consistent non-latin script appearance based on page heuristics
M src/lang/ar.js => src/lang/ar.js +1 -0
@@ 5,6 5,7 @@ if (!constants.language_dev) Object.assign(data, require("./en.js"))

;(() => {
	data.meta_direction = "rtl"
	data.meta_use_boring_font = true

	data.go_to_profile = "اذهب إلى الملف الشخصي"
	data.go_to_post = "اذهب إلى المنشور"

M src/lang/bg.js => src/lang/bg.js +1 -0
@@ 5,6 5,7 @@ if (!constants.language_dev) Object.assign(data, require("./en.js"))

;(() => {
	data.meta_direction = "ltr"
	data.meta_use_boring_font = true

	data.go_to_profile = "Виж профил"
	data.go_to_post = "Виж публикация"

M src/lang/fa.js => src/lang/fa.js +1 -0
@@ 5,6 5,7 @@ if (!constants.language_dev) Object.assign(data, require("./en.js"))

;(() => {
	data.meta_direction = "rtl"
	data.meta_use_boring_font = true

	data.go_to_profile = "برو به نمایه"
	data.go_to_post = "برو به پست"

M src/lang/ru.js => src/lang/ru.js +1 -0
@@ 5,6 5,7 @@ if (!constants.language_dev) Object.assign(data, require("./en.js"))

;(() => {
	data.meta_direction = "ltr"
	data.meta_use_boring_font = true

	data.go_to_profile = "Перейти в профиль"
	data.go_to_post = "Перейти в публикацию"

M src/lang/uk.js => src/lang/uk.js +1 -0
@@ 5,6 5,7 @@ if (!constants.language_dev) Object.assign(data, require("./en.js"))

;(() => {
	data.meta_direction = "ltr"
	data.meta_use_boring_font = true

	data.go_to_profile = "Перейти до профілю"
	data.go_to_post = "Перейти до допису"

M src/lib/structures/BaseUser.js => src/lib/structures/BaseUser.js +6 -0
@@ 1,6 1,7 @@
const constants = require("../constants")
const {proxyProfilePic} = require("../utils/proxyurl")
const {structure} = require("../utils/structuretext")
const {isLatin} = require("../utils/islatin")

const rewriters = {
	rewrite_youtube: ["youtube.com", "www.youtube.com", "m.youtube.com", "youtu.be"],


@@ 52,6 53,11 @@ class BaseUser {
		return structure(this.data.biography)
	}

	bioIsLatin() {
		if (typeof this.data.biography !== "string") return true
		return isLatin(this.data.biography)
	}

	getTtl(scale = 1) {
		const expiresAt = this.cachedAt + constants.caching.resource_cache_time
		const ttl = expiresAt - Date.now()

M src/lib/structures/TimelineEntry.js => src/lib/structures/TimelineEntry.js +8 -0
@@ 5,6 5,7 @@ const collectors = require("../collectors")
const {structure, removeTrailingHashtags} = require("../utils/structuretext")
const TimelineBaseMethods = require("./TimelineBaseMethods")
const TimelineChild = require("./TimelineChild")
const {isLatin} = require("../utils/islatin")
require("../testimports")(collectors, TimelineChild, TimelineBaseMethods)

const rssDescriptionTemplate = compile(`


@@ 138,6 139,13 @@ class TimelineEntry extends TimelineBaseMethods {
		else return caption.split("\n")[0].split(". ")[0]
	}

	captionIsLatin() {
		// the caption introduction is likely to be more meaningful for analysis than the full caption.
		const introduction = this.getCaptionIntroduction()
		if (typeof introduction !== "string") return true
		return isLatin(introduction)
	}

	/**
	 * Alt text is not available for N2, the caption or a placeholder string will be returned instead.
	 * @override

A src/lib/utils/islatin.js => src/lib/utils/islatin.js +16 -0
@@ 0,0 1,16 @@
function isLatin(text) {
	// remove characters from the text that can be used in any script, such as numbers, basic punctuation, and emojis.
	// the emoji regular expression is from https://stackoverflow.com/a/45138005
	const textWithoutMultilingual = text.replace(/[ .,?!¿¡#@$&%\/0-9\u{1f300}-\u{1f5ff}\u{1f900}-\u{1f9ff}\u{1f600}-\u{1f64f}\u{1f680}-\u{1f6ff}\u{2600}-\u{26ff}\u{2700}-\u{27bf}\u{1f1e6}-\u{1f1ff}\u{1f191}-\u{1f251}\u{1f004}\u{1f0cf}\u{1f170}-\u{1f171}\u{1f17e}-\u{1f17f}\u{1f18e}\u{3030}\u{2b50}\u{2b55}\u{2934}-\u{2935}\u{2b05}-\u{2b07}\u{2b1b}-\u{2b1c}\u{3297}\u{3299}\u{303d}\u{00a9}\u{00ae}\u{2122}\u{23f3}\u{24c2}\u{23e9}-\u{23ef}\u{25b6}\u{23f8}-\u{23fa}-]/ug, "")

	// avoid dividing by zero
	if (textWithoutMultilingual.length == 0) return true

	// regular expression from https://stackoverflow.com/a/26900132 - it's close enough for these heuristics.
	const latinText = textWithoutMultilingual.replace(/[^A-Za-zÀ-ÿ]/g, "")

	// if it's at least 60% latin characters, consider it to be latin.
	return latinText.length > textWithoutMultilingual.length * 0.6
}

module.exports.isLatin = isLatin

M src/site/pug/home.pug => src/site/pug/home.pug +1 -1
@@ 7,7 7,7 @@ html(lang=settings.language)
	head
		title Bibliogram
		include includes/head
	body.homepage
	body.homepage(class={"use-boring-font": ll.meta_use_boring_font})
		header
			h1.banner
				img.banner-image(src="/static/img/banner-min.svg" alt="Bibliogram")

M src/site/pug/post.pug => src/site/pug/post.pug +1 -1
@@ 46,6 46,6 @@ html
			meta(property="og:image:alt" content=firstEntry.getAlt())
		meta(property="og:site_name" content="Bibliogram")

	body.post-page
	body.post-page(class={"use-boring-font": !post.captionIsLatin()})
		main
			+post(post, false)

M src/site/pug/settings.pug => src/site/pug/settings.pug +1 -1
@@ 36,7 36,7 @@ html(dir=ll.meta_direction, lang=settings.language)
		title= `${ll.t_settings} | Bibliogram`
		include includes/head
		script(src=getStaticURL("html", "/static/js/settings_message.js") type="module")
	body.settings-page
	body.settings-page(class={"use-boring-font": ll.meta_use_boring_font})
		if status && message
			.status-notice(class=status)= message
		main.settings

M src/site/pug/user.pug => src/site/pug/user.pug +1 -1
@@ 37,7 37,7 @@ html
		meta(property="og:image:type" content="image/jpeg")
		meta(property="og:site_name" content="Bibliogram")

	body
	body(class={"use-boring-font": !user.bioIsLatin()})
		nav(class=(settings.display_top_nav ? "always-displayed" : "")).top-nav
			//- Alt text guidelines from https://axesslab.com/alt-texts/
			a(href="/").nav-icon-link

M src/site/sass/includes/_main.sass => src/site/sass/includes/_main.sass +4 -2
@@ 11,8 11,10 @@ $theme: () !default
body
	font-family: "Bariol", sans-serif

[lang="uk"] body // consistent cyrillic
	font-family: "Cantarell", sans-serif
body.use-boring-font
	// this is useful so that cyrillic and other scripts don't look conspicuous compared to nearby latin letters.
	// the use-boring-font class is activated based on the page and heuristics of its contents
	font-family: sans-serif

input, button, textarea
	font-family: inherit