Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

The goal is really simple. Receiving a string as input, parse all the HTML entities that correspond to the following characters (including their uppercase variants):

áàãâäéèêëíìîïóòõôöúùûüýÿ

Parsing rules:

  • Each entity starts with & and ends with ;
  • The first character after the & will be the modified character (letter case is important!)
  • The remaining characters refer to the name of the accent to use (acute, grave, circ, tilde and uml). The accent name MUST be in lowercase! *
  • Any HTML entity that produces a character that isn't on that list, or that is invalid, should be left untouched (E.g.: &, &etilde;, &a;)
  • Numeric entities should be ignored, since they don't fit in the rules above

This change was introduced as of 18-02-2016. All the existing answers that accept HTML entities with uppercase accent names are valid. Any future answer must follow this rule.

Examples:

á //á
Téhèh //Téhèh
an & //an &

Output:

The output can be in ISO-8859-X (1-15), windows-1252 or UTF-8/16/32.
You can pick one and only one of the valid encodings and use it for any output. You can safely assume that the input will be in ASCII.

Any of the following is a valid output for á:

  • á (ISO-8859-1/15 or windows-1252, equivalent to \xE1)
  • á (UTF-8, equivalent to \xC3\xA1 or \u00E1)
  • (UTF-8, equivalent to a\xCC\x81 or a\u0301)
  • Any combination of diacritics, without using HTML entities.

The output has to be visually similar, when rendered/displayed, to the characters on the list.


Remember, all the standard loopholes and built-ins * are disallowed. Since this is , the shortest answer wins.

* This change was made due to the great disapproval of bonuses and penalities, and at the time of writting, doesn't invalidate any answer

share|improve this question
4  
I didn't vote, but I assume the downvotes are because people don't really like bonuses/penalties - They end up making one challenge into several mini-challenges. – Kevin W. Feb 17 at 16:12
1  
@KevinW. As I explained in the sandbox, I only left those penalities because I want to see what cool built-in stuff people can come up with. But obviously, I don't want to spoil everybody's fun. If I didn't put the penality, an answer like the Javascript example I gave, would be enough. And that required no work at all. – Ismael Miguel Feb 17 at 16:15
1  
IMHO, the bonuses seem arbitrary - either allow or don't allow, don't go in between. – VTCAKAVSMoACE Feb 17 at 19:31
1  
@IsmaelMiguel I suggest no bonuses/penalties - allow whatever programming methods they wish to use (outside of the Standard Loopholes, of course) and remove the bonuses/penalties. – VTCAKAVSMoACE Feb 17 at 19:43
2  
@IsmaelMiguel Nah - that was all of my cents. c: – VTCAKAVSMoACE Feb 17 at 19:51

JavaScript (ES6), 141 122 134 bytes

a=>a.replace(/&([aeiouyAEIOUY](acute|uml)|[aeiouAEIOU](grave|circ)|[aoAO]tilde);/g,b=>b[1]+{g:"̀",a:"́",c:"̂",t:"̃",u:"̈"}[b[2]])

Followed daavko's example using diacritical marks, and I feel like an idiot for not thinking of using it sooner. Actually gets surprisingly short for JavaScript.

EDIT: Neil caught some bad cases of undefined, which are now fixed.

share|improve this answer
    
See? I told you that you could cut some fat! This is a really surprising answer! I trully hope you get more +1's – Ismael Miguel Feb 17 at 19:41
1  
This is just clever. +1 – TuukkaX Feb 17 at 20:05
    
I love it..! String.prototype.replace is so ridiculously golfable for string traversal. – Archenoth Feb 17 at 23:21
    
I'm not convinced that this does the right thing for É (whatever that right thing is). – Neil Feb 18 at 1:21
    
Sadly, @Neil is right. Uppercase HTML entities are considered invalid by browsers. But, I didn't specify that the accent name should be all in lowercase. That is entirelly my fault. I will consider this answer valid and all the ones that were already posted. But any new answer must have the accent names in lowercase. – Ismael Miguel Feb 18 at 15:13

Retina, 115 bytes

I'm new to code-golf, but I think this might work.
This version was made before the rule, which doesn't allow replacing uppercase html entities (for example Á) was introduced.

i`&([aeiouy])acute;
$1́
i`&([aeiou])grave;
$1̀
i`&([ao])tilde;
$1̃
i`&([aeiou])circ;
$1̂
i`&([aeiouy])uml;
$1̈

Quite simple search and replace. Uses UTF-8.

Uses [letter]\xCC\x[diacritical mark hex code] approach. Diacritical mark is added after every relevant letter.

For some reason, the default Droid Sans Mono font in the interpreter can't render the "circ" and "uml" letters properly. If you change it through developer tools to something like DejaVu Sans, it shows just fine. I think this is a limitation of the font, not the program. But if it's program's fault, I'll try to fix it.

Here is a 129 byte version, which doesn't replace uppercase HTML entites (for example Á)

&([aeiouyAEIOUY])acute;
$1́
&([aeiouAEIOU])grave;
$1̀
&([aoAO])tilde;
$1̃
&([aeiouAEIOU])circ;
$1̂
&([aeiouyAEIOUY])uml;
$1̈

Try it online!
Try it online! 129-byte version

share|improve this answer
    
Great use of the marks there. Can't believe I didn't think of that being shorter at first >_< – Mwr247 Feb 17 at 19:26
    
@Mwr247 Thanks! I was searching for a way to do this, since I wanted to try to do it and the marks just showed up somewhere...I'm honestly surprised it's so short. – daavko Feb 17 at 19:29
1  
Nice fair-play and use of the rules! I never liked this language, but I really am loving this answer. Instant +1 – Ismael Miguel Feb 17 at 19:39
    
I counted 115 bytes (110 characters + 5 extra bytes for the marks). – Mwr247 Feb 17 at 19:51
    
@Mwr247 Oh, you're right. I just pasted it into a text document and ran ls -l and it showed 116...seems the editor added an extra newline at the end. I'll fix it. – daavko Feb 17 at 19:55

Japt, 81 75 bytes

Ur`&([%vYy](ac©e|uml)|%v(g?ve|circ)|[AaOo]Èìe);`@Yg +'Ì+"?????"g"gutca"bYgJ

The six ?s represent unprintable chars. Test it online!

Note: This outputs the third encoding option; that is, the letter followed by the raw UTF-8 encoding of the corresponding combining diacritical mark.

How it works

Ur"&(    );"       // Replace each ampersand and semicolon that have one of these between them:
([%vYy](acute|uml) //  A vowel or Yy followed by "acute" or "uml",
|%v(grave|circ)    //  or a vowel followed by "grave" or "circ",
|[AaOo]tilde       //  or "a" or "o" followed by "tilde";
@                  // replace each match X and its middle Y with this function:
""g"gutca"bYgJ     //  Take the unprintable at index (index of the second char in Y in "gutca") in this string.
Yg +'Ì+            //  Concatenate the first char in Y and "Ì" to the beginning.
                   // Implicit output

Hexdump of the code:

00000000: 55 72 60 26 28 5b 25 76 59 79 5d 28 61 63 a9 65  Ur`&([%vYy](ac©e
00000010: 7c 75 6d 6c 29 7c 25 76 28 67 9f 76 65 7c 63 69  |uml)|%v(g.ve|ci
00000020: 72 63 29 7c 5b 41 61 4f 6f 5d c8 ec 65 29 3b 60  rc)|[AaOo]Èìe);`
00000030: 40 59 67 20 2b 27 cc 2b 22 80 81 82 83 88 22 67  @Yg +'Ì+"....."g
00000040: 22 67 75 74 63 61 22 62 59 67 4a                 "gutca"bYgJ
share|improve this answer
    
It seems to work nicely. Can you please provide a hexdump? You seem to have there some "weird" characters that may not work in every encoding. – Ismael Miguel Feb 17 at 20:20
    
@IsmaelMiguel I've just realized that the accents are not part of the ISO-8859-1 encoding; thus, I've uncompressed the string and switched to UTF-8 bytes. Would you still like a hexdump? – ETHproductions Feb 17 at 20:27
    
Up to you, but your previous solution was perfectly fine. – Ismael Miguel Feb 17 at 20:31
    
I think you might have a tiny bug there, your code seems to leave &Yacute; alone, but it should be changed to Ý... – daavko Feb 17 at 20:32
    
@daavko Whoops, you're right! Fixed now. – ETHproductions Feb 17 at 20:35

JavaScript (ES6), 288 bytes

a=>(z=(b,c=1,d=2,e=3,f=0,g=4)=>({b:b+191,grave:c,acute:d,circ:e,tilde:f,uml:g}),y={a:z(0,1,2,3,4,5),e:z(8),i:z(12),o:z(18,1,2,3,4,5),u:z(25),y:z(28,0,2,0)},a.replace(/&\w+;/gi,b=>(x=y[b[1].toLowerCase()])&&(w=x[b.slice(2,-1)])?String.fromCharCode(x.b+w+32*(b[1]>'_')+153*/Yu/.test(b)):b))

Creates a character map object (with the base numeric code for each character), and uses offsets (or 0 if non-existent) to determine if an entity should be converted and what it's character code is. Symmetry in the cases means adding 32 if lowercase, except for &Yuml;, where it uses a different offset for UTF8.

share|improve this answer
    
Nice! I really like your aproach, but 286 bytes is a bit long. Maybe there are a few things that can be cut off? Trimming some fat would be great – Ismael Miguel Feb 17 at 17:32
    
@IsmaelMiguel 288 actually; I just realized that there is in fact a &Yuml; in UTF8: it's just in a weird place. All the same, I thought I condensed and optimized it rather well, considering a literal replace list would be over twice as long. Are you seeing something I'm not? – Mwr247 Feb 17 at 17:46
    
Not really... There must be a better way to make lowercase letters than using .toLowerCase(). That name is HUGE!!! Also, String.fromCharCode can accept multiple parameters, or be called as String.fromCharCode.call([...]) – Ismael Miguel Feb 17 at 17:51
1  
@IsmaelMiguel Seems I was right about it needing a rewrite, but wrong about it needing to be someone else. I feel this answer is more interesting, but the other one is technically more concise, so I've included them both separately. – Mwr247 Feb 17 at 18:57
1  
Not life-changing but your regexp contains no literal letters so it doesn't need the i flag. – Neil Feb 18 at 1:25

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.