내 터미널을 덜 지루하게 만들 수 있습니까?


11

오늘날 터미널은 너무 지루 합니다. 그들은 다음과 같이 사용되었습니다 :

터미널 1 터미널 2

이제 그들은 단조롭고 둔하고 흑백입니다. 터미널을 다채롭게 만드는 프로그램을 작성해주세요!

기술

이 예제 Ruby 코드를 보자 :

예제 코드

대부분의 Linux 터미널은 이러한 이스케이프 시퀀스 ( \e이스케이프 문자를 나타냄)를 지원하며 Windows는 ANSICON 을 사용하여 이스케이프 시퀀스 를 지원할 수 있습니다 . 다음은 문자열의 텍스트 또는 배경색을 변경할 수있는 특정 이스케이프 시퀀스의 구문입니다.

\e[{{COLOR}}m

어디 \e 이스케이프 문자 ( 0x1BASCII)를 나타내며 {{COLOR}}사용하려는 색상 번호로 대체됩니다 (나중에 자세히 설명). 이 이스케이프 시퀀스 다음에 오는 텍스트는 지시 된대로 형식이 지정되고 값은 0모든 형식을 재설정합니다.

당신의 도전은 색상을 포함 할 수있는 일부 텍스트를 지정하는 문자열을 가져 와서 다채로운 버전을 출력하는 것입니다.

입출력

일반 텍스트는 일반처럼 작동하며 문자 그대로 인쇄됩니다. 예를 들어, 입력waffles 은 특수한 색상없이 동일한 출력을 생성합니다.

색상을 지정하는 구문은 Wikipedia의 구문 과 비슷 합니다 . 예를 들어, 문장에서 단어 "빨간색"을 빨간색으로 색칠 This is the color red!하려면 입력은 다음과 같습니다.

This is {{red|the color red}}!

배경색도 작동합니다. 흰색 배경에 검은 글자를 원하면 다음을 사용하십시오.

{{black|white|This text is black on white}}

배경색 만 얻으려면 전경을 생략하십시오.

{{|red|This text has a red background}}

사양

두 개의 열린 중괄호는 항상 색상 지시문 의 시작을 지정합니다 . 두 개의 닫는 중괄호는 끝을 지정합니다. 대괄호는 항상 일치합니다. {{에 해당 하는 없이는 절대 존재하지 않으며 , 해당 }}}}앞서는 절대 오지 않을 것 {{입니다. 이러한 색상 지시문 은 중첩되지 않으며 색상 지시문{{ 내에는 표시되지 않습니다.

색상 지시문에는 항상 하나 또는 두 개의 |기호가 있습니다. 하나가있는 경우 앞에있는 텍스트는 전경색이고 뒤에 나오는 텍스트는 해당 색상으로 표시 할 문자열입니다. 두 개가있는 경우 첫 번째 텍스트 이전의 텍스트는 전경색이고 첫 번째 텍스트 이후이지만 두 번째 이전 텍스트는 배경색이며 두 번째 텍스트 이후의 텍스트는 표시 할 문자열입니다. 이 세로 막대는 색상 지시문 외부에있을 수 있으며 문자 그대로 인쇄해야합니다.

전경색 또는 배경색 (둘다는 아님)이 비어있을 수 있으며,이 경우 기본값으로 두어야합니다. 마지막 문자열 (출력 할 문자열)은 절대로 비어 있지 않습니다.

특정 색상의 텍스트를 출력하는 방법은 다음과 같습니다.

  • 컬러 시퀀스는 "설명"섹션에서 정의된다. 예를 들어 42의 색상 순서는입니다 "\e[42m".

  • 색상을 설정하려면 아래에서 결정한 숫자의 색상 순서를 인쇄하십시오.

     Color name   | Color sequence number (foreground / background)
    --------------+----------
     black        | 30 / 40
     red          | 31 / 41
     green        | 32 / 42
     yellow       | 33 / 43
     blue         | 34 / 44
     magenta      | 35 / 45
     cyan         | 36 / 46
     lightgray    | 37 / 47
     darkgray     | 90 / 100
     lightred     | 91 / 101
     lightgreen   | 92 / 102
     lightyellow  | 93 / 103
     lightblue    | 94 / 104
     lightmagenta | 95 / 105
     lightcyan    | 96 / 106
     white        | 97 / 107
    
  • 색상 이름은 대소 문자를 구분하며 유효하지 않은 색상 이름은 제공되지 않습니다. RED또는 같은 lightgrey철자 를 처리 할 필요는 없습니다 e.

  • 색상 순서를 인쇄하면 그 뒤에 나오는 모든 텍스트에 적용됩니다. 색상 순서를 끝내려면 (기본 색상으로 재설정) 색상 순서를 0( "\e[0m")로 출력하십시오 .

테스트 사례

 {{|yellow|     }}
{{|yellow| }}     {{|yellow| }}
{{|yellow| }} {{red|'}} {{red|'}} {{|yellow| }}
{{|yellow| }} \_/ {{|yellow| }}
{{|yellow| }}     {{|yellow| }}
 {{|yellow|     }}

이것은 악한 적목으로 웃는 얼굴을 출력해야합니다.

규칙

  • 색상을 자동으로 구문 분석하기 위해 프로그래밍 언어의 라이브러리 또는 함수를 사용할 수 없습니다. 이것은 당신 이 의미하는 바를 결정해야 "red"한다는 것을 의미합니다. 도서관에서 자동으로 그렇게 할 수는 없습니다.

  • 이것은 이므로 바이트 단위의 가장 짧은 코드가 이길 것입니다!


실제로 터미널로되어 있습니까? 아니면 화려한 텍스트 뷰어입니까? 명령을 실행해야합니까?
Nathan Merrill

이것을 테스트하기가 어렵습니다. 지정된 구문을 사용하여 STDOUT에 보내는 모든 것은 일반 텍스트로 제공됩니다. 내 bash 프로필은 컬러 프롬프트를 사용하므로 시도한 것 \n\[\e[32m\]\w\n\[\e[0m\]> (녹색 디렉토리 이름, 다음 줄의 일반 프롬프트)을 도용 하지만 프로그램 (파이썬과 Java를 사용해 보았습니다)에서 작동시킬 수 없습니다. 어떤 아이디어?
Geobits

@Geobits 사용해보십시오 echo -e "\e[31mtest\e[0m".
Doorknob

4
나는 당신이 즐길 것이라고 생각합니다 lolcat.
Anko

1
나는에 의해 그렇게 생각 you그는 비 유적 수단 your program(라이브러리 함수에 대한 호출 반대), 그가 소요 determine의 의미 figure out하지 같이 choose. 즉, 매핑을 처리해야하는 프로그램은 String ( "red") |-> Integer (31)입니다. red아니라 31그가 그렇게 말한다 때문에, 그 정보가 프로그램에 통합 될 필요가있다. 정확히 무엇으로 간주 될지 논쟁 할 수 있지만, your program범용 문자열 조작 함수를 사용할 수 있습니까? -뻔뻔스럽게 속임수 / 남용하지 마십시오.
blutorange

답변:


6

루비 205 189 188 186 185 182 174 170 165 161 159 154 바이트

코드에 긴 문자열 이름을 넣는 것만으로는 충분하지 않습니다.

덕분에 부분적으로 170까지 감소 rubik 였습니다. 이제 스크롤 막대가 사라졌습니다!

플렉스 답변 덕분에 하나의 명백하고 눈에 띄지 않는 개선이 있었지만 개선하지 않았다면 이것을 다시 방문하지 않았을 것입니다!

더 이상, #sum으로 4 바이트를 절약했습니다. 나는 그것을 의도하지 않았지만이 솔루션은 대소 문자를 구분하지 않는 것으로 나타났습니다. 행복하게 처리{{RED|Red text}} 합니다.

육각 덤프 :

0000000: 7a3d 2d3e 6a7b 693d 2240 3054 2d44 1547  z=->j{i="@0T-D.G
0000010: 5155 0034 3256 2f46 1749 0b22 2e69 6e64  QU.42V/F.I.".ind
0000020: 6578 2028 415b 6a5d 2e74 6f5f 732e 7375  ex (A[j].to_s.su
0000030: 6d25 3839 292e 6368 723b 692b 3d69 3e39  m%89).chr;i+=i>9
0000040: 3f38 303a 3330 7d0a 243e 3c3c 243c 2e72  ?80:30}.$><<$<.r
0000050: 6561 642e 6773 7562 282f 7b7b 282e 2a3f  ead.gsub(/{{(.*?
0000060: 297d 7d2f 297b 413d 2431 2e73 706c 6974  )}}/){A=$1.split
0000070: 277c 273b 221b 5b25 693b 2569 6d23 7b41  '|';".[%i;%im#{A
0000080: 2e70 6f70 7d1b 5b30 6d22 255b 7a5b 305d  .pop}.[0m"%[z[0]
0000090: 2c31 302b 7a5b 315d 5d7d                 ,10+z[1]]}

당신은 그것을 변환 할 수 있습니다 xxd -r hex.dump .

인쇄 할 수없는 모든 문자가 포함 된 프로그램은 참조 목적으로 이스케이프되었습니다.

z=->j{i="@0T-D\x15GQU\x0042V/F\x17I\v".index (A[j].to_s.sum%89).chr;i+=i>9?80:30}
$><<$<.read.gsub(/{{(.*?)}}/){A=$1.split'|';"\x1b[%i;%im#{A.pop}\x1b[0m"%[z[0],10+z[1]]}

한 줄입니다. 이렇게 사용하세요

ruby colors.rb -W0 < input.txt

-W0플래그는 stderr그렇지 않으면 전송 될 경고를 억제 합니다. 그러나 프로그램은 플래그없이 잘 작동합니다.

산출:

산출


1
아, 나도 같은 생각을했지만 너는 나를 이겼어! base 35, modulus 98 및 xor 1로 char을 저장할 수 있다고 생각합니다. 문자열은 다음과 같습니다 '1?IYU_N[(\x0c\x16&",\x1f\x01'. 내 문자열의 길이는 16입니다. 나는 너의 것이 18이라고 보았으므로 아마 조정해야 할 것이다.
rubik

감사. 2 개의 추가 바이트는 기본 뒤로 / 전경 색상을 설정하는 색상 코드 39/49를 지원하기 위해 존재합니다. 그러나 팁에 감사드립니다. 저는 현재 직장에 있으며 집으로 돌아갈 때 더 많은 생각을 할 것입니다.
blutorange

1
글쎄, 당신이 사용할 수있는 유일한 기초는 35와 36이라는 것을 알았습니다 (적어도 Python의 int()함수는 36을 넘을 수 없습니다). 그런 다음 모듈러스 (2에서 10000까지, 그러나 이론적으로는 모든 유니 코드로 검색을 넓힐 수 있음 )와 xor에 대한 모든 조합을 시도했습니다 . 그런 다음 중복 문자가 포함되지 않은 결과 만 허용되는 것으로 간주했습니다.
rubik

그렇습니다, 그것은 내가 한 일의 정도입니다. 원래 인쇄 가능한 문자로 제한했습니다. 두통이 적고 멋지게 보이기 때문입니다. 그러나 이미 이스케이프 시퀀스 대신 바이트 0x1e를 사용하고 있기 때문에 인쇄 할 수없는 문자를 더 많이 사용할 수 있습니다. 인쇄 가능한 문자를 얻기 위해을 사용했습니다 x.to_i(base)%mod+offset. 그때 교체 +와를 ^잘, 그것은 쿨러를 보이기 때문에. 그 외에는 불필요합니다. 을 삭제 ^99하고 변화 <<+더 바이트 저장. 팁 주셔서 감사합니다, 나는 다른 눈치 채지 못했을 것입니다!
blutorange

4

루비, 329 바이트

h={};(y=0..15).each{|i|h[%w(black red green yellow blue magenta cyan lightgray darkgray lightred lightgreen lightyellow lightblue lightmagenta lightcyan white)[i]]=y.map{|j|[30,40].map{|k|k+i%8+i/8*60}}[i]}
loop{puts gets.gsub(/{{.+?}}/){|x|"\e[#{h[(g=x.scan(/[^{}|]+/))[0]][0]}m#{(g[2]? "\e[#{h[g[1]][1]}m":'')}#{g.last}\e[0m"}}

이것을 실행하려면 어떤 버전의 Ruby가 필요합니까? 내가 사용 ruby 2.1.2p95했는데 오류가 발생했습니다 : undefined method 'gsub' for nil:NilClass (NoMethodError) .
Ray

안녕하세요 @Ray, 그것은 2.0.0-p451에서 작동합니다. 나는 2.1.2에서 그것을 시도하지 않았다. 여기 스크립트로 작동 하고 그것은 여기 IRB에서 작동합니다 .
Alex Deva

텍스트를 수동으로 입력 할 때 작동합니다. 그렇게하면 ruby colors.rb < input.txt모든 입력을 읽은 후에도 계속 반복됩니다. 그런 다음 메서드를 소유하지 않은을 gets반환 하므로 오류가 발생합니다. 대신에 사용하면 짧아집니다. )nil#gsub$><<$<.readloop{puts gets
blutorange

방금 웃는 얼굴 로이 스크립트를 테스트했으며 (내 게시물의 질문과 이미지 참조) 스마일 주위에 노란색 테두리가 없습니까?
blutorange

4

플렉스 (렉서) - 226 197 192 182 168 (또는 166)

166로 낮추려면 \33실제 이스케이프 문자로 변경하십시오 .

 int z;p(i){printf("\33[%dm",i);}
%%
"{{" z=2;
[a-z]*\| if(!z)REJECT;~-yyleng&&p("062q00t03058ns7uo0p90r4"[*(int*)&yytext[yyleng>7?4:0]%131%27]-10*z);z--;
"}}" p(z=0);

컴파일하고 실행하십시오.

$ flex -o colour.c colour.l
$ gcc -o colour colour.c -lfl
$ ./colour < input

3

파이썬-351

import re,sys
R=range
E=lambda n,d=0:'\033[%dm'%(T[n]+d)if n else''
def P(m):f,b,t=m.groups();return'%s%s%s\033[0m'%(E(f),E(b,10),t)
x='!red!green!yellow!blue!magenta!cyan'.replace
T=dict(zip(('black'+x('!',' ')+' lightgray darkgray'+x('!',' light')+' white').split(),R(30,38)+R(90,98)))
print re.sub(r'{{(\w+)?\|?(\w+)?\|?(.+?)}}',P,sys.stdin.read())

1

코브라-496

그것은 수있는 거의 단일 인쇄 문합니다.

use System.Text.RegularExpressions
class P
    def main
        print Regex.replace(Console.readLine,r'\{\{('+(l=List<of String>(((m=' black red green yellow blue magenta cyan'.split).join(' ')+' lightgray darkgray'+m.join(' light')+' white').split))[1:].join('|')+r')?\|?('+l[1:].join('|')+r')?\|(.*?)\}\}',do(a as Match))
            return if(x=l.indexOf('[a.groups[1]]'),r'\e['+'[if(x>8,x+81,x+29)]m','')+if(y=l.indexOf('[a.groups[2]]'),r'\e['+'[if(y>8,y+91,y+39)]m','')+'[a.groups[3]]'+if(x+y,r'\e[0m','')

1

파이썬, 561

stdin에서 형식화 할 텍스트를 읽습니다.

import re,sys
def p(f,b,t):
    p=''
    m='\033[%dm'
    if f!=0:p+=m%f
    if b!=0:p+=m%b
    return p+t+m%0
def c(n,b=0):
    s='black:30#red:31#green:32#yellow:33#blue:34#magenta:35#cyan:36#lightgray:37#darkgray:90#lightred:91#lightgreen:92#lightyellow:93#lightblue:94#lightmagenta:95#lightcyan:96#white:97'
    r=0
    for i in s.split('#'):
        (t,c)=i.split(':')
        if t==n:
            r=int(c)
            if b==1:r+=10
    return r
def r(m):
    i=m.groups()
    f=b=0
    if i[0]!='':f=c(i[0])
    if i[1]!=None:b=c(i[1],1)
    return p(f,b,i[2])
print re.sub('{{(\w*)\|(?:(\w*)\|)?([^}]+)}}',r,sys.stdin.read())

2
is not Nonecodegolf에 포함 하기에는 너무 장황합니다 . !=None예를 들어을 사용할 수 있습니다 .
Ray

또한에서 def p(f,b,t)코드는를 발생 ZeroDivisionError시킵니다. 모든 모드 0은 불가능합니다.
Beta Decay

@BetaDecay는 계수가 아닌 정수가 아니며 형식이 지정된 문자열입니다.
Sammitch

이것을 re.sub실행할 때 잘못된 구문 오류가 발생 합니다
ArtOfCode

(후기 코멘트) 이 499 바이트 코드가 작동합니까?
Outgolfer Erik
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.