I have a Word document containing a numbered list like this
Item 1
Item 2
Item 3
The list style is "List Paragraph". Left indent of "List Paragraph" is 0.5". If we run the following code to reapply the style "List Paragraph", the left indent of the style is now 0.75"
Dim t As ListTemplate
Set t = ActiveDocument.Styles("List Paragraph").ListTemplate
t.ListLevels(1).ResetOnHigher = True
Selection.Range.ListFormat.ApplyListTemplate t, False, wdListApplyToWholeList
As a result, the list is shifted to the right 0.25".
I'm wondering why the method ApplyListTemplate change the left indent of the style "List Paragraph".
Before and after applying the code, the description of the style are
"Indent:
Left: 0.5"
Hanging: 0.25", Numbered + Level: 1 + Numbering Style: 1, 2, 3, … + Start at: 1 + Alignment: Left + Aligned at: 0.75" + Indent at: 1", Style: Quick Style, Priority: 35
Based on: Text"
"Indent:
Left: 0.75"
Hanging: 0.25", Outline numbered + Level: 1 + Numbering Style: 1, 2, 3, … + Start at: 1 + Alignment: Left + Aligned at: 0.75" + Indent at: 1", Style: Quick Style, Priority: 35
Based on: Text"
I found the same behavior in both Office 2003 and 2010
I can't test your exact code because I get a Run-time error 5941, which says "The requested member of the collection does not exist."
That being said, Word has a tendency (for me anyway) to "fix" the indent of a list whenever a change is made to its formatting. There's probably a setting to tell Word to stop "fixing" lists, but I suggest simply adding the following to the end of your code:
With Selection.ParagraphFormat
.LeftIndent = InchesToPoints(0.75) ' Left indent
.RightIndent = InchesToPoints(0) ' Right indent
.FirstLineIndent = InchesToPoints(-0.25) ' First line indent
End With
That will give you a left indent of 0.5" and and a hanging indent of 0.25" (even though the numbers may look a little odd). You don't need the middle line that starts with .RightIndent =, but I thought I'd include it in the event you'd want to change that as well.
Related
I have some problems, I would like my table of contents to be on the second page. Unfortunately, when I generate it with the "toc: true" code, it appears on the first page (i.e. just before the front page, which is not the best). Any help for me?
title: ' '
output:
pdf_document:
number_sections: yes
toc: true
toc_depth: 2
html_document:
df_print: paged
geometry: left = 2.5cm, right = 2cm, top = 2cm, bottom = 2cm
fontsize: 11pt
header-includes:
- \usepackage{float}
- \usepackage{sectsty}
- \usepackage{paralist}
- \usepackage{setspace}\spacing{1.5}
- \usepackage{fancyhdr}
- \usepackage{lastpage}
- \usepackage{dcolumn}
- \usepackage{natbib}\bibliographystyle{agsm}
- \usepackage[nottoc, numbib]{tocbibind}
- \usepackage{ragged2e}
bibliography: bibliography.bib
It's my first time using reportlab to generate pdfs, it's VERY hard for me to understand how it works (it took me a day to even put a sized SVG image :D)
I want to achieve a very basic pdf:
As you can see in the images: 1 cover page, then 2 pages with header and footer BUT header with text is only on the first page...
Text is not static at all, it can break up to 4-5 pages, in the future there could be another section with title with different text.
Also I think what is very hard is to set text's Frame.topPadding to be variable based on
header height... I can't even imagine how to do this xD
This is my code right now
I've achieved to do the first page, it was pretty easy, but when it came to Frames, PageTemplates and other, my head blew up...
def _header(self, canvas, doc, title=None):
# Save the state of our canvas so we can draw on it
canvas.saveState()
y_pad = 50
header_height = (y_pad * 2) + (self.styles['heading'].leading if text else 0)
header_frame = Frame(
x1=0,
y1=self.height - header_height,
width=self.width,
height=header_height,
topPadding=y_pad,
bottomPadding=y_pad
)
canvas.setFillColor(DARKGRAY)
canvas.rect(0, self.height - header_height, self.width, header_height, fill=1)
if text:
header_frame.addFromList([
Paragraph(text, self.styles['heading'])
], canvas)
# Release the canvas
canvas.restoreState()
def _dark_page(self, canvas, doc):
canvas.saveState()
canvas.setFillColor(DARKGRAY)
canvas.rect(0, 0, self.width, self.height, fill=1)
canvas.restoreState()
def _create(self):
doc = SimpleDocTemplate(
self.buffer,
topMargin=0,
rightMargin=0,
leftMargin=0,
bottomMargin=0,
pagesize=A4
)
story = []
# cover page template with dark background set by self._dark_page
main_page_template = PageTemplate(id='main', frames=[
Frame(0, 0, self.width, self.height, 0, 100, 0, 100)
], onPage=self._dark_page)
# basic page template for any further text about product
body_page_template = PageTemplate(id='body', frames=[
Frame(0, 0, self.width, self.height, 80, 120, 80, 120, showBoundary=1)
], onPage=lambda c,d: self._header(c, d, title='title title title title')
doc.addPageTemplates([main_page_template, body_page_template])
story.append(NextPageTemplate('main'))
logo = svg2rlg(LOGO_PATH)
logo.width = logo.minWidth() * 0.4
logo.height = logo.height * 0.4
logo.scale(0.4, 0.4)
# logo._showBoundary = 1
logo.hAlign = 'CENTER'
story.append(logo)
story.append(Spacer(width=0, height=80))
# maybe there's a way to position the image in the center between elements,
# like justify-content: between in css...
image = Image(self._get_product_image_path(), 320, 320)
story.append(image)
story.append(Spacer(width=0, height=80))
title = Paragraph(self.product.title, self.styles['heading'])
story.append(title)
if self.product.breed.name_latin:
story += [
Spacer(width=0, height=10),
Paragraph(self.product.breed.name_latin, self.styles['subheading'])
]
story.append(NextPageTemplate('body'))
story.append(PageBreak())
# actual text
story.append(Paragraph(text*4, self.styles['body']))
doc.build(story)
So the question is
How do I set header and footer on the page, and if page breaks, next page with same header and footer, but header without title until the last page of the PageTemplate?
I've tried to get page numbers in self._header doc argument, but it's returning the first page number of the PageTemplate, not every page, maybe there's a way to get a page number from 0(first page used by some template) to the last page used by this template?
THANKS in advance! It already took me 3 days to try to achieve this...
I often use markers to underline a part of code (e.g., to invite users to hover on it and see hints). Most of time, we want to underline at least one characters. But sometimes, we may want to underline the position between two characters. For instance, given a formula fg(23,), I want to underline the position between , and ), then hovering on it shows a non-empty argument is expected here.
It seems that the following code in the playground can achieve this more or less.
var ed = monaco.editor.create(document.getElementById("container"), {
value: "fg(23,)",
language: "javascript"
});
monaco.editor.setModelMarkers(ed.getModel(), 'test', [{
startLineNumber: 1,
startColumn: 7,
endLineNumber: 1,
endColumn: 7,
message: "a non-empty argument is expected here",
severity: 8
}])
However, setting startColumn same as endColumn does not always do the trick. For instance, I cannot underline the position between ( and 2; setting startColumn: 4, endColumn: 4 does not work.
So does anyone know how to mark a position between 2 characters? We are not limited to underlining, other ways like highlighting are welcomed as well.
(* Link on GitHub: https://github.com/microsoft/monaco-editor/issues/3039 *)
To your question: following this post, it seems that a solution may look something like this (please use the playground to test)
HTML
<div id="container" style="height: 100%"></div>
CSS
.formulaHighlight { /* this class name can be whatever you want */
color: #3456ff !important;
cursor: pointer;
text-decoration: underline;
font-weight: bold;
font-style: oblique;
}
JS
const ed = monaco.editor.create(document.getElementById("container"), {
value: "fg(23,)",
language: "javascript"
});
monaco.editor.setModelMarkers(ed.getModel(), 'test', [{
startLineNumber: 1,
startColumn: 7,
endLineNumber: 1,
endColumn: 7,
message: "a non-empty argument is expected here",
severity: 8
}])
const decorations = ed.deltaDecorations(
[],
[
{
range: new monaco.Range(1, 4, 1, 6),
options: { inlineClassName: 'formulaHighlight' }
}
]
);
The delta decoration method allow to customize styles in specific locations. The monaco.Range method uses the following parameters:
startLineColumn - from which line to start the highlight
startColumn - the numeric value of the first highlight character
endLineNumber - which line stops the highlight
endColumn - the numeric value of last highlighted character
In your case it seems that startLineColumn and endLineNumber will be the same line number. Also,startColumn and endColumn will represent the actual highlight range (within the same line)
I'm using Xmlwriter method to write an html document. When adding elements, it automatically inserts crlf linebreaks between them, no problem there.
Except at some point, when I want to add some tags in my inner text: what I get is a crlf after each , which is definitely not desirable.
I can live without linebreaks between elements, but I can't find the setting in the xmlwriter that could give me this... As far as I can tell, .NewLineHandling only deals with linebreaks in text, not those inserted automatically between elements.
Here are my settings:
With ReportSet 'XML/HTML file writing settings
.Encoding = Text.Encoding.UTF8
.Indent = True
.IndentChars = vbTab
.OmitXmlDeclaration = True
.NewLineHandling = Xml.NewLineHandling.None
End With
And here is the spot where I definitely don't want any linebreak between elements:
For Each section As DiffLib.DiffSection In test
If section.IsMatch Then
cp = EltCnt(k).Substring(n, section.LengthInCollection1)
Report.WriteString(cp)
Else
rmv = EltCnt(k).Substring(n, section.LengthInCollection1)
add = EltCntR(k).Substring(o, section.LengthInCollection2)
With Report
.WriteStartElement("SPAN")
.WriteAttributeString("style", "background-color: #ffcccc; text-decoration: line-through;")
.WriteString(rmv)
.WriteEndElement()
.WriteStartElement("SPAN")
.WriteAttributeString("style", "background-color: #ccffcc;")
.WriteString(add)
.WriteEndElement()
End With
End If
n += section.LengthInCollection1
o += section.LengthInCollection2
Next
So: what should I do not to have linebreaks between the tags?
Never mind, browsers are smarter than me, and just ignore those pesky linebreaks... No need to remove them.
I'd like to create a keyboard shortcut (such as CTRL+T) that automatically moves the cursor to the line after the occurence of a fixed text, such as &todo.
Example:
foo
bar
&todo
fix bug #783
blah
blah2
Pressing CTRL+T would automatically move the cursor to the line beginning with fix ....
Currently I'm doing it like this:
CTRL F
enter &todo, ENTER
ESCAPE (closes the Search bottom panel)
HOME
DOWN ARROW (moves to next line)
but this requires too many actions.
How to do that in a single key shortcut?
The best solution is it use a plugin to do that.
The plugin below does what you require. It will find the next occurrence of pattern (i.e. the &todo marker) below the current cursor position, move the cursor to the line below it, and centre that position in the window. If the pattern is not found below the current cursor position it will search again from the top of the buffer providing a wrap around feature.
Copy and paste the following Python code into a buffer and save it in your Sublime Text config User folder as GoToPattern.py.
import sublime
import sublime_plugin
class GotoPatternCommand(sublime_plugin.TextCommand):
def run(self, edit, pattern):
sels = self.view.sel()
# Optional flags; see API.
flags = sublime.LITERAL | sublime.IGNORECASE
start_pos = sels[0].end() if len(sels) > 0 else 0
find_pos = self.view.find(pattern, start_pos, flags)
if not find_pos and start_pos > 0:
# Begin search again at the top of the buffer; wrap around
# feature, i.e. do not stop the search at the buffer's end.
find_pos = self.view.find(pattern, 0, flags)
if not find_pos:
sublime.status_message("'{}' not found".format(pattern))
return
sels.clear()
sels.add(find_pos.begin())
self.view.show_at_center(find_pos.begin())
row, col = self.view.rowcol(find_pos.begin())
self.view.run_command("goto_line", {"line": row + 2})
# Uncomment for: cursor to the end of the line.
# self.view.run_command("move_to", {"to": "eol"})
Add key bindings:
// The pattern arg, i.e. "&todo", can be changed to anything you want
// and other key bindings can also be added to use different patterns.
{"keys": ["???"], "command": "goto_pattern", "args": {"pattern": "&todo"}}
Add a Command Palette entry to Default.sublime-commands if you want:
{"caption": "GoToPattern: &todo", "command": "goto_pattern", "args": {"pattern": "&todo"}},
These links may be useful to you ST v. 2 API and ST v. 3 API.
P.S. Did you know that Sublime Text has bookmarks? [Just in case you didn't.]
The accepted answer is really better and I'm finally using it.
For reference, here an old solution I used: first create a gototodo.py file in "C:\Users\User\AppData\Roaming\Sublime Text 2\Packages\User\" containing:
import sublime, sublime_plugin
class GototodoCommand(sublime_plugin.TextCommand):
def run(self, edit):
contents = self.view.substr(sublime.Region(0, self.view.size())) # https://stackoverflow.com/questions/20182008/sublime-text-3-api-get-all-text-from-a-file
a = contents.find('&todo')
cursors = self.view.sel()
cursors.clear()
location = sublime.Region(a, a)
cursors.add(location)
self.view.show_at_center(location)
(row, col) = self.view.rowcol(self.view.sel()[0].begin()) # go to the next line
self.view.run_command("goto_line", {"line": row+2})
Then add this in "C:\Users\User\AppData\Roaming\Sublime Text 2\Packages\User\Default (Windows).sublime-keymap":
{ "keys": ["ctrl+t"], "command": "gototodo" }
Done!