automatic update date in sublime by save? - sublimetext

is there a way that sublime text automatically updates the date in a comment block on a file when I edit and save it?
like:
/**
* #author yada yada
* #date 2015-01-08
*/
to:
/**
* #author yada yada
* #date 2015-01-19
*/

ok, got it.
it's a mix of
Can i add date time for sublime snippet?
sublime plugin: find and select text
Is it possible to chain key binding commands in sublime text 2?
Preferences > Key Bindings- User
[
{"keys": ["ctrl+s"], "command": "date_and_save" }
]
add_date.py
'''
Autodate header
#date <>
'''
from datetime import datetime
import sublime, sublime_plugin
class AddDateCommand(sublime_plugin.TextCommand):
def run(self, args):
content = self.view.substr(sublime.Region(0, self.view.size()))
begin = content.find('#date <',0,100)
if begin == -1:
return
end = content.find("\n", begin)
target_region = sublime.Region(begin, end)
self.view.sel().clear()
self.view.sel().add(target_region)
self.view.run_command(
"insert_snippet",
{ "contents": "#date <%s>" % datetime.now().strftime("%Y-%m-%d %H:%M:%S") } )
class DateAndSaveCommand(sublime_plugin.WindowCommand):
def run(self):
self.window.run_command("add_date")
self.window.run_command("save")
\o/

Awesome stuff! Small addition to the above solution:
Instead of
end = begin + 19
This line will make it more dynamical, because it will get rid of everything until the end of the line.
end = content.find("\n", begin)
Helps with versioning up, for example, where the line-length can vary.

Related

How to sort a list of text+date strings in Groovy

I have a list of strings, each one contains text with date like this:
"foo_6.7.2016"
"foo_5.10.2016"
"foo_6.30.2016"
"foo_6.23.2016"
"foo_6.2.2016"
"foo_5.22.2016"
I need to sort them by Date and get this:
"foo_6.30.2016"
"foo_6.23.2016"
"foo_6.7.2016"
"foo_6.2.2016"
"foo_5.22.2016"
"foo_5.10.2016"
An alternative might be:
def foos = [
"foo_6.7.2016",
"foo_5.10.2016",
"foo_6.30.2016",
"foo_6.23.2016",
"foo_6.2.2016",
"foo_5.22.2016"
]
def sorted = foos.sort(false) { Date.parse('M.d.yyyy', it - 'foo_') }.reverse()
For a quick answer that needs substantial cleanup:
def dates = [
"foo_6.7.2016"
"foo_5.10.2016"
"foo_6.30.2016"
"foo_6.23.2016"
"foo_6.2.2016"
"foo_5.22.2016"
]
def prefix = "foo_"
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("M.d.yyyy")
def sorted_dates = dates.collect{ sdf.parse(
it, new java.text.ParsePosition(prefix.length()) ) }.sort().reverse()
def newDates = sorted_dates.collect{ "${prefix} + ${sdf.format(it)}"}
println newDates

Understanding MVC in a QAbstractTableModel

I have some data which are represented by a class of my own ; to fix the ideas I give an example.
class MyOwnModel():
def __init__(self, name="", number=0):
self.name = name
self.number = number
I then have a list of such instances, that I want to represent in a QTableView.
li = [MyOwnModel("a", 1), MyOwnModel("b", 2)]
Then I see two strategies to make a QTableView from that :
change MyOwnModel so that it subclasses QAbstractTableModel
build a new QAbstractTableModel which mimics MyOwnModel in a way that its attributes are for instance two QString and connect the dataChanged signal to a function which updates the instance of MyOwnModel
I am not completely satisfied with any of these, but I have no other idea for the moment.
Which one is the most suitable to my problem ? (I have a more complex class in practice but I would like to use the same framework)
As stated in the comment, your model is your list of object. You should subclass QAbstractTableModel to use this list.
Here's my code snippet for this:
import sys
import signal
import PyQt4.QtCore as PCore
import PyQt4.QtGui as PGui
class OneRow(PCore.QObject):
def __init__(self):
self.column0="text in column 0"
self.column1="text in column 1"
class TableModel(PCore.QAbstractTableModel):
def __init__(self):
super(TableModel,self).__init__()
self.myList=[]
def addRow(self,rowObject):
row=len(self.myList)
self.beginInsertRows(PCore.QModelIndex(),row,row)
self.myList.append(rowObject)
self.endInsertRows()
#number of row
def rowCount(self,QModelIndex):
return len(self.myList)
#number of columns
def columnCount(self,QModelIndex):
return 2
#Define what do you print in the cells
def data(self,index,role):
row=index.row()
col=index.column()
if role==PCore.Qt.DisplayRole:
if col==0:
return str( self.myList[row].column0)
if col==1:
return str( self.myList[row].column1)
#Rename the columns
def headerData(self,section,orientation,role):
if role==PCore.Qt.DisplayRole:
if orientation==PCore.Qt.Horizontal:
if section==0:
return str("Column 1")
elif section==1:
return str("Column 2")
if __name__=='__main__':
PGui.QApplication.setStyle("plastique")
app=PGui.QApplication(sys.argv)
#Model
model=TableModel()
model.addRow(OneRow())
model.addRow(OneRow())
#View
win=PGui.QTableView()
win.setModel(model)
#to be able to close wth ctrl+c
signal.signal(signal.SIGINT, signal.SIG_DFL)
#to avoid warning when closing
win.setAttribute(PCore.Qt.WA_DeleteOnClose)
win.show()
sys.exit(app.exec_())
Each element of myList is a row in the table.

Ruby print hash in grid format

I'm working on coding a chess board. The structure of my board will be like this:
# a b c d e f g h
# 1 * * * * * * * * # <= Black pieces on top
# 2 * * * * * * * *
# 3 * * * * * * * *
# 4 * * * * * * * *
# 5 * * * * * * * *
# 6 * * * * * * * *
# 7 * * * * * * * *
# 8 * * * * * * * * # <= White pieces on bottom
I created an #board hash, which stores the value of any item in the grid (i.e. pieces or blank space).
How can I take my hash, which maps a grid location to a "*" currently (i.e. #board['a8']=> '*', etc), and output that hash in the grid-like format?
Here's my #board variable:
def drawBoard
#board = Hash.new
letter='a'
while letter <= 'h'
i=1
while i<9
#board["#{letter}#{i}"] = "*"
i+=1
end
letter=letter.next
end
#board
end
Current output is just the hash itself. i.e.,
{"a1"=>"*", "a2"=>"*", "a3"=>"*", "a4"=>"*", "a5"=>"*", "a6"=>"*", "a7"=>"*", "a8"=>"*", "b1"=>"*", "b2"=>"*", "b3"=>"*", "b4"=>"*", "b5"=>"*", "b6"=>"*", "b7"=>"*", "b8"=>"*", "c1"=>"*", "c2"=>"*", "c3"=>"*", "c4"=>"*", "c5"=>"*", "c6"=>"*", "c7"=>"*", "c8"=>"*", "d1"=>"*", "d2"=>"*", "d3"=>"*", "d4"=>"*", "d5"=>"*", "d6"=>"*", "d7"=>"*", "d8"=>"*", "e1"=>"*", "e2"=>"*", "e3"=>"*", "e4"=>"*", "e5"=>"*", "e6"=>"*", "e7"=>"*", "e8"=>"*", "f1"=>"*", "f2"=>"*", "f3"=>"*", "f4"=>"*", "f5"=>"*", "f6"=>"*", "f7"=>"*", "f8"=>"*", "g1"=>"*", "g2"=>"*", "g3"=>"*", "g4"=>"*", "g5"=>"*", "g6"=>"*", "g7"=>"*", "g8"=>"*", "h1"=>"*", "h2"=>"*", "h3"=>"*", "h4"=>"*", "h5"=>"*", "h6"=>"*", "h7"=>"*", "h8"=>"*"}
Edit:
Thanks to David's answer, he led me toward a much more compact hash generation method as well. The updated (and working) code:
def drawBoard
#board = Hash.new
('a'..'h').each do |letter|
(1..9).each do |i|
#board["#{letter}#{i}"] = "*"
print #board["#{letter}#{i}"]
end
puts
end
end
Provided that you can use symbols for the keys in #board instead of strings:
#board = {:"a1" => "*", ...}
I think the easiest would be to prepare a fixed template string, and do string format to rewrite the grids.
Template = <<_
a b c d e f g h
1 %{a1} %{b1} %{c1} %{d1} %{e1} %{f1} %{g1} %{h1}
2 %{a2} %{b2} %{c2} %{d2} %{e2} %{f2} %{g2} %{h2}
3 %{a3} %{b3} %{c3} %{d3} %{e3} %{f3} %{g3} %{h3}
4 %{a4} %{b4} %{c4} %{d4} %{e4} %{f4} %{g4} %{h4}
5 %{a5} %{b5} %{c5} %{d5} %{e5} %{f5} %{g5} %{h5}
6 %{a6} %{b6} %{c6} %{d6} %{e6} %{f6} %{g6} %{h6}
7 %{a7} %{b7} %{c7} %{d7} %{e7} %{f7} %{g7} %{h7}
8 %{a8} %{b8} %{c8} %{d8} %{e8} %{f8} %{g8} %{h8}
_
Template % #board
If you let #board be a flat array instead (which can be handled by using modulo operations), then replace the %{..} above with %s, and it will work the same way.
Here is a starting point you can use. You would need to add the row and column labels yourself, and add spaces, but this should get you going in the right direction:
('a'..'h').each do |letter|
(1..8).each do |i|
print #board["#{letter}#{i}"]
end
puts # end the line
end

How to uncomment source code in C++?

How to uncomment many lines of source at once? In particular, this comment symbol - #
I have: Visual studio, Netbeans, DevCpp
I have this source code:
# /**
# * RC4.java - Implementace algoritmu proudove sifry RC4
# *
# * Na zaklade vzorove implementace Arcfour algoritmu Kalle Kaukonena (1997) v
# jazyce C
# * pro potreby vyuky na CVUT FEL prepsal do jayzka Java a upravil Lukas
# Privoznik (2008).
# */
# package rc4;
#
# import java.io.*;
#
#
# /*
# * Kontext S sifrovaciho algoritmu RC4
# */
# class RC4Context {
#
# int x;
# int y;
# char state[];
#
# RC4Context() {
# state = new char[256];
# }
# }
#
Well in your case you could use column selection.
In Visual Studio: Try holding down Alt and drag your mouse to form a rectangle around the first column to select all "#" occurrences and then just press delete.
In Netbeans column selection should work with Strg + Shift + R.

How to automatically turn BibTex citation into something parseable by Zotero?

I have a citation system which publishes users notes to a wiki (Researchr). Programmatically, I have access to the full BibTeX record of each entry, and I also display this on the individual pages (for example - click on BibTeX). This is in the interest of making it easy for users of other citation manager to automatically import the citation of a paper that interests them. I would also like other citation managers, especially Zotero, to be able to automatically detect and import a citation.
Zotero lists a number of ways of exposing metadata that it will understand, including meta tags with RDF, COiNS, Dublin Core and unAPI. Is there a Ruby library for converting BibTeX to any of these standards automatically - or a Javascript library? I could probably create something, but if something existed, it would be far more robust (BibTeX has so many publication types and fields etc).
There's a BibTeX2RDF convertor available here, might be what you're after.
unAPI is not a data standard - it's a way to serve data (to Zotero and other programs). Zotero imports Bibtex, so serving Bibtex via unAPI works just fine. Inspire is an example of a site that does that:
http://inspirehep.net/
By now one can simply import bibtex files of type .bib directly in Zotero. However, I noticed my bibtex files were often less complete than Zotero (in particular they often missed a DOI), and I did not find an "auto-complete" function (based on the data in the bibtex entries) in Zotero.
So I import the .bib file with Zotero, to ensure they are all in there. Then I run a python script that gets all the missing DOI's it can find for the entries in that .bib file, and exports them to a space separated .txt file.:
# pip install habanero
from habanero import Crossref
import re
def titletodoi(keyword):
cr = Crossref()
result = cr.works(query=keyword)
items = result["message"]["items"]
item_title = items[0]["title"]
tmp = ""
for it in item_title:
tmp += it
title = keyword.replace(" ", "").lower()
title = re.sub(r"\W", "", title)
# print('title: ' + title)
tmp = tmp.replace(" ", "").lower()
tmp = re.sub(r"\W", "", tmp)
# print('tmp: ' + tmp)
if title == tmp:
doi = items[0]["DOI"]
return doi
else:
return None
def get_dois(titles):
dois = []
for title in titles:
try:
doi = titletodoi(title)
print(f"doi={doi}, title={title}")
if not doi is None:
dois.append(doi)
except:
pass
# print("An exception occurred")
print(f"dois={dois}")
return dois
def read_titles_from_file(filepath):
with open(filepath) as f:
lines = f.read().splitlines()
split_lines = splits_lines(lines)
return split_lines
def splits_lines(lines):
split_lines = []
for line in lines:
new_lines = line.split(";")
for new_line in new_lines:
split_lines.append(new_line)
return split_lines
def write_dois_to_file(dois, filename, separation_char):
textfile = open(filename, "w")
for doi in dois:
textfile.write(doi + separation_char)
textfile.close()
filepath = "list_of_titles.txt"
titles = read_titles_from_file(filepath)
dois = get_dois(titles)
write_dois_to_file(dois, "dois_space.txt", " ")
write_dois_to_file(dois, "dois_per_line.txt", "\n")
The DOIs of the .txt are fed into magic wand of Zotero. Next, I (manually) remove the duplicates by choosing the latest added entry (because that comes from the magic wand with the most data).
After that, I run another script to update all the reference id's in my .tex and .bib files to those generated by Zotero:
# Importing library
import bibtexparser
from bibtexparser.bparser import BibTexParser
from bibtexparser.customization import *
import os, fnmatch
import Levenshtein as lev
# Let's define a function to customize our entries.
# It takes a record and return this record.
def customizations(record):
"""Use some functions delivered by the library
:param record: a record
:returns: -- customized record
"""
record = type(record)
record = author(record)
record = editor(record)
record = journal(record)
record = keyword(record)
record = link(record)
record = page_double_hyphen(record)
record = doi(record)
return record
def get_references(filepath):
with open(filepath) as bibtex_file:
parser = BibTexParser()
parser.customization = customizations
bib_database = bibtexparser.load(bibtex_file, parser=parser)
# print(bib_database.entries)
return bib_database
def get_reference_mapping(main_filepath, sub_filepath):
found_sub = []
found_main = []
main_into_sub = []
main_references = get_references(main_filepath)
sub_references = get_references(sub_filepath)
for main_entry in main_references.entries:
for sub_entry in sub_references.entries:
# Match the reference ID if 85% similair titles are detected
lev_ratio = lev.ratio(
remove_curly_braces(main_entry["title"]).lower(),
remove_curly_braces(sub_entry["title"]).lower(),
)
if lev_ratio > 0.85:
print(f"lev_ratio={lev_ratio}")
if main_entry["ID"] != sub_entry["ID"]:
print(f'replace: {sub_entry["ID"]} with: {main_entry["ID"]}')
main_into_sub.append([main_entry, sub_entry])
# Keep track of which entries have been found
found_sub.append(sub_entry)
found_main.append(main_entry)
return (
main_into_sub,
found_main,
found_sub,
main_references.entries,
sub_references.entries,
)
def remove_curly_braces(string):
left = string.replace("{", "")
right = left.replace("{", "")
return right
def replace_references(main_into_sub, directory):
for pair in main_into_sub:
main = pair[0]["ID"]
sub = pair[1]["ID"]
print(f"replace: {sub} with: {main}")
# UNCOMMENT IF YOU WANT TO ACTUALLY DO THE PRINTED REPLACEMENT
# findReplace(latex_root_dir, sub, main, "*.tex")
# findReplace(latex_root_dir, sub, main, "*.bib")
def findReplace(directory, find, replace, filePattern):
for path, dirs, files in os.walk(os.path.abspath(directory)):
for filename in fnmatch.filter(files, filePattern):
filepath = os.path.join(path, filename)
with open(filepath) as f:
s = f.read()
s = s.replace(find, replace)
with open(filepath, "w") as f:
f.write(s)
def list_missing(main_references, sub_references):
for sub in sub_references:
if not sub["ID"] in list(map(lambda x: x["ID"], main_references)):
print(f'the following reference has a changed title:{sub["ID"]}')
latex_root_dir = "some_path/"
main_filepath = f"{latex_root_dir}latex/Literature_study/zotero.bib"
sub_filepath = f"{latex_root_dir}latex/Literature_study/references.bib"
(
main_into_sub,
found_main,
found_sub,
main_references,
sub_references,
) = get_reference_mapping(main_filepath, sub_filepath)
replace_references(main_into_sub, latex_root_dir)
list_missing(main_references, sub_references)
# For those references which have levenshtein ratio below 85 you can specify a manual swap:
manual_swap = [] # main into sub
# manual_swap.append(["cantley_impact_2021","cantley2021impact"])
# manual_swap.append(["widemann_envision_2021","widemann2020envision"])
for pair in manual_swap:
main = pair[0]
sub = pair[1]
print(f"replace: {sub} with: {main}")
# UNCOMMENT IF YOU WANT TO ACTUALLY DO THE PRINTED REPLACEMENT
# findReplace(latex_root_dir, sub, main, "*.tex")
# findReplace(latex_root_dir, sub, main, "*.bib")

Resources