UP | HOME |

Remarcar de forma automática palabras en un pdf (con R y LaTeX)

2025-12-07

Remarcar de forma automática palabras en un pdf (con R y LaTeX)

Normalmente recibo documentos en pdf para revisar y suelo subrayar los verbos comodín. Resulta tan tedioso y aburrido que he decidido automatizarlo.

pp01_recuadros-1.png

Primero, me aseguro de que el tamaño del documento se ajuste a din A4. Posteriormente obtengo los bounding box de las palabras, reviso las más repetidas, y genero un fichero tex donde incluyo la página original junto con el rectángulo de las palabras que he considerado problemáticas.

library(data.table,quietly=TRUE);setDTthreads(0L);
library(pdftools)

ficheropdf <- "yourfile.pdf"

## ============================================================
## Comprobamos que es din A4
## ============================================================
A4_HEIGHT_PT <- 841.890
A4_WIDTH_PT <- 595.276
pagesizedata <- as.data.table(pdf_pagesize(ficheropdf))
w <- pagesizedata[,mean(right)]
h <- pagesizedata[,mean(bottom)]
if( w < floor(A4_WIDTH_PT) || h < floor(A4_HEIGHT_PT) ){
    cat("Las dimensiones medias de la página son ", w, " x ", h,". Para cambiar a din A4 emplea la siguiente instrucción:\n\n")
    texto <- paste0("gs -sDEVICE=pdfwrite -sPAPERSIZE=a4 -dFIXEDMEDIA -dPDFFitPage -o ",tools::file_path_sans_ext(basename(ficheropdf)),"_a4.pdf -f ", ficheropdf)
    cat(texto,"\n\n")
    stop("Fin")
}


## ============================================================
## Palabras con su bounding box
## ============================================================
data <- pdf_data(ficheropdf,font_info = FALSE)
datos <- lapply(1:length(data),function(i){
    dat <- data[[i]]
    dat$page=i
    x <- pagesizedata[i,height]
    dat$hpage  <- x
    x <- pagesizedata[i,width]
    dat$wpage <- x
    dat$posx <- dat$x
    dat$posy <- dat$hpage - (dat$y ) - dat$height
    as.data.table(dat)
})
datos <- rbindlist(datos)
datos[,data:= paste0(width,"/",height,"/",posx,"/",posy)]
datos

## ============================================================
## Palabras comunes
## ============================================================
stopwords <- c("de", ".", "en", "la", "el", "y", "los", "del", "%", "que", 
               "o", "a", "se", "las", "con", "un", "al", "por")
aa <- datos[!text  %in% stopwords,table(text)]
head(sort(aa,decreasing=TRUE),100)

palabrasrepetidas <- c("es","son")

datospalabras <- datos[text  %in% palabrasrepetidas]
datospalabras[,.N,by=page][order(N)]


ficherotex <- paste0(tools::file_path_sans_ext(basename(ficheropdf)),"_recuadros.tex")
texto <- "
\\documentclass[a4paper]{article}
\\usepackage{graphicx}
\\usepackage[margin=0pt]{geometry} % A4: 595.28 x 841.89 pt
\\usepackage{tikz}

\\newcommand{\\paginapdf}[2] % Compilar dos veces
{\\begin{tikzpicture}[remember picture,overlay,inner sep=0pt]%
\\node [anchor=east] at (current page.east)
{{\\includegraphics[page=#2]{#1}}};%
\\end{tikzpicture}}

\\pagestyle{empty}
\\begin{document} %Compilar dos veces

"
cat(texto,file=ficherotex,append=FALSE)

for(pagina in 1:(datos[,max(page)])){
    tablita <- datospalabras[page == pagina]
    texto <- paste0("\\paginapdf{",ficheropdf,"}{",pagina,"}%")
    if(nrow(tablita)){
        texto <- paste0(texto,"
\\begin{tikzpicture}[overlay, remember picture]
        \\def\\WordData{
")
        texto <- paste0(texto, paste(tablita[,data],collapse=",\n") )
        texto <- paste0(texto,"
    }
         \\foreach \\w/\\h/\\x/\\y in \\WordData {
                   \\coordinate (P) at ([xshift=\\x pt, yshift=\\y pt]current page.south west);
                   \\draw [red,thick] (P) rectangle ++(\\w pt, \\h pt);
     }
\\end{tikzpicture}
"
)}
    texto <- paste0(texto,"\n\\newpage\n\n")
    cat(texto,file=ficherotex,append=TRUE)
}
texto <- "\\end{document}"
cat(texto,file=ficherotex,append=TRUE)

tools::texi2pdf(ficherotex,clean=FALSE,index=FALSE)
tools::texi2pdf(ficherotex,clean=TRUE,index=FALSE)
cat("Compilado", ficherotex,"\n")