Files
Crosspoint/lib/I18n/translations/spanish.yaml
T
Vincent Politzer 4e5e2fe40a feat: focus reading (#1670)
## Summary

This PR introduces **Focus Reading**, a generic implementation of
artificial fixation points (similar to Bionic Reading) designed to
improve reading speed and focus by bolding the initial characters of
words. This is achieved by dynamically bolding characters during
indexing.

<img width="500" alt="Focus Reading on X3"
src="https://github.com/user-attachments/assets/94a632a5-82da-47be-957c-538b35bf84d9"
/>

### Implementation Details
#### Core Text Engine (`ParsedText`)
- Modified `ParsedText::addWord` to implement a custom bolding
algorithm. It uses a 45% ratio for bolding, with a minimum of 1
character and a maximum of 9.
- UTF-8 Safety: Integrated `utf8NextCodepoint` to ensure character
counting and string slicing occur at safe byte boundaries, preventing
corruption of multi-byte characters (e.g., accented letters or smart
quotes).
- Intelligent Tokenization: This correctly identifies and separates
"word" characters (letters, apostrophes, hyphens) from "non-word"
characters (numbers, brackets, smart quotes).
- Formatting Preservation: The logic ensures that punctuation is not
"stolen" for the bolding count and that existing styles (like italics or
underlines) are preserved across the bold/regular split.
- Processing at indexing stage reduces CPU load at render-time and
ensures layout/fit is unaffected.
- Split details are tracked with `wordIsFocusSuffix`. After splitting
and layout, suffixes are merged back into their preceding word entries
to prevent a doubling of RAM usage.

#### Settings and UI
- Version Management: Bumped `SECTION_FILE_VERSION` to `21`
- Global Settings: Added `focusReadingEnabled` to `CrossPointSettings`.
- User Interface: Added a new toggle in the "Reader" section of the
settings menu, positioned after the "Embedded Style" option.
- Localization: Added the `STR_FOCUS_READING` string

#### Plumbing
- Plumbed the `focusReadingEnabled` boolean through
`EpubReaderActivity`, `Section`, and `ChapterHtmlSlimParser` to ensure
the user's setting reaches the `ParsedText` constructor during chapter
indexing.

## Additional Context

### Files Changed
- `lib/Epub/Epub/ParsedText.h / .cpp`: Core fixation logic and UTF-8
tokenization.
- `lib/Epub/Epub/Section.h / .cpp`: Cache header updates and
invalidation logic.
- `lib/Epub/Epub/parsers/ChapterHtmlSlimParser.h / .cpp`: Plumbing the
setting to text blocks.
- `src/CrossPointSettings.h`: Data persistence for the new setting.
- `src/SettingsList.h`: UI toggle implementation.
- `src/activities/reader/EpubReaderActivity.cpp`: Handling settings
changes during reading sessions.
- `lib/I18n/translations/*.yaml`: UI strings.

---

### AI Usage

While CrossPoint doesn't have restrictions on AI tools in contributing,
please be transparent about their usage as it
helps set the right context for reviewers.

Did you use AI tools to help write this code? _**YES**_
2026-05-10 20:02:14 +02:00

300 lines
11 KiB
YAML

_language_name: "Español"
_language_code: "ES"
_order: "1"
STR_CROSSPOINT: "CrossPoint"
STR_BOOTING: "Iniciando..."
STR_SLEEPING: "Suspendido"
STR_ENTERING_SLEEP: "Entrando en suspensión"
STR_BROWSE_FILES: "Explorador de archivos"
STR_FILE_TRANSFER: "Transferir archivos"
STR_SETTINGS_TITLE: "Ajustes"
STR_CONTINUE_READING: "Continuar leyendo"
STR_NO_OPEN_BOOK: "No hay libros abiertos"
STR_START_READING: "Comenzar a leer"
STR_NO_FILES_FOUND: "No se encontraron archivos"
STR_SELECT_CHAPTER: "Seleccionar capítulo"
STR_NO_CHAPTERS: "Sin capítulos"
STR_END_OF_BOOK: "Fin del libro"
STR_EMPTY_CHAPTER: "Capítulo vacío"
STR_INDEXING: "Indexando"
STR_MEMORY_ERROR: "Error de memoria"
STR_PAGE_LOAD_ERROR: "Error al cargar la página"
STR_EMPTY_FILE: "Archivo vacío"
STR_OUT_OF_BOUNDS: "Fuera de rango"
STR_LOADING: "Cargando..."
STR_LOADING_POPUP: "Cargando"
STR_WIFI_NETWORKS: "Redes Wi-Fi"
STR_NO_NETWORKS: "No hay redes disponibles"
STR_NETWORKS_FOUND: "%zu redes encontradas"
STR_SCANNING: "Buscando..."
STR_CONNECTING: "Conectando..."
STR_CONNECTED: "¡Conectado!"
STR_CONNECTION_FAILED: "Error de conexión"
STR_FORGET_NETWORK: "¿Olvidar la red?"
STR_SAVE_PASSWORD: "¿Guardar contraseña?"
STR_PRESS_OK_SCAN: "Pulse OK para buscar de nuevo"
STR_JOIN_NETWORK: "Unirse a una red"
STR_CREATE_HOTSPOT: "Crear punto de acceso"
STR_JOIN_DESC: "Conectarse a una red Wi-Fi existente"
STR_HOTSPOT_DESC: "Conectarse a este dispositivo"
STR_STARTING_HOTSPOT: "Iniciando punto de acceso..."
STR_HOTSPOT_MODE: "Modo punto de acceso"
STR_CONNECT_WIFI_HINT: "Conecte su dispositivo a esta red Wi-Fi"
STR_OPEN_URL_HINT: "Abra esta dirección en su navegador"
STR_OR_HTTP_PREFIX: "o http://"
STR_SCAN_QR_HINT: "o escanee el código QR con su móvil:"
STR_CALIBRE_WIRELESS: "Calibre inalámbrico"
STR_CALIBRE_WEB_URL: "OPDS URL"
STR_NETWORK_LEGEND: "* (Cifrado) | + (Guardado)"
STR_MAC_ADDRESS: "MAC Address:"
STR_CHECKING_WIFI: "Verificando Wi-Fi..."
STR_ENTER_WIFI_PASSWORD: "Introduzca la contraseña del Wi-Fi"
STR_TO_PREFIX: "a "
STR_CALIBRE_RECEIVING: "Recibiendo: "
STR_CALIBRE_RECEIVED: "Recibido: "
STR_CALIBRE_INSTRUCTION_1: "1) Instale el complemento CrossPoint Reader"
STR_CALIBRE_INSTRUCTION_2: "2) Conéctese a la misma red Wi-Fi"
STR_CALIBRE_INSTRUCTION_3: "3) Desde Calibre, seleccione \"Enviar a dispositivo\""
STR_CALIBRE_INSTRUCTION_4: "\"Permanezca en esta pantalla mientras se envía\""
STR_CAT_DISPLAY: "Pantalla"
STR_CAT_READER: "Lector"
STR_CAT_CONTROLS: "Controles"
STR_CAT_SYSTEM: "Sistema"
STR_SLEEP_SCREEN: "Pantalla de suspensión"
STR_SLEEP_COVER_MODE: "Modo de pantalla de suspensión"
STR_HIDE_BATTERY: "Ocultar % de batería"
STR_EXTRA_SPACING: "Espaciado entre párrafos"
STR_TEXT_AA: "Suavizado de texto"
STR_IMAGES: "Imágenes"
STR_IMAGES_DISPLAY: "Mostrar"
STR_IMAGES_PLACEHOLDER: "Reemplazar"
STR_IMAGES_SUPPRESS: "Ocultar"
STR_SHORT_PWR_BTN: "Toque corto botón encendido"
STR_ORIENTATION: "Orientación"
STR_SIDE_BTN_LAYOUT: "Función botones laterales (lector)"
STR_LONG_PRESS_BEHAVIOR: "Comportamiento al mantener pulsado el botón"
STR_LONG_PRESS_BEHAVIOR_OFF: "Desactivado"
STR_LONG_PRESS_BEHAVIOR_SKIP: "Saltar capítulo"
STR_LONG_PRESS_BEHAVIOR_ORIENTATION: "Cambio de orientación"
STR_FONT_FAMILY: "Tipografía"
STR_FONT_SIZE: "Tamaño"
STR_LINE_SPACING: "Interlineado"
STR_SCREEN_MARGIN: "Margen de lectura"
STR_PARA_ALIGNMENT: "Ajuste de párrafo"
STR_HYPHENATION: "División de palabras"
STR_TIME_TO_SLEEP: "Auto suspensión"
STR_SHOW_HIDDEN_FILES: "Mostrar archivos ocultos"
STR_REFRESH_FREQ: "Frecuencia de refresco"
STR_KOREADER_SYNC: "Sincronización de KOReader"
STR_CHECK_UPDATES: "Verificar actualizaciones"
STR_LANGUAGE: "Idioma"
STR_CLEAR_READING_CACHE: "Borrar caché de lectura"
STR_USERNAME: "Usuario"
STR_PASSWORD: "Contraseña"
STR_SYNC_SERVER_URL: "URL del servidor de sinc."
STR_DOCUMENT_MATCHING: "Coincidencia de doc."
STR_AUTHENTICATE: "Autenticar"
STR_KOREADER_USERNAME: "Usuario de KOReader"
STR_KOREADER_PASSWORD: "Contraseña de KOReader"
STR_FILENAME: "Nombre de archivo"
STR_BINARY: "Binario"
STR_SET_CREDENTIALS_FIRST: "Configurar credenciales"
STR_WIFI_CONN_FAILED: "Fallo de conexión Wi-Fi"
STR_AUTHENTICATING: "Autenticando..."
STR_AUTH_SUCCESS: "¡Autenticación exitosa!"
STR_KOREADER_AUTH: "Autenticación KOReader"
STR_SYNC_READY: "La sincronización de KOReader está lista para usarse"
STR_AUTH_FAILED: "Error de autenticación"
STR_DONE: "Hecho"
STR_CLEAR_CACHE_WARNING_1: "Esto borrará todos los datos del libro en caché."
STR_CLEAR_CACHE_WARNING_2: "¡Se perderá todo el progreso de lectura!"
STR_CLEAR_CACHE_WARNING_3: "Los libros deberán ser reindexados"
STR_CLEAR_CACHE_WARNING_4: "cuando se vuelvan a abrir."
STR_CLEARING_CACHE: "Borrando caché..."
STR_CACHE_CLEARED: "Caché borrada"
STR_ITEMS_REMOVED: "elementos eliminados"
STR_FAILED_LOWER: "falló"
STR_CLEAR_CACHE_FAILED: "No se pudo borrar la caché"
STR_CHECK_SERIAL_OUTPUT: "Consulte los registros del puerto serie"
STR_DARK: "Oscuro"
STR_LIGHT: "Claro"
STR_CUSTOM: "Personalizado"
STR_COVER: "Portada"
STR_NONE_OPT: "Ninguno"
STR_FIT: "Ajustar"
STR_CROP: "Recortar"
STR_NEVER: "Nunca"
STR_IN_READER: "En el lector"
STR_ALWAYS: "Siempre"
STR_IGNORE: "Ignorar"
STR_SLEEP: "Suspender"
STR_PAGE_TURN: "Pasar página"
STR_PORTRAIT: "Vertical"
STR_LANDSCAPE_CW: "Horizontal (horario)"
STR_INVERTED: "Invertido"
STR_LANDSCAPE_CCW: "Horizontal (antihorario)"
STR_PREV_NEXT: "Ant./Sig."
STR_NEXT_PREV: "Sig./Ant."
STR_NOTO_SERIF: "Noto Serif"
STR_NOTO_SANS: "Noto Sans"
STR_OPEN_DYSLEXIC: "Open Dyslexic"
STR_SMALL: "Pequeño"
STR_MEDIUM: "Mediano"
STR_LARGE: "Grande"
STR_X_LARGE: "Extra grande"
STR_TIGHT: "Estrecho"
STR_NORMAL: "Normal"
STR_WIDE: "Amplio"
STR_JUSTIFY: "Justificado"
STR_ALIGN_LEFT: "Izquierda"
STR_CENTER: "Centro"
STR_ALIGN_RIGHT: "Derecha"
STR_MIN_1: "1 min."
STR_MIN_5: "5 min."
STR_MIN_10: "10 min."
STR_MIN_15: "15 min."
STR_MIN_30: "30 min."
STR_PAGES_1: "1 pág."
STR_PAGES_5: "5 pág."
STR_PAGES_10: "10 pág."
STR_PAGES_15: "15 pág."
STR_PAGES_30: "30 pág."
STR_UPDATE: "Actualizar"
STR_CHECKING_UPDATE: "Verificando actualización..."
STR_NEW_UPDATE: "¡Nueva actualización disponible!"
STR_CURRENT_VERSION: "Versión actual:"
STR_NEW_VERSION: "Nueva versión:"
STR_UPDATING: "Actualizando..."
STR_NO_UPDATE: "No hay actualizaciones disponibles"
STR_UPDATE_FAILED: "Fallo de actualización"
STR_UPDATE_COMPLETE: "Actualización completada"
STR_POWER_ON_HINT: "Reinicie manteniendo pulsado botón de encendido"
STR_NO_ENTRIES: "No se encontraron elementos"
STR_DOWNLOADING: "Descargando..."
STR_DOWNLOAD_FAILED: "Fallo de descarga"
STR_ERROR_MSG: "Error:"
STR_UNNAMED: "Sin nombre"
STR_NO_SERVER_URL: "No se configuró URL de servidor"
STR_FETCH_FEED_FAILED: "Fallo al obtener el feed"
STR_PARSE_FEED_FAILED: "Fallo al procesar el feed"
STR_NETWORK_PREFIX: "Red: "
STR_IP_ADDRESS_PREFIX: "IP: "
STR_ERROR_GENERAL_FAILURE: "Error: Fallo general"
STR_ERROR_NETWORK_NOT_FOUND: "Error: Red no encontrada"
STR_ERROR_CONNECTION_TIMEOUT: "Error: Tiempo de conexión agotado"
STR_SD_CARD: "Tarjeta microSD"
STR_BACK: "« Atrás"
STR_EXIT: "« Salir"
STR_HOME: "« Inicio"
STR_SELECT: "Selecc."
STR_SELECTED: "Seleccionado"
STR_TOGGLE: "Cambiar"
STR_CONFIRM: "Confirmar"
STR_CANCEL: "Cancelar"
STR_CONNECT: "Conectar"
STR_OPEN: "Abrir"
STR_DOWNLOAD: "Descargar"
STR_RETRY: "Reintentar"
STR_YES: "Sí"
STR_NO: "No"
STR_SHOW: "Mostrar"
STR_HIDE: "Ocultar"
STR_STATE_ON: "Activado"
STR_STATE_OFF: "Desactivado"
STR_NOT_SET: "No configurado"
STR_DIR_LEFT: "Izq."
STR_DIR_RIGHT: "Dcha."
STR_DIR_UP: "Subir"
STR_DIR_DOWN: "Bajar"
STR_OK_BUTTON: "OK"
STR_SLEEP_COVER_FILTER: "Filtro de pantalla de suspensión"
STR_FILTER_CONTRAST: "Contraste"
STR_CUSTOMISE_STATUS_BAR: "Personalizar barra de estado"
STR_CHAPTER_PAGE_COUNT: "Contador de pág. por cap."
STR_BOOK_PROGRESS_PERCENTAGE: "Porcentaje progreso libro"
STR_PROGRESS_BAR: "Barra de progreso"
STR_PROGRESS_BAR_THICKNESS: "Grosor de barra de progreso"
STR_PROGRESS_BAR_THIN: "Fino"
STR_PROGRESS_BAR_MEDIUM: "Medio"
STR_PROGRESS_BAR_THICK: "Ancho"
STR_BOOK: "Libro"
STR_CHAPTER: "Capítulo"
STR_EXAMPLE_CHAPTER: "Capítulo 21"
STR_EXAMPLE_BOOK: "Título del libro"
STR_PREVIEW: "Previsualización"
STR_TITLE: "Título"
STR_BATTERY: "Batería"
STR_UI_THEME: "Interfaz"
STR_THEME_CLASSIC: "Clásico"
STR_THEME_LYRA: "Lyra"
STR_THEME_LYRA_EXTENDED: "Lyra Extendido"
STR_THEME_ROUNDEDRAFF: "RoundedRaff"
STR_SUNLIGHT_FADING_FIX: "Corrección de desvanecimiento"
STR_REMAP_FRONT_BUTTONS: "Reconfigurar botones frontales"
STR_OPDS_BROWSER: "Navegador OPDS"
STR_COVER_CUSTOM: "Portada + Pers."
STR_MENU_RECENT_BOOKS: "Libros recientes"
STR_NO_RECENT_BOOKS: "No hay libros recientes"
STR_CALIBRE_DESC: "Transferir contenido a este dispositivo"
STR_FORGET_AND_REMOVE: "¿Desea olvidar la red y la contraseña guardada?"
STR_FORGET_BUTTON: "Olvidar"
STR_CALIBRE_STARTING: "Iniciando Calibre..."
STR_CALIBRE_SETUP: "Configuración"
STR_CALIBRE_STATUS: "Estado"
STR_CLEAR_BUTTON: "Borrar"
STR_DEFAULT_VALUE: "Predeterminado"
STR_REMAP_PROMPT: "Pulse un botón frontal para cada función"
STR_UNASSIGNED: "Sin asignar"
STR_ALREADY_ASSIGNED: "Ya asignado"
STR_REMAP_RESET_HINT: "Botón lateral arriba: restablecer configuración"
STR_REMAP_CANCEL_HINT: "Botón lateral abajo: anular reconfiguración"
STR_HW_BACK_LABEL: "Atrás (primer botón)"
STR_HW_CONFIRM_LABEL: "Confirmar (segundo botón)"
STR_HW_LEFT_LABEL: "Izq. (tercer botón)"
STR_HW_RIGHT_LABEL: "Dcha. (cuarto botón)"
STR_GO_TO_PERCENT: "Ir a %"
STR_GO_HOME_BUTTON: "Volver al menú Inicio"
STR_SYNC_PROGRESS: "Sincronizar progreso de lectura"
STR_DELETE_CACHE: "Borrar caché del libro"
STR_DELETE: "Borrar"
STR_DISPLAY_QR: "Mostrar página como QR"
STR_CHAPTER_PREFIX: "Cap.: "
STR_PAGES_SEPARATOR: " pág. | "
STR_BOOK_PREFIX: "Libro: "
STR_CALIBRE_URL_HINT: "Para Calibre, agregue /opds a su URL"
STR_PERCENT_STEP_HINT: "Izq./Dcha.: 1% | Subir/Bajar: 10%"
STR_SYNCING_TIME: "Tiempo de sincronización..."
STR_CALC_HASH: "Calculando hash del documento..."
STR_HASH_FAILED: "No se pudo calcular el hash del documento"
STR_FETCH_PROGRESS: "Recuperando progreso remoto..."
STR_UPLOAD_PROGRESS: "Subiendo progreso..."
STR_NO_CREDENTIALS_MSG: "No se han configurado credenciales"
STR_KOREADER_SETUP_HINT: "Configure una cuenta de KOReader en la configuración"
STR_PROGRESS_FOUND: "¡Progreso encontrado!"
STR_REMOTE_LABEL: "Remoto:"
STR_LOCAL_LABEL: "Local:"
STR_PAGE_OVERALL_FORMAT: "Página %d, %.2f%% completado"
STR_PAGE_TOTAL_OVERALL_FORMAT: "Página %d / %d, %.2f%% completado"
STR_DEVICE_FROM_FORMAT: " De: %s"
STR_APPLY_REMOTE: "Aplicar progreso remoto"
STR_UPLOAD_LOCAL: "Subir progreso local"
STR_NO_REMOTE_MSG: "No se encontró progreso remoto"
STR_UPLOAD_PROMPT: "¿Subir posición actual?"
STR_UPLOAD_SUCCESS: "¡Progreso subido!"
STR_SYNC_FAILED_MSG: "Fallo de sincronización"
STR_SAVE_PROGRESS_FAILED: "No se pudo guardar el progreso"
STR_SECTION_PREFIX: "Secc.:"
STR_UPLOAD: "Subir"
STR_BOOK_S_STYLE: "Estilo del libro"
STR_EMBEDDED_STYLE: "Estilo integrado"
STR_FOCUS_READING: "Lectura enfocada"
STR_OPDS_SERVER_URL: "URL del servidor OPDS"
STR_FOOTNOTES: "Pie de página"
STR_NO_FOOTNOTES: "No hay notas al pie de esta página"
STR_LINK: "[enlace]"
STR_SCREENSHOT_BUTTON: "Tomar captura de pantalla"
STR_TILT_PAGE_TURN: "Pasar página inclinando"
STR_AUTO_TURN_ENABLED: "Avance activado: "
STR_AUTO_TURN_PAGES_PER_MIN: "Avance auto. (pág./min)"