Need a unique gift idea?
A Pastebin account makes a great Christmas gift
SHARE
TWEET

Untitled

a guest Jul 18th, 2018 51 Never
Upgrade to PRO!
ENDING IN00days00hours00mins00secs
 
  1. package main
  2.  
  3. import (
  4.     "container/vector";
  5.     "fmt";
  6.     "go/ast";
  7.     "go/token";
  8.     "go/parser";
  9.     "go/printer";
  10.     "io";
  11.     "os";
  12.     "path";
  13.     "regexp";
  14.     "strings";
  15.  
  16.     . "./html";
  17. )
  18.  
  19.  
  20. type HTMLStyler struct {
  21.     comment     *ast.Comment;
  22.     comment_text    []string;
  23.     comment_offset  int;
  24.     prev    *history;
  25. }
  26.  
  27. type history struct {
  28.     val interface {};
  29.     prev *history;
  30. }
  31.  
  32. type collector struct {
  33.     contents *vector.StringVector;
  34. }
  35.  
  36. func (self *collector) Write(p []byte) (n int, err os.Error) {
  37.     self.contents.Push(string(p));
  38.     return len(p), nil;
  39. }
  40.  
  41.  
  42. func (self *HTMLStyler) LineTag(line int) ([]byte, printer.HTMLTag) {
  43.     return []byte{}, printer.HTMLTag{}
  44. }
  45.  
  46. func (self *HTMLStyler) Comment(comment *ast.Comment, line []byte) ([]byte, printer.HTMLTag) {
  47.     if self.comment == comment {
  48.         self.comment_offset++;
  49.         if self.comment_text[self.comment_offset] == "" {
  50.             self.comment_offset++;
  51.         }
  52.     } else {
  53.         self.comment = comment;
  54.         self.comment_text = strings.Split(string(comment.Text), "\r\n", 0);
  55.         self.comment_offset = 0;
  56.     }
  57.  
  58.     self.prev = &history{comment, self.prev};
  59.  
  60.     return strings.Bytes(self.comment_text[self.comment_offset]), printer.HTMLTag{
  61.         Start: "<span class=\"go-comment\">",
  62.         End: "</span>",
  63.     };
  64. }
  65.  
  66. func (self *HTMLStyler) BasicLit(x *ast.BasicLit) ([]byte, printer.HTMLTag) {
  67.     kind := "other";
  68.     switch x.Kind {
  69.     case token.INT:
  70.         kind = "int"
  71.     case token.FLOAT:
  72.         kind = "float"
  73.     case token.CHAR:
  74.         kind = "char"
  75.     case token.STRING:
  76.         kind = "string"
  77.     }
  78.  
  79.     if x.Value[0] == '`' {
  80.         kind = "string go-raw-string";
  81.     }
  82.  
  83.     self.prev = &history{x, self.prev};
  84.  
  85.     return x.Value, printer.HTMLTag{
  86.         Start: "<span class=\"go-basiclit go-" + kind + "\">",
  87.         End: "</span>",
  88.     };
  89. }
  90.  
  91. func (self *HTMLStyler) Ident(id *ast.Ident) ([]byte, printer.HTMLTag) {
  92.     classes := "go-local";
  93.     if id.IsExported() {
  94.         classes = "go-exported"
  95.     }
  96.  
  97.     switch id.String() {
  98.     case "bool", "uint8", "uint16", "uint32", "uint64", "int8", "int16", "int32", "int64", "float32", "float64", "byte", "uint", "int", "float", "uintptr", "string":
  99.         classes += " go-prim-ident";
  100.     default:
  101.         if tok, ok := self.prev.val.(token.Token); ok && tok.String() == "func" || tok.String() == ")" {
  102.             classes += " go-func-ident";
  103.         }
  104.     }
  105.  
  106.     self.prev = &history{id, self.prev};
  107.  
  108.     return strings.Bytes(id.String()), printer.HTMLTag{
  109.         Start: "<span class=\"go-ident " + classes + "\">",
  110.         End: "</span>",
  111.     };
  112. }
  113.  
  114. func (self *HTMLStyler) Token(tok token.Token) ([]byte, printer.HTMLTag) {
  115.     extra := "";
  116.  
  117.     if tok.IsKeyword() {
  118.         extra += " go-keyword"
  119.     }
  120.  
  121.     if tok.IsLiteral() {
  122.         extra += " go-literal"
  123.     }
  124.  
  125.     if tok.IsOperator() {
  126.         extra += " go-operator"
  127.     }
  128.  
  129.     self.prev = &history{tok, self.prev};
  130.  
  131.     return strings.Bytes(tok.String()), printer.HTMLTag{
  132.         Start: "<span class=\"go-token" + extra + "\">",
  133.         End: "</span>",
  134.     };
  135. }
  136.  
  137. func Print(filename string, source interface{}) (pretty string, ok os.Error) {
  138.     fileAst, ok := parser.ParseFile(filename, source, 4);
  139.  
  140.     // Make common corrections for snippet pastes
  141.     if ok != nil && source != nil {
  142.         src := source.(string);
  143.  
  144.         if m, _ := regexp.MatchString(`^package`, src); !m {
  145.             src = "package main\n\n" + src
  146.         }
  147.  
  148.         if fileAst, ok = parser.ParseFile(filename, src, 4); ok != nil {
  149.             return
  150.         }
  151.     }
  152.  
  153.     coll := new(collector);
  154.     coll.contents = vector.NewStringVector(0);
  155.  
  156.     (&printer.Config{
  157.         Mode: 5,
  158.         Tabwidth: 4,
  159.         Styler: new(HTMLStyler),
  160.     }).Fprint(coll, fileAst);
  161.  
  162.     pretty = strings.Join(coll.contents.Data(), "");
  163.  
  164.     return;
  165. }
  166.  
  167. func prettyPaste(id string, limit int) (code []string, err os.Error) {
  168.     source, err := io.ReadFile("pastes" + path.Clean("/"+id));
  169.     if err != nil {
  170.         return
  171.     }
  172.  
  173.     multi := strings.Split(string(source), "\n---", 0);
  174.  
  175.     allCode := make([]string, len(multi));
  176.     results := make(chan int);
  177.     for i := 0; i < len(multi); i++ {
  178.         go func(i int) {
  179.             allCode[i], _ = prettySource(id, multi[i], limit);
  180.             results <- i
  181.         }(i);
  182.     }
  183.  
  184.     for i := 0; i < len(multi); i++ {
  185.         <-results;
  186.     }
  187.  
  188.     code = allCode;
  189.  
  190.     return;
  191. }
  192.  
  193. func prettySource(filename string, source string, limit int) (code string, err os.Error) {
  194.     prettyCode, ok := Print(filename, source);
  195.     if ok != nil {  // If it fails to parse, just serve it raw.
  196.         prettyCode = source
  197.     }
  198.  
  199.     linesPre := Pre().Attrs(As{"class": "line-numbers"});
  200.     codePre := Pre().Attrs(As{"class": "code-lines"});
  201.  
  202.     stopped := false;
  203.     for i, code := range strings.Split(prettyCode, "\n", 0) {
  204.         line := i + 1;
  205.         linesPre.Append(
  206.             fmt.Sprintf(
  207.                 A("%d").Attrs(As{
  208.                     "rel": "#L%d",
  209.                     "href": "#LC%d",
  210.                     "id": "LID%d",
  211.                 }).Out()+"\n",
  212.                 line, line, line, line));
  213.         codePre.Append(
  214.             Div(code).Attrs(As{
  215.                 "class": "line",
  216.                 "id": "LC" + fmt.Sprint(line),
  217.             }).Out());
  218.  
  219.         if limit != 0 && i == limit {
  220.             stopped = true;
  221.             break;
  222.         }
  223.     }
  224.  
  225.     if stopped {
  226.         linesPre.Append("\n");
  227.         codePre.Append(
  228.             Div(
  229.                 A("\n...").Attrs(As{
  230.                     "href": "/{@|url+html}",
  231.                     "class": "go-comment",
  232.                 })).Attrs(As{
  233.                 "class": "line",
  234.             }).Out());
  235.     }
  236.  
  237.     code = Table(
  238.         Tbody(
  239.             Tr(
  240.                 Td(linesPre).Attrs(As{"width": "1%", "valign": "top"}),
  241.                 Td(codePre).Attrs(As{"valign": "top"})))).Attrs(As{
  242.         "class": "code",
  243.         "cellspacing": "0",
  244.         "cellpadding": "0",
  245.     }).Out();
  246.  
  247.     return;
  248. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top