![]() |
#1 |
Junior Member
![]() Posts: 3
Karma: 10
Join Date: Aug 2025
Device: Generic
|
Word Lookup tool modification/improvement.
Hi,
I need help with the word lookup tool, especially when using Google dictionary, as alignment is off, reducing the column-gap to 0px greatly elevates the experience, you can enhance it a bit further by setting grid-template-columns: minmax (0px,0px). The improvement is illustrated in the screenshot. You can try this by clicking "inspect" on the Google dictionary page and going to the "computed styles" tab. Can this be achieved via a plugin to inject javascript? Can anyone help me create one? Last edited by BetterRed; Yesterday at 06:29 PM. |
![]() |
![]() |
![]() |
#2 |
Junior Member
![]() Posts: 3
Karma: 10
Join Date: Aug 2025
Device: Generic
|
Solution.
I'm not able to edit my original post so I'll be posting it here. Credits: ChatGPT
There are two ways, both includes editing lookup.js (located at calibre/app/resource/lookup.js or usr/share/calibre/lookup.js in linux) Option 1. This is the one I use but might break in the future, please replace the entire code of lookup.js with this one. Code:
/* vim:fileencoding=utf-8 * * Copyright (C) 2019 Kovid Goyal <kovid at kovidgoyal.net> * * Distributed under terms of the GPLv3 license */ (function() { "use strict"; var num_tries = 0; // apply the 3px indent to any level-1 define heading function indentHeadings() { document.querySelectorAll('span[role="heading"][aria-level="1"]') .forEach(function(el) { el.style.position = 'relative'; el.style.left = '3px'; }); } function fix_google_markup() { var cc = document.getElementById('center_col'); if (!cc) { if (++num_tries > 10) return; setTimeout(fix_google_markup, 100); return; } // zero-out column gaps everywhere var style = document.createElement('style'); style.textContent = ` * { column-gap: 0px !important; -webkit-column-gap: 0px !important; } `; document.head.appendChild(style); var max_width = 'calc(100vw - 25px)'; cc.style.maxWidth = max_width; cc.style.marginLeft = '0'; var rcnt = document.getElementById('rcnt'); if (rcnt) rcnt.style.marginLeft = '0'; var cnt = document.getElementById('cnt'); if (cnt) cnt.style.paddingTop = '0'; var s = document.getElementById('search'); if (s) s.style.maxWidth = max_width; var params = new URLSearchParams(location.search.slice(1)); var q = params.get('q'); if (q && q.startsWith('define:')) { // inline layout tweaks for define: results cc.style.position = 'absolute'; cc.style.top = '0'; cc.style.left = '0'; cc.style.paddingLeft = '0'; cc.style.paddingRight = '6px'; ['sfcnt','top_nav','before-appbar','appbar', 'searchform','easter-egg','topstuff'] .forEach(function(id) { var e = document.getElementById(id); if (e) e.style.display = 'none'; }); // wrap definition text document.querySelectorAll('[data-topic]') .forEach(e => e.style.maxWidth = max_width); // now that the define: block is up, indent headings indentHeadings(); // observe any future DOM changes in center_col and re-indent new MutationObserver(indentHeadings) .observe(cc, { childList: true, subtree: true }); } // remove the promo sidebar if present var promo = document.getElementById('promos'); if (promo) promo.remove(); // wrap search results document.querySelectorAll('[data-ved]') .forEach(e => e.style.maxWidth = max_width); // prevent overlap of search results + citations document.querySelectorAll('cite').forEach(function(elem) { var wrapper = elem.closest('div'); if (wrapper) wrapper.style.position = 'static'; }); } if (location.hostname === 'www.google.com') { window.addEventListener('DOMContentLoaded', fix_google_markup); } })(); Code:
var cc = document.getElementById('center_col'); // --- paste this code below the above line, ctrl+f in your fav text editor to find the line --- var style = document.createElement('style'); style.textContent = ` * { column-gap: 0px !important; -webkit-column-gap: 3px !important; } `; document.head.appendChild(style); // --- and the between the below line, you can leave this comment if you'd like --- var max_width = 'calc(100vw - 25px)'; Last edited by BetterRed; Yesterday at 06:32 PM. |
![]() |
![]() |
Advert | |
|
![]() |
#3 |
null operator (he/him)
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 21,767
Karma: 30237628
Join Date: Mar 2012
Location: Sydney Australia
Device: none
|
Moderator Notice
I moved this to the Development Forum. I don't think the Viewer has plugin support… yet. And I uploaded the images to here; use the paper clip icon to upload attachments BR Last edited by BetterRed; Yesterday at 06:34 PM. |
![]() |
![]() |
![]() |
#4 |
Junior Member
![]() Posts: 3
Karma: 10
Join Date: Aug 2025
Device: Generic
|
![]()
Update: Fixes rendering issues with non-dictionary results. Tested on 8.7.0. {Mods: is it possible to delete the above post with code? I'll be including all the screenshots in this post.}
Code:
/* vim:fileencoding=utf-8 * * Copyright (C) 2019 Kovid Goyal <kovid at kovidgoyal.net> * * Distributed under terms of the GPLv3 license */ (function() { "use strict"; var num_tries = 0; var styleAdded = false; // Track if we've added our CSS styles function fix_google_markup() { var cc = document.getElementById('center_col'); if (!cc) { if (++num_tries <= 10) { return setTimeout(fix_google_markup, 100); } return; } // figure out if they actually got a dictionary card var isDict = !!document.querySelector('.lr_container, .lr_dct_ent'); // grab the raw query var params = new URLSearchParams(location.search.slice(1)); var q = params.get('q') || ''; // 1) DICTIONARY MODE if (isDict) { // Only add styles once to prevent duplication if (!styleAdded) { var style = document.createElement('style'); style.textContent = ` * { column-gap: 0!important; -webkit-column-gap: 0!important; } #center_col { position: absolute !important; top: 1px !important; /* Using your preferred 1px value */ left: 0 !important; z-index: 100; } #cnt { position: relative; min-height: 100vh; } /* Clear the space where search form was */ #searchform, #appbar, #before-appbar { display: none !important; } `; document.head.appendChild(style); styleAdded = true; } var maxW = 'calc(100vw - 25px)'; cc.style.maxWidth = maxW; cc.style.marginLeft = '0'; ['rcnt','cnt','search'] .forEach(function(id) { var e = document.getElementById(id); if (e) { if (id==='search') e.style.maxWidth = maxW; else if (id==='cnt') e.style.paddingTop = '0'; else e.style.marginLeft = '0'; } }); cc.style.paddingLeft = '0'; cc.style.paddingRight = '6px'; // hide everything but the dictionary ['sfcnt','top_nav','easter-egg','topstuff'] .forEach(function(id){ var e = document.getElementById(id); if (e) e.style.display = 'none'; }); // Special handling for searchform area ['searchform', 'appbar', 'before-appbar'].forEach(function(id) { var e = document.getElementById(id); if (e) e.style.display = 'none'; }); // constrain define text document .querySelectorAll('[data-topic]') .forEach(e => e.style.maxWidth = maxW); // indent headings and watch for re-renders indentHeadings(); new MutationObserver(indentHeadings) .observe(cc, { childList:true, subtree:true }); // Ensure footer stays at bottom - with null check var cnt = document.getElementById('cnt'); if (cnt) cnt.style.minHeight = '100vh'; } // 2) Normal MODE (define: but no dict card) else if (q.startsWith('define:')) { // SAFER: Use try-catch for Normal mode operations try { ['sfcnt','top_nav','before-appbar','appbar', 'searchform','easter-egg','topstuff'] .forEach(function(id){ var e = document.getElementById(id); if (e) e.style.display = 'none'; }); } catch(e) { console.error("Error in Normal mode cleanup:", e); } } // 3) UNIVERSAL CLEAN-UP (with null checks) try { // remove that promo sidebar, wrap rest nicely var promo = document.getElementById('promos'); if (promo) promo.remove(); document .querySelectorAll('[data-ved]') .forEach(e => e.style.maxWidth = '100%'); document .querySelectorAll('cite') .forEach(c => { var wrap = c.closest('div'); if (wrap) wrap.style.position = 'static'; }); } catch(e) { console.error("Error in universal cleanup:", e); } } if (location.hostname === 'www.google.com') { window.addEventListener('DOMContentLoaded', fix_google_markup); // Re-run on resize to handle Google's dynamic layout changes window.addEventListener('resize', function() { // Reset try counter to handle DOM changes num_tries = 0; styleAdded = false; fix_google_markup(); }); } })(); |
![]() |
![]() |
![]() |
#5 |
creator of calibre
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 45,396
Karma: 27756918
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
|
|
![]() |
![]() |
Advert | |
|
![]() |
#6 |
Bibliophagist
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 46,522
Karma: 169115146
Join Date: Jul 2010
Location: Vancouver
Device: Kobo Sage, Libra Colour, Lenovo M8 FHD, Paperwhite 4, Tolino epos
|
For those who are not aware, Kovid's post means the code is now in calibre's master for those running from source and will be in the next release for those who are not.
|
![]() |
![]() |
![]() |
|
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
Dictionary lookup word-wrap | foosion | Viewer | 7 | 08-09-2021 12:07 AM |
Use external browser for lookup-word in Calibre-4.1 | 3n4n | Library Management | 1 | 10-26-2019 07:39 AM |
Can't select a particular word to highlight or lookup on NC | nookleus | Nook Color & Nook Tablet | 4 | 01-06-2011 10:47 AM |
Classic Noob Question on Word Lookup | boxer | Barnes & Noble NOOK | 4 | 07-31-2010 09:22 AM |
Lookup a word on the dictionary | Adamastorx | Sony Reader | 1 | 02-19-2009 03:57 PM |