Indent a string using given parentheses

16

6

Given the following input to the program:

  1. List of block start characters
  2. List of block end characters
  3. A string to format

format the string with the blocks delimited by the two character sets indented.

Formatting is done with two spaces per level and the parentheses are placed as shown in the example below. You may assume the sets of opening and closing characters to be disjoint.

E.g. for {[(< and }])> as the opening and closing character sets and the following string:

abc{xyz{text[note{comment(t{ex}t)abc}]}}

the following output would be expected:

abc
{
  xyz
  {
    text
    [
      note
      {
        comment
        (
          t
          {
            ex
          }
          t
        )
        abc
      }
    ]
  }
}

You may not hard-code the list of “parentheses” characters. How input is given is not specified, though; this could be either command-line arguments or via standard input, as you wish.

Prashant Bhate

Posted 2011-07-04T22:33:00.023

Reputation: 291

5Can we assume that for each parenthesis there's a closing one, and in the same order? – Juan – 2011-07-05T01:22:42.150

Does the program have to support any parenthesis characters given as arguments? e.g. ./program 'p' 'q' <<< '1p23p45q67q8' Or does it need only support {[(< and }])> ? – Joey Adams – 2011-07-05T03:27:29.200

@Joey, I'd assume not, though that would be all the more impressive. – Neil – 2011-07-05T07:39:45.047

joey : input are 1. open parenthesis characters 2.close parenthesis chars 3. string to indent. Juan : we can assume that, though code need not rely on that, what I mean is if delim is part of opening parenthesis chars, increase indent, else if part of closing parenthesis chars decrease indent. – Prashant Bhate – 2011-07-05T11:25:55.983

I rewrote the task specification. Could you look over it and figure out whether that's roughly what you meant? I've tried to be clearer on the exact specifications as the previous wording gave rise to four wrong answers. – Joey – 2011-07-05T12:04:48.810

Another thing: Is this supposed to be a Code Golf? Your solution doesn't seem to imply this, but as a challenge it's fairly trivial. Please clarify. – Joey – 2011-07-05T15:12:01.473

considering forum yes you are right , changed answer to reflect the same. I was trying it in java and so posted it here ! – Prashant Bhate – 2011-07-05T15:44:29.800

Are leading/trailing newlines allowed? – Lowjacker – 2011-07-06T21:58:14.110

Lowjacker assume that no newlines in the input – Prashant Bhate – 2011-07-07T08:26:26.027

1@Phrasant Bhate: And in the output? – Lowjacker – 2011-07-07T11:37:34.763

Answers

6

Perl - 131 96 94 chars

$i="";for$_(split/([\Q$ARGV[0]$ARGV[1]\E])/,$ARGV[2]){$i=~s/..// if/[\Q$ARGV[1]\E]/;print "$i$_\n"if$_;$i.='  'if/[\Q$ARGV[0]\E]/;}

Seems like there should be room for eliminating common expressions, at least, but it's a quick take that handles the example, as well as Joey Adams's hypothetical about arbitrary brackets.


There was, indeed, plenty of room for improvement:

$_=pop;($s,$e)=map"[\Q$_\E]",@ARGV;for(split/($s|$e)/){print"  "x($i-=/$e/),"$_\n"if$_;$i+=/$s/}

...and still a little more:

$_=pop;($s,$e)=map"[\Q$_\E]",@ARGV;map{print"  "x($i-=/$e/),"$_\n"if$_;$i+=/$s/}split/($s|$e)/

DCharness

Posted 2011-07-04T22:33:00.023

Reputation: 541

6

Ruby, 106 101 96 95

s,e,i=$*
i.scan(/[#{z=Regexp.quote s+e}]|[^#{z}]*/){|l|puts'  '*(s[l]?~-$.+=1:e[l]?$.-=1:$.)+l}

Input is provided via the command line.

Lowjacker

Posted 2011-07-04T22:33:00.023

Reputation: 4 466

1You can save 4 characters by using ~-j+=1 instead of (j+=1;j-1). Additionally, using $. everywhere instead of j allows you to remove the j=0, which saves another character. – Ventero – 2011-07-07T11:37:23.723

3

JavaScript, 255 227 205 characters

Hey, its length fits perfectly in a byte! :D

function(s,e,t){R=eval.bind(0,"Array(n).join(' ')");for(i=n=0,b=r='';c=t[i++];)~s.indexOf(c)?(r+=b,b='\n'+R(++n)+c+'\n '+R(++n)):~e.indexOf(c)?b+='\n'+((n-=2)?R()+' ':'')+c+'\n'+(n?R()+' ':''):b+=c;return r+b}

It's a function, pass it the start characters, the end characters, then the text.

Ry-

Posted 2011-07-04T22:33:00.023

Reputation: 5 283

Your own edit comment has been used against you. :D – Doorknob – 2013-09-30T23:38:29.820

@Doorknob: I… I thought I had never done that. D: I am so sorry. (Were you hunting?) – Ry- – 2013-09-30T23:52:57.257

@Doorknob: And thanks for reminding me about this; shortened :) – Ry- – 2013-10-01T00:02:19.733

No I wasn't hunting, just stumbled upon this question, but I decided to, and I found this :O :P

– Doorknob – 2013-10-01T02:03:26.497

3

Mathematica (non code golf)

indent[str_String]:=Module[{ind,indent,f},
ind=0;
indent[i_]:="\n"<>Nest["    "<>ToString[#]&,"",i];
f[c_] :=  (indent[ind] <> c <> indent[++ind]) /; StringMatchQ["[({",___~~c~~___];
f[c_] := ( indent[--ind] <> c <>indent[ind])  /; StringMatchQ["])}",___~~c~~___];
f[c_] := (c <>indent[ind])       /; StringMatchQ[";,",___~~c~~___];
f[c_] := c  ;
f /@ Characters@ str//StringJoin
]

Test

indent["abc{xyz{text[note{comment(t{ex}t)abc}]}}"]
abc
{
    xyz
    {
        text
        [
            note
            {
                comment
                (
                    t
                    {
                        ex
                    }
                    t
                )
                abc
            }

        ]

    }

}

As a bonus, following function can be used to format mathematica expression

format[expr_] := indent[expr // FullForm // ToString]

EDIT(non code golf) Updated with fine granular control over the way newlines are rendered

indent[str_String, ob_String, cb_String, delim_String] := 
  Module[{ind, indent, f, tab}, ind = 0; tab = "    ";
   indent[i_, tab_, nl_] := nl <> Nest[tab <> ToString[#] &, "", i];
   f[c_] := (indent[ind, "", " "] <> c <> indent[++ind, tab, "\n"]) /;StringMatchQ[ob, ___ ~~ c ~~ ___];
   f[c_] := (indent[--ind, "", " "] <> c <> indent[ind, tab, "\n"]) /;StringMatchQ[cb, ___ ~~ c ~~ ___];
   f[c_] := (c <> indent[ind, tab, "\n"]) /;StringMatchQ[delim, ___ ~~ c ~~ ___];
   f[c_] := c;
   f /@ Characters@str // StringJoin];
format[expr_] := indent[expr // InputForm // ToString, "[({", "])}", ";"];

format[Hold@Module[{ind, indent, f, tab}, ind = 0; tab = "    ";
 indent[i_, tab_, nl_] := nl <> Nest[tab <> ToString[#] &, "", i];
 f[c_] := (indent[ind, "", " "] <> c <> indent[++ind, tab, "\n"]) /;StringMatchQ[ob, ___ ~~ c ~~ ___];
 f[c_] := (indent[--ind, "", " "] <> c <> indent[ind, tab, "\n"]) /;StringMatchQ[cb, ___ ~~ c ~~ ___];
 f[c_] := (c <> indent[ind, tab, "\n"]) /;StringMatchQ[delim, ___ ~~ c ~~ ___];
 f[c_] := c;
 f /@ Characters@str // StringJoin]]

Output

Hold [
    Module [
         {
            ind, indent, f, tab }
        , ind = 0;
         tab = "    ";
         indent [
            i_, tab_, nl_ ]
         := StringJoin [
            nl, Nest [
                StringJoin [
                    tab, ToString [
                        #1 ]
                     ]
                 & , "", i ]
             ]
        ;
         f [
            c_ ]
         := StringJoin [
            indent [
                ind, "", " " ]
            , c, indent [
                ++ind, tab, "\n" ]
             ]
         /;
         StringMatchQ [
            ob, ___~~c~~___ ]
        ;
         f [
            c_ ]
         := StringJoin [
            indent [
                --ind, "", " " ]
            , c, indent [
                ind, tab, "\n" ]
             ]
         /;
         StringMatchQ [
            cb, ___~~c~~___ ]
        ;
         f [
            c_ ]
         := StringJoin [
            c, indent [
                ind, tab, "\n" ]
             ]
         /;
         StringMatchQ [
            delim, ___~~c~~___ ]
        ;
         f [
            c_ ]
         := c;
         StringJoin [
            f / @
                 Characters [
                    str ]
                 ]
             ]
         ]

Prashant Bhate

Posted 2011-07-04T22:33:00.023

Reputation: 291

That is hardly code golf, with multi-character names like indent. Is your goal maximally terse code, or readability? There are a number of ways to make that code shorter, if that is indeed your goal. Also: "You may not hard-code the list of “parentheses” characters." yet isn't that exactly what you did here? Anyway, sorry to sound so negative; it just strikes me as a strange answer to your own challenge. – Mr.Wizard – 2011-11-28T17:13:54.637

1@Mr.Wizard its not code golf, I have added it for my own reference [updated to make it clear]. I frequently use it to understand unformatted mathematica code that span larger than a page – Prashant Bhate – 2011-12-27T13:40:11.273

2

C - 213 209

I hate stupid mistakes... >.<

#include<stdio.h>
#include<string.h>
int main(int i,char**s){for(char q,r,c,t,a=0;~(c=getchar());t=q|r){q=!!strchr(s[1],c);a-=r=!!strchr(s[2],c);for(i=0;t|q|r&&i<2*a+1;putchar(i++?' ':'\n'));a+=q;putchar(c);}}

Reads left-parens from first command-line argument, right-parens from second argument, and input to indent on stdin.

Pretty-printed & commented:

int main(int i, char **s) {
  for (char q, r, /* is left-paren? is right-paren? */
            c,    /* character read from input */
            t,    /* last char was a paren-char */
            a=0;  /* indentation */
       ~(c = getchar());
       t = q|r) {
         q = !!strchr(s[1],c);
    a -= r = !!strchr(s[2],c);
    for (i=0; t|q|r && i<2*a+1; putchar(i++? ' ' : '\n'));
    a += q;
    putchar(c);
  }
}

FireFly

Posted 2011-07-04T22:33:00.023

Reputation: 7 107

2

Python – 162 chars

i=f=0
s=""
l,r,z=[raw_input()for c in'   ']
o=lambda:s+("\n"+"  "*i)*f+c
for c in z:
 if c in l:f=1;s=o();i+=1
 elif c in r:i-=1;f=1;s=o()
 else:s=o();f=0
print s

Juan

Posted 2011-07-04T22:33:00.023

Reputation: 2 738

Note that the task calls for the two sets of parentheses to be part of the input, not hardcoded. – Joey – 2011-07-05T12:51:43.373

@Joey noted, I'll get around to fixing that in a while. Thanks – Juan – 2011-07-05T13:40:25.750

2

Python 2.7.X - 136 chars

import sys
a,c=sys.argv,0
for i in a[3]:
 if not(i in a[2]):print ' '*c+i
 else:print ' '*(c-4)+i
 if i in a[1]:c+=4
 if i in a[2]:c-=4

Usage : $ ./foo.py '(' ')' '(ab(cd(ef)gh)ij)'

Resulting Output:

(
    a
    b
    (
        c
        d
        (
            e
            f
        )
        g
        h
    )
    i
    j
)

arrdem

Posted 2011-07-04T22:33:00.023

Reputation: 805

Do you need the spaces after the print statements? – Zacharý – 2016-12-04T00:25:06.900

1

Groovy, 125

p=args;i=0;s={a,b->"\n"+"\t"*(b?i++:--i)+a+"\n"+"\t"*i};p[0].each{c->print p[1].contains(c)?s(c,1):p[2].contains(c)?s(c,0):c}

You can save the script in a file indent.groovy and try it with:
groovy indent.groovy "abc{xyz{text[note{comment(t{ex}t)abc}]}}" "{[(" ")]}"

Marco Martinelli

Posted 2011-07-04T22:33:00.023

Reputation: 293

I tried around in groovy for an hour before seeing your answer, I used a similar aproach, but mine is much longer than yours so I won't even bother to post.. Good job! :) – Fels – 2013-10-11T17:33:08.583

1

Python - 407

from sys import*;o=argv[1];c=argv[2];t=argv[3];p=0;n=False;a=lambda:h not in e;b=lambda s:print(s+(" "*p)+h);r="";e=o+c
for h in t:
 for k in o:
  if h==k:
   if(r in e)and(r!=""):b("")
   else:b("\n")
   p+=2;n=True;break
 for k in c:
  if h==k:
   p-=2
   if(r in e)and(r!=""):b("")
   else:b("\n")
   n=True;break
 if a()and n:print((" "*p)+h,end="");n=False
 elif a():print(h,end="")
 r=h

An ungolfed version of the program:

import sys

open_set = sys.argv[1]
close_set = sys.argv[2]
text = sys.argv[3]
spaces = 0
newline = False
a = lambda : char not in b_set
b = lambda s: print(s + (" " * spaces) + char)
prev = ""
b_set = open_set + close_set

for char in text:
    for bracket in open_set:
        if char == bracket:
            if (prev in b_set) and (prev != ""):
                b("")
            else:
            b("\n")
        spaces += 2
        newline = True
        break
    for bracket in close_set:
        if char == bracket:
            spaces -= 2
            if (prev in b_set) and (prev != ""):
                b("")
            else:
                b("\n")
            newline = True
            break
    if a() and newline:
        print((" " * spaces) + char, end="")
        newline = False
    elif a():
        print(char, end="")
    prev = char

The arguments to the program are (in order): the opening parentheses, the closing parentheses, and the text to indent.

Example ($ is command line prompt):

$ python indent.py "{[(<" "}])>" "abc{xyz{text[note{comment(t{ex}t)abc}]}}"
abc
{
  xyz
  {
    text
    [
      note
      {
        comment
        (
          t
          {
            ex
          }
          t
        )
        abc
      }
    ]
  }
}

golfer9338

Posted 2011-07-04T22:33:00.023

Reputation: 411

1

Python3, 184 182 chars

import sys
_,p,q,t=sys.argv
i,f,x=0,1,print
for e in t:
 if e in p:f or x();x(' '*i+e);i+=2;f=1
 elif e in q:f or x();i-=2;f=1;x(' '*i+e)
 else:not f or x(' '*i,end='');f=x(e,end='')

Example:

$ python3 ./a.py '{[(<' '}])>' 'abc{xyz{text[note{comment(t{ex}t)abc}]}}'
abc
{
  xyz
  {
    text
    [
      note
      {
        comment
        (
          t
          {
            ex
          }
          t
        )
        abc
      }
    ]
  }
}

Alexandru

Posted 2011-07-04T22:33:00.023

Reputation: 5 485

heinrich5991 suggested saving two characters by changing the second line to _,p,q,t=sys.argv – Peter Taylor – 2013-04-03T08:53:47.147

1

C (159 225 chars)

#define q(s,c)strchr(s,c)
#define p(i,j,k)printf("\n%*s%c%c%*s",i,"",*s,k,j,"")
g(char*b,char*e,char*s){int i;for(i=0;*s;s++)q(b,*s)?p(i-2,i+=2,'\n'):q(e,*s)?q(b,*(s+1))||q(e,*(s+1))?p(i-=2,i-2,0):p(i-=2,i-2,'\n'):putchar(*s);}

It cost me 66 extra characters just to fix the bug with the empty lines :( Frankly, I need a fresh approach, but I'll call it a day for now.

#define p(i,j)printf("\n%*s%c\n%*s",i,"",*s,j,"")
f(char*b,char*e,char*s){int i;for(i=0;*s;s++){strchr(b,*s)?p(i-2,i+=2):strchr(e,*s)?p(i-=2,i-2):putchar(*s);}}

A rather quick & dirty approach. It has a bug of producing empty lines between consecutive closing parenthesis, but otherwise it does the job (or so I think). I will revisit it for a better & cleaner solution, sometime this week.

char *b is the opening parenthesis set, char *e is the closing parenthesis set and char *s is the input string.

Harry K.

Posted 2011-07-04T22:33:00.023

Reputation: 215

1

Perl - 69 bytes

TMTOWTDI makes code simple

#!perl -p
s/([[{(<])|([]})>])|\w+/"  "x($1?$t++:$2?--$t:$t)."$&
"/ge

Hojung Youn

Posted 2011-07-04T22:33:00.023

Reputation: 47

3You're supposed to take the parentheses as input, not hardcode them. – Gareth – 2011-07-31T08:26:28.373

1

Scala(2.9), 211 characters

object P extends App{def x(j:Int)={"\n"+"  "*j}
var(i,n)=(0,"")
for(c<-args(2)){if(args(0).exists(_==c)){print(x(i)+c)
i+=1
n=x(i)}else{if(args(1).exists(_==c)){i-=1
print(x(i)+c)
n=x(i)}else{print(n+c)
n=""}}}}

Gareth

Posted 2011-07-04T22:33:00.023

Reputation: 11 678

1

Perl - 89 85 bytes

A version of Hojung Youn's answer which accepts the block characters via two arguments.

#!perl -p
BEGIN{$b=pop;$a=pop}s/([$a])|([$b])|\w+/"  "x($1?$t++:$2?--$t:$t)."$&
"/ge

Called like:

perl golf.pl<<<'abc{xyz{text[note{comment(t{ex}t)abc}]}}' '[{(<' ']})>'

Sorpigal

Posted 2011-07-04T22:33:00.023

Reputation: 111

Very nice concept, @Hojung and Sorpigal. It is a bit fragile, though. For example, swap the ] and } in the close-paren argument, and the ] closes the character class, leading to an unmatched paren error. Similarly, suppose the open set starts with ^, perhaps to match v in the close set; you'll get the complement of the intended [$a] class. That's why I used \Q...\E in my answer. The \w+ for non-paren characters works for the example, but what about input like 'x(foo-bar)y' '(' ')'? Of course, it isn't clear the code needs to handle something like that. – DCharness – 2011-08-02T15:23:29.523

0

C, 256

Parameters:

  • e is the ending char,
  • n is the indentation,
  • b the opening brackets,
  • d the closing brackets.

I broke the code up to avoid the horizontal scrollbar.

#define r char
#define P(c) putchar(c);
#define N P(x)
#define W printf("%*s",n,"");
r*s,x='\n';i(r e,int n,r*b,r*d){r*t=s,*p;int l=0;W while(*s!=e)    
{if(p=strchr(b,*s)){if(s!=t){N W}P(*s++)N i(d[p-b],n+2,b,d); N W 
P(*s++);l=1;}else{if(l){N W l=0;}P(*s++)}}}

Complete program is 363 characters.

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define r char
#define P(c) putchar(c);
#define N P(x)
#define W printf("%*s",n,"");
r*s,x='\n';i(r e,int n,r*b,r*d)
{r*t=s,*p;int l=0;W while(*s!=e)
{if(p=strchr(b,*s)){if(s!=t){N W}
P(*s++)N i(d[p-b],n+2,b,d); N W
P(*s++);l=1;}else{if(l){N W l=0;}
P(*s++)}}}main(int c,r*v[]){s =
v[3];i('\0',0,v[1],v[2]);}

tkf

Posted 2011-07-04T22:33:00.023

Reputation: 121

0

VB.net (?c)

Language isn't suited to code golfing, so I used an uncommon approach. Using a trace listener to output to the console.

Imports System.Diagnostics.Debug
Module Module1
  Sub Main(args() As String)
    IndentText(args(0), args(1), args(2)) 'openings, closings, text)
  End Sub
  Sub IndentText(o As String, e As String, t As String)
    Dim x = 0
    Listeners.Add(New Diagnostics.ConsoleTraceListener)
    IndentSize = 2
    For Each c In t
      If o.Contains(c) Then
        WriteLine("")
        WriteLine(c)
        Indent()
        x = 1
      ElseIf e.Contains(c) Then
        If x = 0 Then WriteLine("")
        Unindent()
        WriteLine(c)
        x = 1
      Else
        Write(c)
        x = 0
      End If
    Next
  End Sub
End Module

Uses commandline args for the input

args(0) is the indenting chars
args(1) is the undenting chars
args(2) is the text to be indented.

Adam Speight

Posted 2011-07-04T22:33:00.023

Reputation: 1 234

0

D (300)

C[] i(C,S)(ref S s,C p){if(!*s)return[];static C[] w;w~=" ";C[] r;C c=s[0];while(c!=p){s=s[1..$];r~=(c=='{'||c=='['||c=='<'?"\n"~w~c~"\n"~i(s,cast(char)(c+2)):c=='('?"\n"~w~c~"\n"~i(s,')'):[c]);c=*s;}w=w[1..$];if(*s)s=s[1..$];c=*s;return" "~w~r~"\n"~w~(c=='}'||c==']'||c=='>'||c==')'?[p]:p~"\n"~w);}

needs a null terminated string for the bounds check (otherwise the if(*s) needs to be changed to if(s.length))

ratchet freak

Posted 2011-07-04T22:33:00.023

Reputation: 1 334

Note that the task calls for the two sets of parentheses to be part of the input, not hardcoded. – Joey – 2011-07-05T12:51:51.390

0

Java

Non codegolf version! Assuming we have this version of split() that includes delims,

public static String indent(String input, String openPars,
        String closingPars) {
    String re = "["
            + (openPars + closingPars).replace("[", "\\[").replace("]",
                    "\\]") + "]";
    String[] split = inclusiveSplit(input, re, 0);
    int indent = 0;
    StringBuilder sb = new StringBuilder();
    for (String string : split) {
        if (StringUtils.isEmpty(string))
            continue;
        if (closingPars.indexOf(string) != -1) {
            indent--;
        }
        sb.append(StringUtils.repeat(" ", indent * 2));
                    sb.append(string);
                    sb.append("\n");
        if (openPars.indexOf(string) != -1) {
            indent++;
        }
    }
    String string = sb.toString();
    return string;
}

Prashant Bhate

Posted 2011-07-04T22:33:00.023

Reputation: 291

2StringUtils is not part of the Standard JDK. – st0le – 2011-07-07T04:58:44.450

0

C 284 Non White space Characters

I'm no fan of obfuscation but well...

#include<cstdio>
#include<cstring>
#define g printf
#define j char
int main(int a,j**b){int c=0;for(j*f=b[3];*f!='\0';++f){if(strchr(b[1],*f)!=0){g("\n%*c\n%*c",c,*f,c+2,'\0');c+=2;}else if(strchr(b[2],*(f))!=0){c-=2;g("\n%*c",c,*f);if(strchr(b[2],*(f+1))==0)g("\n%*c",c,'\0');}else putchar(*f);}}

Usage: ./program start_brackets end_brackets string_to_parse

Mihai Bişog

Posted 2011-07-04T22:33:00.023

Reputation: 101

0

php (187) (153)

function a($s,$o,$e){while(''!=$c=$s[$i++]){$a=strpbrk($c,$o)?2:0;$b=strpbrk($c,$e)?2:0;echo ($a+$b||$r)?"\n".str_pad('',$t-=$b):'',$c;$t+=$a;$r=$a+$b;}}

Function takes string, opening delimiters, ending delimiters as arguments.

migimaru

Posted 2011-07-04T22:33:00.023

Reputation: 1 040

0

Powershell, 146 Bytes

param([char[]]$s,[char[]]$e,[char[]]$f)$f|%{}{if($_-in$s){$o;'  '*$i+$_;$o='  '*++$i;}elseif($_-in$e){$o;'  '*--$i+$_;$o='  '*$i}else{$o+=$_}}{$o}

Ungolfed Explanation

param([char[]]$start,             # Cast as array of Chars
      [char[]]$end,
      [char[]]$string)
$string | foreach-object { } {    # For every char in string. Empty Begin block
    if ( $_ -in $start ) {        # If char is in start
        $o                        # Print stack ($o)
        '  ' * $i + $_            # Newline, indent, insert start char
        $o = '  ' * ++$i          # Set stack to ident (incremented)
    } elseif ( $_ -in $end ) {    # If char is in end
        $o                        # Print stack
        '  ' * --$i + $_          # Newline, decrement indent, insert end char
        $o = '  ' * $i            # Set stack to indent
    } else {
        $o+ = $_                  # Otherwise add character to stack
    }
} { $o }                          # Print remaining stack (if any)

Jonathan Leech-Pepin

Posted 2011-07-04T22:33:00.023

Reputation: 273

0

C, 181 characters

#define d(m,f)if(strchr(v[m],*s)){puts("");for(j=f;j--;)printf("  ");}
i;main(j,v,s)char**v,*s;{for(s=v[3];*s;s++){d(1,i++)d(2,--i)putchar(*s);d(1,i)if(!strchr(v[2],*(s+1)))d(2,i)}}

Pretty much the most straightforward approach imaginable. Iterate through the string (v[3]), if it's a left brace (as defined in v[1]), increase the indent level, if it's a right brace (as defined in v[2]), decrease the indent level.

Cole Cameron

Posted 2011-07-04T22:33:00.023

Reputation: 1 013

-1

C, 114 121

main(i,x,s,c){while(~(c=getchar()))(s=x)|(x=2*!!strchr("(){}[]<>",c))?s=c-1&x,i-=x-2*s,printf("\n%*c",i-s,c):putchar(c);}

Not very nice, but a solution.. an empty line may appear before/after depending on whether input starts/finishes with a parentheses.

With the new restriction, this approach is almost useless for golfing.

esneider

Posted 2011-07-04T22:33:00.023

Reputation: 149

Doesn't indent the opening parentheses far enough and outputs empty lines between consecutive closing ones. – Joey – 2011-07-05T07:57:37.417

@joey fixed, thank you for the feedback! – esneider – 2011-07-05T12:31:57.390

It still hard-codes the parentheses while they should be part of the input. Currently all answers do not conform to the specification. – Joey – 2011-07-05T12:42:59.823