[Question]
  [
As many of you will know, almost every programming language has a standard casing system; unfortunately, we have not been able to agree on a singular system to use and now must frequently switch between camelCase, snake\_case, PascalCase and kebab-case.
Now I know what you're thinking... wouldn't it be nice if we had a program that could convert from one casing to another?  
Well - soon we're going to have plenty!!! *(This is where you come in)*
## Challenge
You're job is to write a program/function that will take an input string, and a casing system. It will then print/return the converted string.
### Inputs:
You're program will receive two inputs, an alphabetic string that is to be converted and a string that **will always** be one of `kebab` `camel` `pascal` or `snake`.
### Outputs:
You're program should output a string that conforms to the new casing. You can assume the input string is valid and will only conform to one of the casings (*i.e. it won't be* `mixed_Casing`).  
As most programming languages prefer lowercase variable names, you should convert all letters to lowercase unless it is needed to be upper case for the casing requirements.
* Snake Case: All letters are lower case, with underscores separating words.
* Kebab Case: All letters are lower case, with hyphens separating words.
* Camel Case: The first letter of every word after the first is capitalized, with no spaces.
* Pascal Case: The first letter of every word is capitalized, with no spaces.
## Test Cases:
```
"aJavaVariable", "snake" = "a_java_variable"  
"a_python_variable", "kebab" = "a-python-variable" 
"golf", "camel" = "golf"
"camelToPascal", "pascal" = "CamelToPascal"  
"PascalToCamel", "camel" = "pascalToCamel"  
"", "snake" = "" 
"doHTMLRequest", "kebab" = "do-h-t-m-l-request"  
```
```
<!-- Run the snippet to see the leaderboard. Report any bugs to @ozewski on Github. -->    <iframe src="https://ozewski.github.io/ppcg-leaderboard/?id=216396" width="100%" height="100%" style="border:none;">Oops, your browser is too old to view this content! Please upgrade to a newer version of your browser that supports HTML5.</iframe><style>html,body{margin:0;padding:0;height:100%;overflow:hidden}</style>
```
  
[Answer]
# [JavaScript (Node.js)](https://nodejs.org), ~~127 126~~ 120 bytes
Expects `(string)(type)`.
```
s=>t=>s.split(/_|-|(?=[A-Z])/).map((s,i)=>(k=parseInt(t,29)%5,(b=Buffer(s))[0]=b[0]&95|(k+!i>1)<<5,b)).join(['-_'[k-3]])
```
[Try it online!](https://tio.run/##jdBBa4MwFMDxu5@iE7a@R43dWjwUGse209ilsJ7mRKKLw2oTMdlOfndXJV6kkl3CI/wf@ZET@2Uqa4paEyG/eJfTTtFQ01D5qq4KDeukJS080uiJfMS4Rv/MagDlFUhDKGnNGsVfhQbtbXZ4G3iQ0uefPOcNKMToPqbp5bjbBS2Uq5sifMD9PvBSRP8kCwHRkiTLqCTbOMYuk0LJivuV/IYcXCVYyRMtk2Fw0dy4iM6kLHnKUqIlsZYZO/PqKN9t3eHyKexKuFgt3E/houPMYQdLv2GGeay1NNg3Wzdip6EdO7zQb5hhHmstDfbF1o3YaWjH1sNmvzJO89x/tAZ8sJcj@Ura/QE "JavaScript (Node.js) – Try It Online")
### How?
The type string \$t\$ is converted to an ID \$k \in [0..4]\$ by parsing it as a base-29 value and applying a modulo \$5\$:
```
 type     | base 29 -> dec. | mod 5
----------+-----------------+-------
 "pascal" |    520544830    |   0
 "camel"  |      8750191    |   1
 "kebab"  |     14496618    |   3
 "snake"  |     20373819    |   4
```
This formula was chosen because it puts *pascal* next to *camel* and *kebab* next to *snake*, allowing the following expressions:
* Put the leading character in uppercase if 1) the type is *pascal* (\$k=0\$), or 2) the type is *camel* (\$k=1\$) and this is not the first word (\$i\neq 0\$):
```
(b = Buffer(s))[0] = b[0] & 95 | (k + !i > 1) << 5
```
* Join with `"-"` for *kebab* (\$k=3\$), `"_"` for *snake* (\$k=4\$) or an empty string otherwise:
```
.join(['-_'[k - 3]])
```
[Answer]
# [Perl 5](https://www.perl.org/) `-lF'_|-|(?=[A-Z])'`, 69 bytes
```
$,=('_','-')[$c=3-ord(<>)%14%7];say map$c>1&&$i++||$c>2?ucfirst:lc,@F
```
[Try it online!](https://tio.run/##NYtdC4IwGEbv9yu6MKfkIvsgqLS6iYiCiOiiCHmdq8Tl1mZBsN/eCqSb5xwOPJIpPrDWCSIPJzjABPsnh0Y9IlTmTWK/Gfabw/NYw7txB@nQOHRdJ2@1jPl5d/qkl1zpasRpMFtYCyt4wQFUDilnSJdQMASJfFc3USavfy9YCim6Cn5BFO6M17sXW9AUOJI1MrHcb9Y79ngyXdWfj5BVLkptyWbQ7oQdS/gCJ4YYbxqd5uR49vEX "Perl 5 – Try It Online")
[Answer]
# [Retina 0.8.2](https://github.com/m-ender/retina/wiki/The-Language/a950ad7d925ec9316e3e2fb2cf5d49fd15d23e3d), 81 bytes
```
T`l\_-`L_`^.|_.|-.
\B(?=[A-Z].*¶s)
_
\B(?=[A-Z].*¶k)
-
T`L`l`^.(?!.*¶p)|_.|-.
1G`
```
[Try it online!](https://tio.run/##K0otycxL/K@qEZyg8z8kIScmXjfBJz4hTq8mXq9GV48rxknD3jbaUTcqVk/r0LZiTa54NKFsTS5drpAEn4QcoCYNe0WQWIEmVLehe8L//4leiWWJYYlFmYlJOak6xXmJ2alcifEFlSUZ@XnxZTDx7NSkxCSu9PycNJ3kxNzUHC4wGZIfkFicnJijUwCmuKDaU/I9Qnx9glILS1OLSyBaAQ "Retina 0.8.2 – Try It Online") Takes input on separate lines but link includes test suite that splits the input on commas. Explanation:
```
T`l\_-`L_`^.|_.|-.
```
Uppercase the first letter and any letters after `_` or `-`, which get deleted. This gives you Pascal case.
```
\B(?=[A-Z].*¶s)
_
\B(?=[A-Z].*¶k)
-
```
Prefix interior capital letters with `_` (for snake case) or `-` (for kebab case).
```
T`L`l`^.(?!.*¶p)|_.|-.
```
Except for Pascal case, lowercase the first letter, plus (since we just marked them) all the letters for snake or kebab case.
```
1G`
```
Delete the second input (the case) leaving the result.
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), ~~50~~ ~~48~~ 47 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
.ªÐáмÙ¡¸˜Dgi`.œ.ΔD™Q]l²ÇO5%©2‹i„_-®èýë™J®4Qićlì
```
[Try it online](https://tio.run/##AWgAl/9vc2FiaWX//y7CqsOQw6HQvMOZwqHCuMucRGdpYC7Fky7OlETihKJRXWzCssOHTzUlwqky4oC5aeKAnl8twq7DqMO9w6vihKJKwq40UWnEh2zDrP//ZG9IVE1MUmVxdWVzdAprZWJhYg) or [verify all test cases](https://tio.run/##yy9OTMpM/V9Waa@k8KhtkoKSfWVCqNJ/vUOrDk84vPDCnsMzDy08tOP0HJf0zAS9o5P1zk1xedSyKDA2J@Jwu7@p6qGVRo8admY@apgXr3to3eEVh/ceXg2U9zq0ziQw80h7zuE1/5X0wnT@R0crJXolliWGJRZlJiblpCrpKBXnJWanKsXqAGXiCypLMvLz4ssQstmpSYlJYNn0/Jw0oEByYm5qDlgAzArJD0gsTk7MAcoUQBggKRRjU/I9Qnx9glILS1OLS1CMxGYhwnyIwSH5zmARuEwsAA).
**Explanation:**
```
.ª           # Sentence capitalize the first (implicit) input-string, which titlecases
             # without removing existing capital letters
  Ð          # Triplicate that string
   á         # Only leave its letters
    м        # Remove all those letters (so only "-"/"_" are left, if any)
     Ù       # Uniquify the potential multiple "-"/"_" to a single character
      ¡      # Split the string on this character
       ¸˜    # Wrap it into a list, and flatten
Dg           # Get the length of a copy of this list
  i          # If this length is 1 (thus no "-"/"_" were present):
   `         #  Push the string to the stack to remove the wrapped list
    .œ       #  Get all partitions of this string
      .Δ     #  Find the first partition which is truthy for:
        D    #   Duplicate the list of substrings
         ™   #   Titlecase each string
          Q  #   Check that the two lists are equal
  ]          # Close both the find_first and if-statement
   l         # Lowercase each string in the list
    ²        # Push the second input-string
     Ç       # Convert it to a list of codepoint integers
      O      # Sum those
       5%    # And take modulo-5 on it (snake=0; kebab=1; camel=4; pascal=3)
         ©   # Store this in variable `®` (without popping)
2‹i          # If it's smaller than 2 (thus snake or kebab):
   „_-       #  Push string "_-"
      ®è     #  (0-based) index `®` into this string
        ý    #  Join the list by this character as delimiter
  ë          # Else (thus camel or pascal):
   ™         #  Titlecase each string in the list
    J        #  Join them together
     ®4Qi    #  If `®` equals 4 (thus camel):
         ć   #   Extract head; pop and push remainder-string and first character
             #   separated to the stack
          l  #   Lowercase this first character
           ì #   And then prepend it back in front of the remainder-string
             # (after which the result is output implicitly)
```
[Answer]
# [Ruby](https://www.ruby-lang.org/),  ~~112~~  103 bytes
```
->s,c{x=s.split(/(?=[A-Z])|-|_/).map{x=c[5]||x&&c<?d?_1.capitalize: _1.downcase}*(c>?s??_:c[?k]??-:'')}
```
[Try it online!](https://tio.run/##XZBPT4NAEMXv/RQbmrRgWHowXhrpxvRijCbGNB4khAzL1q5sWWShtrJ8dsqfUIunnXm/92YmmxXhqd66NV4pm5ZHVzkqFTw3FyZxvQf84Vsa62BhOXtIS8310aXena/1cTaj9yQi3KGQ8hwE/2VLxJ1I/iQUFKtuTLoiipBgST0S@4Tg5XxuVbU3QciAJzjAO2QcQsEMGxkqgbgrIPhqUHC4sM4epKd8J5MrGRkxCyHsIrineBz6lGLbYgp7JtqiF1rUSRv5CopCh9JLtR6j1j26r5d6vJHrYfZlSTomrTmSj5uX5zf2XTCVjy6PJN7hHO@xwNmAJ77DgO4CJThl5q2FIok0T9Iit1HcfKyNZJE3nW5GN49CxrTscGWjadk6KmNAW@8q6A9qn2@6DLhiqEgEU/@9yHX/fG1qwpKoPgM "Ruby – Try It Online") (+1 byte because TIO doesn't support ruby 2.7's `_1`)
Multiple bytes saved thanks to @Dingus
* `x` tracks whether it's not the first iteration
* `c[5]` asks whether it's `"pascal"` (the only one with 6 letters)
* `c>?s` asks if `c` is greater than `'s'`, this is only true for `"snake"`, etc.
* the multiplication at the end is equivalent to `join`
[Answer]
# [Laravel](https://laravel.com/)/PHP, 264 bytes
It accepts a GET request to `/{string}/{kebab|camel|pascal|snake}` as input, and output is done via dumping. Bytes are counted for the one file that I wrote.
web.php:
```
<? use Illuminate\Support\Str;Illuminate\Support\Facades\Route::get('/{a}/{b}',function(){$a=str_replace("_","-",request()->a);switch(request()->b[0]){case'p':dd(Str::studly($a));case'c':dd(Str::camel($a));case'k':dd(Str::kebab($a));default:dd(Str::snake($a));}});
```
I wrote/ran this on [PHP Sandbox](https://phpsandbox.io/) and verified it with PHPUnit tests like so (must be run one at a time!):
```
$this->get('/aJavaVariable/snake');
$this->get('/a_python_variable/kebab');
$this->get('/golf/camel');
$this->get('/camelToPascal/pascal');
$this->get('/PascalToCamel/camel');
$this->get('//snake'); // 404 (no output)
$this->get('/doHTMLRequest/kebab');
```
Could probably save bytes by using Laravel < 6 and the helpers str\_\*, but didn't feel like verifying it would run. Does anyone see any other shortcuts?
]