FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

cleaned up indentation logic · plotdevice/plotdevice@553383c · GitHub

Repository navigation

Commit 553383c

Browse files
committed
cleaned up indentation logic
- combined the \n\n-scanner in .append() and the indentation-preserver in .overleaf() - both now call the Text._dedent class method
1 parent 7d64faa commit 553383c

1 file changed

Lines changed: 43 additions & 14 deletions

File tree

‎plotdevice/gfx/text.py‎

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -167,23 +167,23 @@ def append(self, txt=None, **kwargs):
167167
attrs = self._fontify(merged_style)
168168
attrib_txt = NSMutableAttributedString.alloc().initWithString_attributes_(decoded, attrs)
169169

170-
# ensure that any paragraph with more than one leading newline is un-indented.
171-
zap = [0] if self._store.length()==0 else [] # also avoid indenting the very first line
172-
zap += [m.end()-1 for m in re.finditer(r'\n\n+[^\n]', attrib_txt.string())]
173-
self._dedent(attrib_txt, *zap)
170+
# ensure the very-first character of a Text is indented flush left. also watch for
171+
# double-newlines at the edge of the existing string and the appended chars
172+
if self._store.length()==0 or self._store.string().endswith('\n\n'):
173+
Text._dedent(attrib_txt)
174+
elif self._store.string().endswith('\n') and re.match(r'\n[^\n]', attrib_txt.string()):
175+
Text._dedent(attrib_txt, 1)
176+
177+
# ensure that any paragraph with more than one leading newline is indented flush-left
178+
for m in re.finditer(r'\n\n+[^\n]', attrib_txt.string()):
179+
Text._dedent(attrib_txt, m.end()-1)
174180

175181
if attrib_txt:
176182
# let the typesetter deal with the new substring
177183
self._store.appendAttributedString_(attrib_txt)
178184
self._resized()
179185

180-
def _dedent(self, attrib_txt, *indices):
181-
for idx in indices:
182-
old_graf, _ = attrib_txt.attribute_atIndex_effectiveRange_("NSParagraphStyle", idx, None);
183-
real_margin, _ = attrib_txt.attribute_atIndex_effectiveRange_("head", idx, None);
184-
graf = old_graf.mutableCopy()
185-
graf.setFirstLineHeadIndent_(real_margin)
186-
attrib_txt.addAttribute_value_range_("NSParagraphStyle", graf, (idx, 1))
186+
### NSAttributedString de/manglers ###
187187

188188
def _fontify(self, defaults, *styles):
189189
"""Merge the named-styles and defaults in order and return nsattibutedstring attrs"""
@@ -234,7 +234,26 @@ def _fontify(self, defaults, *styles):
234234
kern = (spec['tracking'] * font.size)/1000.0
235235

236236
# build the dict of features for this combination of styles
237-
return dict(NSFont=font._nsFont, NSColor=color, NSParagraphStyle=graf, NSKern=kern, head=head)
237+
return dict(NSFont=font._nsFont, NSColor=color, NSParagraphStyle=graf, NSKern=kern)
238+
239+
@classmethod
240+
def _dedent(cls, attrib_txt, idx=0, inherit=False):
241+
"""Removes first-line paragraph indentation of at the given attributed-string index.
242+
243+
Sets the first-line indent equal to the subsequent-lines value (unless the first line
244+
is outdented; in which leave it alone).
245+
246+
Passing inherit=True will override this logic and set the first-indent equal to the
247+
subsequent-indent without regard for its indent/outdent status.
248+
249+
Note that this method *modifies* the attrib_txt reference rather than returning a value.
250+
"""
251+
old_graf, _ = attrib_txt.attribute_atIndex_effectiveRange_("NSParagraphStyle", idx, None);
252+
graf = old_graf.mutableCopy()
253+
first, rest = graf.firstLineHeadIndent(), graf.headIndent()
254+
if first > rest or inherit: # leave negative-indentations alone
255+
graf.setFirstLineHeadIndent_(rest)
256+
attrib_txt.addAttribute_value_range_("NSParagraphStyle", graf, (idx, 1))
238257

239258
### flowing text into new Text objects or subsidiary TextFrames ###
240259

@@ -245,9 +264,19 @@ def overleaf(self):
245264
full = self.text
246265
if full not in seen:
247266
next_pg = self.copy()
248-
next_pg._store.deleteCharactersInRange_([0, len(seen)])
267+
268+
# delete the first page's-worth of chars and update indices
269+
nc = len(seen)
270+
next_pg._store.deleteCharactersInRange_([0, nc])
271+
nodes = {}
272+
for tag, elts in self._nodes.items():
273+
nodes[tag] = [e._replace(start=e.start-nc, end=e.end-nc) for e in elts if e.end-nc > 0]
274+
next_pg._nodes = nodes
275+
276+
# if the page-break is in the middle of a paragraph, preserve the first character's initial
277+
# indentation (since otherwise it'll be treated as a `first' line of a new paragraph)
249278
if not seen.endswith('\n'):
250-
next_pg._dedent(next_pg._store, 0)
279+
Text._dedent(next_pg._store, inherit=True)
251280
return next_pg
252281

253282
def flow(self, columns=all, layout=None):

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL