Riduci HTML a n caratteri mantenendo la formattazione


11

Quasi ogni lingua ha una funzione integrata che può dividere una stringa in una determinata posizione. Tuttavia, non appena nella stringa sono presenti tag html, la funzione integrata non funzionerà correttamente.

Il tuo compito è scrivere un programma o una funzione che divide una stringa all'ennesimo carattere ma non conta i caratteri dei tag html e genererà un html valido. Il programma deve mantenere la formattazione. Gli spazi esterni ai tag html possono essere conteggiati o non conteggiati, come si desidera, ma devono essere conservati. Tuttavia, è possibile scambiare più spazi consecutivi in ​​un unico spazio.

Ingresso:

  1. la stringa
  2. la posizione in cui dividere (in base a 0)

Questi possono essere presi come argomenti di programma o funzione o possono essere letti dall'input standard.

Output: la stringa divisa che può essere restituita o scritta nell'output standard.

L'input sarà html valido, non conterrà alcuna entità (come  ). I tag che vengono aperti dopo il limite di caratteri devono essere omessi dall'output (vedere l'ultimo esempio).

Esempio:

Ingresso :, <i>test</i>3
Uscita:<i>tes</i>

Ingresso :, <strong><i>more</i> <span style="color: red">complicated</span></strong>7
Uscita:<strong><i>more</i> <span style="color: red">co</span></strong>

Ingresso :, no html2
Uscita:no

Ingresso :, <b>no</b> <i>html root</i>5
Uscita:<b>no</b> <i>ht</i>

Ingresso :, <b>no img</b><img src="test.png" />more text6
Uscita:<b>no img</b>

Puoi usare qualsiasi lingua e la libreria standard della lingua data. Questo è il golf del codice, il programma più corto vince. Divertiti!


1
l'input può contenere "<" se ">" s che non fanno parte di un tag HTML?
xem,

Si dovrebbe usare &lt;e &gt;invece di <>, quindi no ( &lt;o &gt;non sarà presente neanche).
David Frank,

Potresti includere un esempio di mark up dopo il nodo di testo in cui si verifica la divisione? Come <i>ab</i><b>cd</b> 1?
Martin Ender,

Ci sono altre opzioni oltre a <i>a</i>?
David Frank,

@DavidFrank <i>a</i><b></b>(il che ha senso se si considera che bpotrebbe anche essere divo img.)
Martin Ender

Risposte:


2

Questa risposta non è più valida con l'ultima regola.

Javascript ( ES6 ) 94 91

f=(s,l)=>s.split(/(<[^>]+>)/).map(x=>x[0]=='<'?x:[l-->0?y:''for(y of x)].join('')).join('')
f('<strong><i>more</i> <span style="color: red">complicated</span></strong>', 7);
// '<strong><i>more</i> <span style="color: red">co</span></strong>'

Ungolfed:

f=(s,l)=>
    s.split(/(<[^>]+>)/). // split string s by <*>, capture group is spliced into the array 
    map(x=> // map function to every item in the array
        x[0]=='<'? // if first character is a <
            x // don't modify the string
        : // else
            [ // array comprehension
                for(y of x) // for every character y in x
                    l-->0? // if l > 0 (and decrement l)
                        y // character y
                    : // else
                        '' // empty string 
            ].join('') // join characters in array
        ).
    join('') // join all strings in array

Potresti fornire il codice non golfato o forse solo una spiegazione di cosa e perché il codice lo fa? Attualmente è un po 'difficile da capire. Grazie!
Gaurang Tandon,

@GaurangTandon ha aggiunto un codice non golfato con commenti
nderscore il

2

Rebol - 252 caratteri

c: complement charset"<>"f: func[s n][t: e: 0 to-string collect[parse s[any[(m: 0)copy w[["</"some c">"](-- t)|["<"some c"/>"]|["<"some c">"](++ t)| any c(m: 1)](if e = 0[if m = 1[w: copy/part w n n: n - length? w]keep w]if all[n <= 0 t = 0][e: 1])]]]]

Ungolfed con commenti:

c: complement charset "<>"

f: func [s n] [
    t: e: 0             ;; tag level (nesting) & end output flag
    to-string collect [
        parse s [
            any [
                (m: 0)                            ;; tag mode
                copy w [
                      ["</" some c ">" ] (-- t)   ;; close tag
                    | ["<"  some c "/>"]          ;; self-closing / void elements
                    | ["<"  some c ">" ] (++ t)   ;; open tag
                    | any c (m: 1)                ;; text mode
                ] (
                    ;; flag not set so can still output
                    if e = 0 [
                        ;; in text mode - so trim text
                        if m = 1 [
                            w: copy/part w n
                            n: n - length? w
                        ]
                        keep w
                    ]

                    ; if all trimmed and returned to flat tag level then end future output
                    if all [n <= 0  t = 0] [e: 1]
                )
            ]
        ]
    ]
]

Esempi nella console di Rebol:

>> f "<i>test</i>" 3
== "<i>tes</i>"

>> f {<strong><i>more</i> <span style="color: red">complicated</span></strong>} 7
== {<strong><i>more</i> <span style="color: red">co</span></strong>}

>> f {no html} 2
== "no"

>> f {<b>no</b> <i>html root</i>} 5
== "<b>no</b> <i>ht</i>"

>> f {<b>no img</b><img src="test.png" />more text} 6
== "<b>no img</b>"

>> f {<i>a</i><b></b>} 1
== "<i>a</i>"

>> f {<strong><i>even</i> <span style="color: red">more <b>difficult</b></span></strong>} 14
== {<strong><i>even</i> <span style="color: red">more <b>diff</b></span></strong>}

>> f {<strong><i>even</i> <span style="color: red">more <b>difficult</b></span></strong>} 3 
== {<strong><i>eve</i><span style="color: red"><b></b></span></strong>}

Ancora una volta ciò infrange l'ultima regola: i tag che vengono aperti dopo il limite di caratteri devono essere omessi dall'output (vedi l'ultimo esempio). Nell'ultimo esempio i tag span e b devono essere omessi. Questa regola rende la sfida quasi impossibile.
edc65,

@ edc65 - Sfortunatamente (@David Frank) non ha commentato o aggiornato i suoi esempi, quindi non è chiaro se vuole questo comportamento o no? Speravo che il mio ultimo esempio suscitasse qualcosa! Andiamo via così com'è fino a quando non avremo chiarimenti. Ad ogni modo, ci vorranno solo altri 17 caratteri per farlo funzionare come hai suggerito. L'hack non mi è particolarmente piaciuto, quindi invece riscrivilo qui (ungolfed) - gist.github.com/draegtun/93682f5a07c40bd86e31
draegtun

0

Rubino ... Molto rubylike con anelli

def split(str,n)

  i = current = 0 
  return_str = ""

  while i < n
    if str[current] == "<"
      while str[current] != ">"
        return_str.concat str[current]
        current += 1
      end
      return_str.concat str[current]
      current += 1
    else
      return_str.concat str[current]
      i += 1
      current += 1
    end
  end

  while current < str.length
    if str[current] == "<"
      while str[current] != ">"
        return_str.concat str[current]
        current += 1
      end
      return_str.concat str[current]
      current += 1
    end
    current += 1
  end


  return_str + str[current..-1]
end

Questa domanda è contrassegnata come codegolf, dovresti golf la tua risposta. Puoi iniziare sostituendo i nomi delle variabili con nomi di una lettera, usando nomi di funzioni più brevi e rimuovendo gli spazi bianchi ovunque tu sia
sagiksp

0

(IE) JS - 135

function f(t,n){b=document.body;b.innerHTML=t;r=b.createTextRange();r.moveStart("character",n);r.select();r.execCommand('cut');return b.innerHTML}

Adesso mi sento sporco. Ma è necessario iniziare a rimuovere tutti quei caratteri ...

function f(t,n)
{b=document.body;b.innerHTML=t;r=b.createTextRange();r.collapse();r.moveEnd("character",n);
r.select();return r.htmlText}

Disclaimer:

  • eseguito nella console di IE

1
Questa infrange l'ultima regola (folle): i tag che vengono aperti dopo il limite di caratteri devono essere omessi dall'output (prova il mio esempio nei commenti sopra).
edc65,

@ edc65 si spera, la versione aggiornata controlla tutte le regole
pubblicata il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.