source: style.c @ 7803326

release-1.9
Last change on this file since 7803326 was 14be3a5, checked in by Jason Gross <jgross@mit.edu>, 10 years ago
Give owl_text_indent an indent_first_line parameter This is useful if you need to indent text that isn't broken into chunks that end with newlines. This is primarily in preparation for the next commit, where we need to replace the indent on the first line by a prefix. The other (reasonable) option is to make owl_text_indent always prefix the string it's given with an indent, even when it's given the empty string. This would break the nice property that indent(A + B) = indent(A) + indent(B) whenever A ended with a newline. After some discussion on zephyr and on the github pull request, I decided to go with this option.
  • Property mode set to 100644
File size: 2.5 KB
Line 
1#define OWL_PERL
2#include "owl.h"
3
4/* Assumes owenership of one existing ref on `obj`*/
5void owl_style_create_perl(owl_style *s, const char *name, SV *obj)
6{
7  s->name=g_strdup(name);
8  s->perlobj = obj;
9}
10
11int owl_style_matches_name(const owl_style *s, const char *name)
12{
13  if (!strcmp(s->name, name)) return(1);
14  return(0);
15}
16
17const char *owl_style_get_name(const owl_style *s)
18{
19  return(s->name);
20}
21
22const char *owl_style_get_description(const owl_style *s)
23{
24  SV *sv = NULL;
25  OWL_PERL_CALL_METHOD(s->perlobj,
26                       "description",
27                       ;,
28                       "Error in style_get_description: %s",
29                       0,
30                       sv = SvREFCNT_inc(POPs);
31                       );
32  if(sv) {
33    return SvPV_nolen(sv_2mortal(sv));
34  } else {
35    return "[error getting description]";
36  }
37}
38
39/* Use style 's' to format message 'm' into fmtext 'fm'.
40 * 'fm' should already be be initialzed
41 */
42void owl_style_get_formattext(const owl_style *s, owl_fmtext *fm, const owl_message *m)
43{
44  const char *body;
45  char *indent;
46  int curlen;
47  owl_fmtext with_tabs;
48
49  SV *sv = NULL;
50 
51  /* Call the perl object */
52  OWL_PERL_CALL_METHOD(s->perlobj,
53                       "format_message",
54                       XPUSHs(sv_2mortal(owl_perlconfig_message2hashref(m)));,
55                       "Error in format_message: %s",
56                       0,
57                       sv = SvREFCNT_inc(POPs);
58                       );
59
60  if(sv) {
61    body = SvPV_nolen(sv);
62  } else {
63    body = "<unformatted message>";
64  }
65
66  /* indent and ensure ends with a newline */
67  indent = owl_text_indent(body, OWL_TAB, true);
68  curlen = strlen(indent);
69  if (curlen == 0 || indent[curlen-1] != '\n') {
70    char *tmp = indent;
71    indent = g_strconcat(tmp, "\n", NULL);
72    g_free(tmp);
73  }
74
75  owl_fmtext_init_null(&with_tabs);
76  /* fmtext_append.  This needs to change */
77  owl_fmtext_append_ztext(&with_tabs, indent);
78  /* Expand tabs, taking the indent into account. Otherwise, tabs from the
79   * style display incorrectly due to our own indent. */
80  owl_fmtext_expand_tabs(&with_tabs, fm, OWL_TAB_WIDTH - OWL_TAB);
81  owl_fmtext_cleanup(&with_tabs);
82
83  g_free(indent);
84  if(sv)
85    SvREFCNT_dec(sv);
86}
87
88int owl_style_validate(const owl_style *s) {
89  if (!s || !s->perlobj || !SvOK(s->perlobj)) {
90    return -1;
91  }
92  return 0;
93}
94
95void owl_style_cleanup(owl_style *s)
96{
97  if (s->name) g_free(s->name);
98  SvREFCNT_dec(s->perlobj);
99}
100
101void owl_style_delete(owl_style *s)
102{
103  owl_style_cleanup(s);
104  g_free(s);
105}
Note: See TracBrowser for help on using the repository browser.