0

I have a string with the names of a bunch of different ftext objects.

library("officer")
library("stringr")

itanor <- fp_text(font.size = 10, italic = T, font.family = "Open Sans")
normal <- fp_text(font.size = 10, font.family = "Open Sans")

h <- "Lorem ipsum _<dolor>_ sit amet, _<lorem>_ rutrum eget _<nec>_ hac placerat
proin. Eget _<facilisis>_ ut, varius."
h <- str_replace_all(h, "_(?=\\w)", "_<")
h <- str_replace_all(h, "(?<=\\w)_", ">_")
h <- str_split(h, "_")
> h
[[1]]
[1] "Lorem ipsum "               
[2] "<dolor>"                    
[3] " sit amet, "                
[4] "<lorem>"                    
[5] " rutrum eget "              
[6] "<nec>"                      
[7] " hac placerat\nproin. Eget "
[8] "<facilisis>"                
[9] " ut, varius."

Each one that starts with "<" is italic and the others regular text:

itit <- str_which(h[[1]], "<")
itnot <- str_which(h[[1]], "<", negate = TRUE)
g <- 1
repeat{
  semsinal <- gsub("<|>","", h[[c(1,itit[g])]])
  assign(paste0("juntar",itit[g]), (ftext(semsinal, itanor)))
  g <- g +1; if(g > length(itit)) {break}}
g <- 1
repeat{
  assign(paste0("juntar",itnot[g]), (ftext(h[[c(1,itnot[g])]], normal)))
  g <- g +1; if(g > length(itnot)) {break}}
gm <- length(grep("juntar",objects(), value = T))
join <- c(noquote(paste0("juntar",1:gm)))
> join
[1] juntar1 juntar2 juntar3 juntar4
[5] juntar5 juntar6 juntar7 juntar8
[9] juntar9

Then I need to make a single paragraph with "fpar" function using "join" object, because I'll never know how many "juntar" objects I'll have.

I've already tried mget, but it doesn't work.

The expected result is this:

> head(fpar(juntar1,juntar2, juntar3, juntar4, juntar5, juntar6, juntar7, juntar8, juntar9))
$chunks
$chunks[[1]]
text: Lorem ipsum 
format:
  size italic  bold underlined color
1   10  FALSE FALSE      FALSE black
      shading  fontname fontname_cs
1 transparent Open Sans   Open Sans
  fontname_eastasia fontname.hansi
1         Open Sans      Open Sans
  vertical_align
1       baseline

$chunks[[2]]
text: dolor
format:
  size italic  bold underlined color
1   10   TRUE FALSE      FALSE black
      shading  fontname fontname_cs
1 transparent Open Sans   Open Sans
  fontname_eastasia fontname.hansi
1         Open Sans      Open Sans
  vertical_align
1       baseline
...

but I get instead:

> fpar(mget(join[1:9]))
$chunks
$chunks[[1]]
$chunks[[1]]$juntar1
text: Lorem ipsum 
format:
  size italic  bold underlined color
1   10  FALSE FALSE      FALSE black
      shading  fontname fontname_cs
1 transparent Open Sans   Open Sans
  fontname_eastasia fontname.hansi
1         Open Sans      Open Sans
  vertical_align
1       baseline

$chunks[[1]]$juntar2
text: dolor
format:
  size italic  bold underlined color
1   10   TRUE FALSE      FALSE black
      shading  fontname fontname_cs
1 transparent Open Sans   Open Sans
  fontname_eastasia fontname.hansi
1         Open Sans      Open Sans
  vertical_align
1       baseline
...

The same thing happens when I use a loop function and "eval/parse":

fpar(c(sapply(join, function(x) eval(parse(text = x)), USE.NAMES = F)))

And when I use only eval/parse, I can only get the last object, but in the right way:

fpar(base::eval(parse(text = join)))

Could someone help me with this?

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • Using `assign` and `mget` here is really the fundamentally wrong approach. Use vectors and/or lists. Having variables with running numbers in their name is virtually *always* a mistake. — Unrelatedly, but in a similar vein, don’t use `repeat` where a simple `for` loop (or `lapply`) would do the job. It just makes the code a lot more complex. Lastly, using `noquote` also makes no sense here and likely just causes confusion. – Konrad Rudolph Feb 14 '22 at 18:52
  • Ok, thank you. All criticism is welcome, but you just showed the mistakes and didn't help me to improve my knowledge in programming. Next time you can answer in a more uplifting way. – Ludovico Victorio Aug 11 '22 at 17:57
  • Fair point, but my comment contained the relevant hint: use vectors and/or lists. For better or for worse, Stack Overflow isn't a programming tutorial, and it cannot replace a good book or course. – Konrad Rudolph Aug 12 '22 at 07:22
  • Ok, I understand that. I saw a lot of questions like that answered politely. My hint is: practice your social behavior and your empathy. You can reach better results wherever you go. Peace. ; ) – Ludovico Victorio Nov 16 '22 at 14:39

1 Answers1

0

I finally reached a solution. Although being attacked by a inflated ego and an arrogance in its pure state, I managed to do it.

spec_italic <- fp_text(font.size = 10, italic = T, font.family = "Open Sans")
normal <- fp_text(font.size = 10, font.family = "Open Sans")

h <- "Lorem ipsum _dolor_ sit amet, _lorem_ rutrum eget _nec_ hac placerat
proin. Eget _facilisis_ ut, varius."

h <- strsplit(h, "_")

formatted_text <- list()

for(i in 1:length(text_splitted)){
  if (i %% 2 == 0) {
    formatted_text[[i]] <- ftext(text_splitted[i], spec_italic)
  } else {
    formatted_text[[i]] <- ftext(text_splitted[i], normal)
  }
}

formatted_paragraph <- do.call("fpar", unname(formatted_text))
body_add_fpar(formatted_paragraph, style = "regular")

So it gives to each even term a ftext with an italic format and put it all in a list. Then I concatenate the ftexts using the do.call function applying an fpar function.